正文
linux中pud命令 purge命令linux的
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
如何在LINUX中获取进程中某个虚拟地址所在物理内
/*
*伪代码,示例
*32位地址,三级映射(没有pud_t),页面大小4KB
*/
unsigned long addr = 0x12345678;//要找的虚拟地址,用户空间所访问的地址
unsigned long real_addr = 0x00;//要输出的地址
struct task_struct *cur_task = get_current();//获取当前进程控制块
struct mm_struct *mm = cur_task - mm;//进程虚拟空间
pgd_t *pgd;//描述页全局目录项
pmd_t *pmd;//描述页中间项
pte_t *pte;//页表项
pgd = pgd_offset(mm, addr);//找出所在目录
if (pgd_none(*pgd)){
goto out;
}
pmd = pmd_offset(pgd, addr);//找出所在中间项
if (pmd_none(*pmd)){
goto out;
}
pte = pte_offset(pmd, addr);//找出所在页面
if (pte_none(*pte)) {
goto out;
}
//假设每页4KB
real_addr = addr 0x00003fff; //取出页面偏移量
real_addr += pte;//内核空间访问的地址
real_addr -= PAGE_OFFSET;//真正物理地址()
printk("物理地址是 %x\n",real_addr);
return;
out:
printk("没有内存映射",real_addr);
linux pgd pte 是什么关系
根据pid获取pcb,根据pcb获取vm,之后就可以了埃 下面是一个样本代码: pcb=find_task_by_pid(pid); pgd=pgd_offset(pcb-mm,va); pud=pud_offset(pgd,va); pmd=pmd_offset(pud,va); pte=pte_offset_kernel(pmd,va)
linux怎么查看tlb miss
在ARM架构下linux中pud命令,TLB miss后的工作绝大多数情况是由hardwarepage table walk完成,特殊情况下hardware page table walk可以被关闭,此时发生TLB miss后CPU就会产生一个translationfault,剩下的工作由OS接管,完成对于translation fault的异常处理。
默认情况下,发生TLB miss后,hardware page table walk自动启动开始扫描内存中的pagetable,若找到相应PTE(page table entry),则自动完成TLB entry的重填工作linux中pud命令;如果找不到,则发出一个page fault异常,然后OS接管处理page fault。内核中有do_page_fault函数,该函数从硬盘中调换页面进内存,更新页表,然后重新执行发生TLB miss的那条指令,hardware page table walk重新执行,完成TLB重填的工作。
这里关心的是关闭hardware pagetable walk后,再发生TLB miss后的处理例程。如果发生这种情况,ARM CPU会发出一个translation fault(If translation table walksare disabled, for example, PD0 or EPD0 is set to 1 for TTBR0, or PD1 or EPD1 isset to 1 for TTBR1, the processor returns a Translation fault.见cortex-A15TRM p 5-5)。OS处理该异常的流程如下。
首先发生translation fault后,CPU会发出一个abort异常,然后跳转到该异常地址处(以发生指令预取中止异常为例,跳转到0x00000010)去执行,该地址处存放的是一个跳转指令 (W(b) vector_pabt +stubs_offset),然后,通过判断,若发生该异常的指令处于usr模式,则跳转到__pabt_usr函数去执行,该函数中有条跳转指令bl CPU_PABORT_HANDLER,CPU_PABORT_HANDLER是个宏定义,对于ARMv7,该定义是:# define CPU_PABORT_HANDLER v7_pabort,
v7_pabort函数中就读取linux中pud命令了IFSR和IFAR两个寄存器的值:
//pabort-v7.S
/*
*Function: v6_pabort
*
*Params : r0 = address of aborted instruction
*
*Returns : r0 = address of abort
* : r1 = IFSR
*
*Purpose : obtain information about current prefetch abort.
*/
.align 5
ENTRY(v7_pabort)
mrc p15,0, r0, c6, c0, 2 @ get IFAR
mrc p15,0, r1, c5, c0, 1 @ get IFSR
mov pc,lr
ENDPROC(v7_pabort)
IFAR中存储linux中pud命令了发生异常的指令地址,IFSR中存储的是一个32位数,其中某些位表明异常类型等(参考Cortex-A15TRM p4-76)
剩余的工作就是根据以上两个寄存器提取出来的信息,调用相应函数(do_PrefetchAbort——do_translation_fault)进行处理。OS接管后的操作是(do_translation_fault函数),首先判断发生TLBmiss的那条指令是用户指令还是系统指令,如果是系统指令则剩余工作是对页全局目录(pgd),页上级目录(pud),页中间目录(pmd)进行操作;如果是用户指令,则调用do_page_fault函数,剩下的工作就是page fault的处理过程,根据不同情况判断,包括权限检查,分配页面,发送SIGSEGV信号给进程,直接杀死进程等。不管哪种操作,OS都没有对TLB进行重填。
对于page fault的处理过程如下:在取数或者取指令时,发生指令或者数据的地址不存在的情况,则发生中止异常。
以取指发生异常为例。发生指令预取中止异常后,CPU自动跳转到0x0000000C(可配置成0xfffffffc,这里不考虑)去执行,该地址处是一个跳转指令 (W(b) vector_pabt + stubs_offset),然后,通过判断,若发生该异常的指令处于usr模式,则跳转到__pabt_usr函数去执行,该函数中有条跳转指令bl CPU_PABORT_HANDLER,CPU_PABORT_HANDLER是个宏定义,对于ARMv7,该定义是:# defineCPU_PABORT_HANDLER v7_pabort,v7_pabort函数中就读取了IFSR和IFAR两个寄存器的值:
//pabort-v7.S
/*
* Function: v6_pabort
*
* Params : r0 = address ofaborted instruction
*
* Returns : r0 = address of abort
* : r1 = IFSR
*
* Purpose : obtain information aboutcurrent prefetch abort.
*/
.align 5
ENTRY(v7_pabort)
mrc p15, 0, r0, c6, c0, 2 @ get IFAR
mrc p15, 0, r1, c5, c0, 1 @ get IFSR
mov pc, lr
ENDPROC(v7_pabort)
IFAR中存储了发生异常的指令地址,IFSR中存储的是一个32位数,其中某些位表明异常类型等(参考Cortex-A15 TRM p4-76)
剩余的工作就是根据以上两个寄存器提取出来的信息,调用相应函数(do_PrefetchAbort——do_page_fault)进行处理。
windows和linux双系统全盘备份
大多数人日常工作所用的系统是Windows,如果想尝试或者转向Linux,那么进行Windows与Linux共存的双系统安装是个不错的主意。但双系统的安装较之单系统,在磁盘分区和引导管理器两个方面增加了复杂性,本文对双系统下引导管理器的安装来加以介绍。
笔者假定你已经有了一个可以正常运行的Win2k/XP系统,并且已经为Linux准备好了硬盘分区:Windows位于第一块硬盘的第一个分区,在 Linux下表示为hda1,在Grub下表示为(hd0,0),而Linux位于hdaX,用Grub表示为(hd0, X-1)。——Linux下的硬盘分区计数是从hda1开始的,而Grub的硬盘分区计数是从(hd0,0)开始的,所以hdaX就是(hd0,X- 1)。这里X如果在1-4之内,说明Linux分区是主分区,如果X大于4,说明Linux分区是逻辑分区,本文并不限定Linux必须位于主分区,它在逻辑分区一样是可以引导的。
首先说明本文的思路,笔者推荐由Windows到Linux的引导序列,即首先引导Windows的ntloader,然后通过 ntloader加载Linux分区的Grub引导扇区,最后通过Grub引导Linux系统。本文涉及到的引导管理器包括ntloader和Grub, ntloader是Windows系统自带的,在安装Win2k/XP后就已经安装了,Windows 2000以及Windows Xp就是由ntloader加载的。Grub是Linux系统下很强大的引导管理器,在常见的Linux版本里都是有的,一般是自动安装的。
下面具体说明安装序列:
一、在已经准备好的Linux分区上安装Grub
这个过程通常是由 Linux系统的安装程序自动进行的,当安装程序进行到引导管理器的安装,并就Grub的安装给出一些提示时,要当心了:我们选择Grub,而不是lilo,并且Grub要安装在该Linux分区,不要安装到硬盘主引导记录MBR(master boot record)上。安装程序询问Grub的安装位置时,应该是上文提到的hdaX或者(hd0,X-1),如果你写成hda或者(hd0),就会安装到 MBR上。
之所以强调Grub安装到 Linux分区,而不是MBR,因为本文是双系统安装,要顾忌到与Windows系统的兼容性(“兼容”在这里并不准确,实际是共生的意思)。我们的原则,就是把对已经安装的Windows系统的修改限制到最小的必要的程度,不去进行并非必要的修改,以此保障Linux 与Windows两个系统的和平共处。“简洁即美”,“简单”也会更安全。
如果安装到MBR,也是可以的,但可能会有下面的问题:
1、如果所安装的 Windows系统修改了MBR的默认设置,那么再把Grub安装到MBR,就对MBR的内容进行了修改,可能会导致 Windows不能正常启动。通常的Windows安装并不会改动MBR的内容,但如果你安装了一些引导管理程序,它们往往是通过MBR进行设置的。时下很流行的一些“一键恢复”程序,有些也是通过MBR设置的;
2、日后重装Windows系统时,MBR里的Grub会被擦除,这会造成Linux系统不能引导。虽然这个问题也是可以解决的,但笔者更欣赏一劳永逸的安装方式,Grub安装到Linux分区下,可以避免日后的麻烦;
3、在一些个别情形下,Grub不能正常引导系统。这个现象并不常见,但仍有可能发生,要知道Grub目前仍然是版本前的软件,而将Grub装到MBR里,就会把问题弄得更复杂。
当你所安装的Linux系统不能指定将Grub安装到Linux的所在分区时,我们的选择是:
暂将Grub安装到MBR,如果Linux系统能被Grub加以引导,进入Linux系统后,我们再手工将Grub装入Linux分区,然后恢复MBR;或者在安装程序内暂时不进行Grub的安装,退出安装程序后手工安装Grub。
恢复MBR需要用DOS、 win98/me的启动软盘引导系统,以/mbr参数执行引导软盘上的磁盘分区程序fdisk.exe,即在DOS命令 行(plain dos)下执行A:\fdisk /mbr。如果机器没有软驱,那么就需要用光盘或者U盘来引导机器进入DOS;在Windows 2k/XP下,一个叫Vfloppy的软件可以用软盘镜像文件来实现对软盘的虚拟引导,如果你的机器没有USB接口(或没有可以引导DOS的U盘),也没有光驱和软驱,可以一试。
我曾经用Xubuntu的 LiveCD在一台设置了“一键恢复”的TCL电脑安装时,安装程序没有给出任何选择,自动将Grub安装到了MBR 上,结果不能进入任何系统。最后还是用DOS下的A:\ fdisk /mbr恢复了MBR,能够正常引导Windows后,手工将Grub装到了Linux下的根分区,然后通过ntloader加载Grub,才实现了对 Linux的引导。
手工安装Grub的简便方法是用一张带有Grub的Linux LiveCD(比如常见的Knoppix、Morphix、Ubuntu,都是可以的),启动系统,在Linux的安装程序内如果能进入shell也是可以的,总之就是为了执行Linux指令,在终端下执行以下指令:
# grub
grub root (hd0,X-1)
grub setup (hd0,X-1)
grub quit
以上指令首先定位Grub 所需的/boot目录在分区(hd0,X-1),然后将Grub的引导代码写入(hd0,X-1)分区的第一个扇区,所以你首先应该确保(hd0,X-1)分区内的/boot/grub目录下已经有stage1、stage2、*_stage*等文件,这些文件可以通过释放Grub的打包文件来获得,或者直接从LiveCD光盘内的/boot/grub目录复制。
如果LiveCD带有grub-install脚本,也可以直接执行
# mount /dev/hdaX /mnt
# grub-install --root-directory=/mnt /dev/hdaX
以上指令首先将带有Grub目录/boot/grub的/hdaX挂载到/mnt,然后将Grub安装到/hdaX。
二、将Grub装配到ntloader内
Grub已经安装到了Linux分区内,但它还不能引导系统,我们需要把它和ntloader联接起来,由ntloader对Grub加以引导。这是通过把hdaX分区内的Grub引导扇区转换为文件,并装配到Windows的ntloader内来实施的。
仍然用LiveCD启动Linux系统(因为你所安装的Linux系统目前还是不能引导的),或者在安装程序可以进入shell的情况下,执行以下指令:
# mount -t vfat /dev/hda1 /mnt
# dd if=/dev/hdaX of=/mnt/linux.lnx bs=512 count=1
以上两条指令将Windows的启动分区(本文中为hda1)挂载到/mnt下,然后把Linux分区(hdaX)的第一个扇区(大小为512字节)复制为Windows启动分区根目录下名为linux.lnx的文件。
注意:如果你的Windows启动分区(即Windows下的C盘)不是fat32文件系统,而是ntfs文件系统,你需要在软驱内放入格式化的DOS软盘,并将第一条指令替换为:
# mount -t msdos /dev/fd0 /mnt
因为ntfs文件系统不经过特殊处理,在Linux下是不可写的,即使你将指令中的vfat替换为ntfs,实现了挂载,也是一样,所以我们在这里把linux.lnx写入DOS格式的软盘,然后通过软盘在Windows下把linux.lnx放入C盘。
接着是在Windows下编辑C盘根目录下的boot.ini文件,boot.ini通常是隐藏、只读的系统文件,所以需要把它的“隐藏”、“只读”属性去掉,才可以编辑。在“我的电脑”工具菜单“文件夹选项”下的“查看”栏中取消“隐藏受保护的操作系统文件”和“隐藏已知文件类型的扩展名”,并选择“显示所有文件和文件夹”,就可以看到C盘根目录下的boot.ini文件了。在boot.ini内的[operating systems]栏增添一行:
c:\linux.lnx=”Grub Menu”
并将[boot loader]栏内的“timeout=0”,改为“timeout=5”,这样引导Windows时将会显示带有“Grub Menu”字样的操作系统选择菜单,并持续5秒钟,如果选择Grub Menu,就会进入Grub菜单。
三、设置menu.lst文件
menu.lst是对 Grub进行设置的一个文本文件,可以用文本编辑器加以编辑,位于/boot/grub目录内。我们在前面虽然已经把 Grub安装到了Linux根分区上,但如果没有生成menu.lst文件并对它加以设置,Grub是没有任何作用的。对menu.lst文件进行设置是个复杂的工作,特别是有关kernel和initrd的各种特殊参数,幸而系统安装的menu.lst文件内通常有详尽的注释。并且你的Grub如果是由安装程序自动设置的,那么通常menu.lst已经被设置好了,我们仅仅根据自己的需要进行一些修改和调整,而不必重写menu.lst。即使你的 menu.lst不是由安装程序生成的,也不必担心,还可以参考、分析安装光盘或者LiveCD上的menu.lst文件来对Linux分区内的 menu.lst加以设置。
如果Grub已经由安装程序装到了MBR,并且能够引导所安装的Linux,那么自动生成的Linux系统根分区下的 /boot/grub/menu.lst就已经被配置好了,我们只须把Grub重新安装到Linux系统根分区,恢复Windows下的原初MBR,按照上文的方法把Linux系统根分区的Grub引导代码装载到ntloader就可以了。因为Grub的安装位置不是在menu.lst文件内指定,而是在 linux shell中执行grub,进入Grub命令行后,应用Grub的内部指令root和setup来指定,或者在可执行的shell脚本文件grub- install中,以参数的形式指定设备文件(如/dev/hda或/dev/hdaX)。
假使所安装的Linux系统没有使用Grub,而是使用lilo作为引导管理器,只要lilo能够实现引导,我们就可以借鉴linux系统内的 /etc/lilo.conf文件来对menu.lst加以设置。Lilo.conf是lilo的配置文件,其格式虽然与menu.lst不同,但关键部分是相同的,如指定kernel和initrd的位置,向内核传递引导参数,指定缺省引导的系统和延时时长,在lilo.conf中内核参数是在 APPEND后,我们可以将lilo.conf中的参数移植到menu.lst中。
四、Menu.lst的一个实例:
以下作为实例的 menu.lst是我在windows 2000系统中安装的grub4nt的配置文件,所以可以看到(hd0,0)既是Windows的引导分区,又是Grub文件及一些linux内核文件的所在分区。虽然Grub4nt不能在menu.lst中应用savedefault命令外(可能因为grub4nt不支持在fat32文件系统上的写操作),其他设置与标准的Gnu Grub并无不同,大家可以通过这个实例来具体了解配置文件menu.lst。
default 0
timeout 5
foreground = 333333
background = eeeeee
color light-gray/blue black/light-gray
gfxmenu (hd0,0)/boot/morphix/message
title ubuntu linux
kernel (hd0,2)/vmlinuz ro root=/dev/hda3
title ubuntu linux (rescue mode)
kernel (hd0,2)/vmlinuz ro single root=/dev/hda3
title Other operating systems:
root
title PUD LiveHD
kernel (hd0,0)/boot/pud/linux lang=us ramdisk_size=100000 init=/etc/init apm=power-off vga=791 nomce initrd=miniroot.gz quiet BOOT_IMAGE=knoppix
initrd (hd0,0)/boot/pud/miniroot.gz
title Windows
root (hd0,0) 或者 rootnoverify (hd0,0)
makeactive
chainloader +1
title submenu - Morphix LiveHD
configfile (hd0,1)/boot/grub/menu.lst
这里不对menu.lst做全面解释了,只结合实例,介绍几个重点环节,完整说明请阅读网上Grub的使用手册。
Default 0
default用来设置缺省引导系统,数字序列从0开始,本例会在menu.lst内自动寻找以title开始的词条,并引导第一个title词条,你可以根据自己的需要改成其他数字,如1(第二个title词条);
timeout 5
timeout用来设置Grub引导的延时时长,本例中为5秒钟,系统在等待5秒后用户如果没有手动选择要引导的系统,Grub就会自动引导由default指定的系统;
title ubuntu linux
title用来指示 Grub所引导系统的设置的开始,title后面的文字在Grub菜单中会被作为系统的名称显示出来,本例中Grub引导菜单会显示 ubuntu linux、ubuntu linux (rescue mode)、other operating systems、PUD LiveHD、Windows、submenu - Morphix六个词条,其中第三个词条并非一个真实的系统,仅起指示的作用,故其root部分为空;
kernel (hd0,2)/vmlinuz ro root=/dev/hda3
kernel用来指示linux系统的内核文件的所在位置及引导参数,(hd0,2)/vmlinuz指内核为hda3(第一块硬盘第三个主分 区)内根目录下的vmlinuz文件,根文件系统(/)位于hda3,
注意:指示内核文件所用路径中的分区必须用Grub的表示法,不能用linux的表 示法, 而根文件系统的位置必须用linux下的设备文件名来表示(本例中为/dev/hda3)。有时,vmlinuz并不是真实的内核文件,
而是内核文件的一 个链结文件(link file),但这不影响Grub的引导,它能根据链结文件找到真实的内核并加以引导,这在内核文件带有很长的版本号时会非常有用,简化了内核文件名的拼 写,减少了拼写错误的出错几率
linux kernel 内存管理-页表、TLB
页表用来把虚拟页映射到物理页,并且存放页的保护位(即访问权限)。
在Linux4.11版本以前,Linux内核把页表分为4级:
页全局目录表(PGD)、页上层目录(PUD)、页中间目录(PMD)、直接页表(PT) 。
4.11版本把页表扩展到5级,在页全局目录和页上层目录之间增加了 页四级目录(P4D) 。
各处处理器架构可以选择使用5级,4级,3级或者2级页表,同一种处理器在页长度不同的情况可能选择不同的页表级数。可以使用配置宏CONFIG_PGTABLE_LEVELS配置页表的级数,一般使用默认值。
如果选择4级页表,那么使用PGD,PUD,PMD,PT;如果使用3级页表,那么使用PGD,PMD,PT;如果选择2级页表,那么使用PGD和PT。 如果不使用页中间目录 ,那么内核模拟页中间目录,调用函数pmd_offset 根据页上层目录表项和虚拟地址获取页中间目录表项时 , 直接把页上层目录表项指针强制转换成页中间目录表项 。
每个进程有独立的页表,进程的mm_struct实例的成员pgd指向页全局目录,前面四级页表的表项存放下一级页表的起始地址,直接页表的页表项存放页帧号(PFN) 。
内核也有一个页表, 0号内核线程的进程描述符init_task的成员active_mm指向内存描述符init_mm,内存描述符init_mm的成员pgd指向内核的页全局目录swapper_pg_dir 。
ARM64处理器把页表称为转换表,最多4级。ARM64处理器支持三种页长度:4KB,16KB,64KB。页长度和虚拟地址的宽度决定了转换表的级数,在虚拟地址的宽度为48位的条件下,页长度和转换表级数的关系如下所示:
ARM64处理器把表项称为描述符,使用64位的长描述符格式。描述符的0bit指示描述符是不是有效的:0表示无效,1表示有效。第1位指定描述符类型。
在块描述符和页描述符中,内存属性被拆分为一个高属性和一个低属性块。
处理器的MMU负责把虚拟地址转换成物理地址,为了改进虚拟地址到物理地址的转换速度,避免每次转换都需要查询内存中的页表,处理器厂商在管理单元里加了称为TLB的高速缓存,TLB直译为转换后备缓冲区,意译为页表缓存。
页表缓存用来缓存最近使用过的页表项, 有些处理器使用两级页表缓存 : 第一级TLB分为指令TLB和数据TLB,好处是取指令和取数据可以并行;第二级TLB是统一TLB,即指令和数据共用的TLB 。
不同处理器架构的TLB表项的格式不同。ARM64处理器的每条TLB表项不仅包含虚拟地址和物理地址,也包含属性:内存类型、缓存策略、访问权限、地址空间标识符(ASID)和虚拟机标识符(VMID)。 地址空间标识符区分不同进程的页表项 , 虚拟机标识符区分不同虚拟机的页表项 。
如果内核修改了可能缓存在TLB里面的页表项,那么内核必须负责使旧的TLB表项失效,内核定义了每种处理器架构必须实现的函数。
当TLB没有命中的时候,ARM64处理器的MMU自动遍历内存中的页表,把页表项复制到TLB,不需要软件把页表项写到TLB,所以ARM64架构没有提供写TLB的指令。
为了减少在进程切换时清空页表缓存的需要,ARM64处理器的页表缓存使用非全局位区分内核和进程的页表项(nG位为0表示内核的页表项), 使用地址空间标识符(ASID)区分不同进程的页表项 。
ARM64处理器的ASID长度是由具体实现定义的,可以选择8位或者16位。寄存器TTBR0_EL1或者TTBR1_EL1都可以用来存放当前进程的ASID,通常使用寄存器TCR_EL1的A1位决定使用哪个寄存器存放当前进程的ASID,通常使用寄存器 TTBR0_EL1 。寄存器TTBR0_EL1的位[63:48]或者[63:56]存放当前进程的ASID,位[47:1]存放当前进程的页全局目录的物理地址。
在SMP系统中,ARM64架构要求ASID在处理器的所有核是唯一的。假设ASID为8位,ASID只有256个值,其中0是保留值,可分配的ASID范围1~255,进程的数量可能超过255,两个进程的ASID可能相同,内核引入ASID版本号解决这个问题。
(1)每个进程有一个64位的软件ASID, 低8位存放硬件ASID,高56位存放ASID版本号 。
(2) 64位全局变量asid_generation的高56位保存全局ASID版本号 。
(3) 当进程被调度时,比较进程的ASID版本号和全局版本号 。如果版本号相同,那么直接使用上次分配的ASID,否则需要给进程重新分配硬件ASID。
存在空闲ASID,那么选择一个分配给进程。不存在空闲ASID时,把全局ASID版本号加1,重新从1开始分配硬件ASID,即硬件ASID从255回绕到1。因为刚分配的硬件ASID可能和某个进程的ASID相同,只是ASID版本号不同,页表缓存可能包含了这个进程的页表项,所以必须把所有处理器的页表缓存清空。
引入ASID版本号的好处是:避免每次进程切换都需要清空页表缓存,只需要在硬件ASID回环时把处理器的页表缓存清空 。
虚拟机里面运行的客户操作系统的虚拟地址转物理地址分两个阶段:
(1) 把虚拟地址转换成中间物理地址,由客户操作系统的内核控制 ,和非虚拟化的转换过程相同。
(2) 把中间物理地址转换成物理地址,由虚拟机监控器控制 ,虚拟机监控器为每个虚拟机维护一个转换表,分配一个虚拟机标识符,寄存器 VTTBR_EL2 存放当前虚拟机的阶段2转换表的物理地址。
每个虚拟机有独立的ASID空间 ,页表缓存使用 虚拟机标识符 区分不同虚拟机的转换表项,避免每次虚拟机切换都要清空页表缓存,在虚拟机标识符回绕时把处理器的页表缓存清空。
linux内核模块编写要求从一个虚存区VMA和一个虚地址addr求这个地址所在的物理页面
implicit declaration of function ***
查查英语也应该晓得linux中pud命令了阿....
隐式的函数声明linux中pud命令,就是说你使用linux中pud命令了kmap_atomic、kmap_atomic但是没有声明,一般是因为没有包含头文件,或者是内核的API发生了些许变化。
这两个函数包含在linux/highmem.h中,你在程序中添加一句:#include linux/highmem.h试试。
PS :这个是在2.6.38的内核中的,你在lxr.linux.no搜下对应版本的kernel,linux中pud命令我没有细细查。
关于linux中pud命令和purge命令linux的的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。