热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

当前位置 :| 主页>Linux教程>内核研究>

/sys/i386/i386/locore.s分析笔记

来源: 作者: 时间:2008-08-27 Tag: 点击:

继续回到KPTphys(0x1000000)之后的页表区域。再分配一个页表条目给cpu0pp指向的
1个页面的区域(0x1025000),属性为读写。
0x1000000 : 0x00000003 0x00001003 0x00002003 0x00003003
0x1000010 : 0x00004003 0x00005003 0x00006003 0x00007003
......
0x1003fe0 : 0x00ff8003 0x00ff9003 0x00ffa003 0x00ffb003
0x1003ff0 : 0x00ffc003 0x00ffd003 0x00ffe003 0x00fff003
0x1004000 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004010 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004020 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004030 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004040 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004050 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004060 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004070 : 0x00000000 0x00000000 0x0101e003 0x0101f003
0x1004080 : 0x01020003 0x01021003 0x01022003 0x01023003
0x1004090 : 0x01024003 0x01025003
863 /* Map SMP page table page into global kmem FWIW */
864 movl R(SMPptpa), %eax
865 movl $1, %ecx
866 fillkptphys($PG_RW)
再分配一个页表条目给SMPptpa指向的1个页面的区域(0x1026000),属性为读写。
0x1000000 : 0x00000003 0x00001003 0x00002003 0x00003003
0x1000010 : 0x00004003 0x00005003 0x00006003 0x00007003
......
0x1003fe0 : 0x00ff8003 0x00ff9003 0x00ffa003 0x00ffb003
0x1003ff0 : 0x00ffc003 0x00ffd003 0x00ffe003 0x00fff003
0x1004000 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004010 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004020 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004030 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004040 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004050 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004060 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1004070 : 0x00000000 0x00000000 0x0101e003 0x0101f003
0x1004080 : 0x01020003 0x01021003 0x01022003 0x01023003
0x1004090 : 0x01024003 0x01025003 0x01026003
868 /* Map the private page into the SMP page table */
869 movl R(cpu0pp), %eax
870 movl $0, %ebx /* pte offset = 0 */
871 movl $1, %ecx /* one private page coming right up */
872 fillkpt(R(SMPptpa), $PG_RW)
在SMPptpa(0x1026000)页面中分配一个页表条目来映射cpu0pp(0x1025000)指向的页面,
属性为读写。
0x1026000 : 0x01025003 0x00000000 0x00000000 0x00000000
874 /* ... and put the page table table in the pde. */
875 movl R(SMPptpa), %eax
876 movl $MPPTDI, %ebx
877 movl $1, %ecx
878 fillkpt(R(IdlePTD), $PG_RW)
在IdlePTD指向的页表页面目录中创建一条页表目录项来指向SMPptpa指向的SMP页表页面。
MPPTDI定义为1023,表示最后一个页表目录项。属性为读写。我们可以看到,页表目录页面
的其它页表目录项的内容到此时仍然为空。
0x101e000 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101e010 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101efe0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101eff0 : 0x00000000 0x00000000 0x00000000 0x01026003
880 /* Fakeup VA for the local apic to allow early traps. */
881 ALLOCPAGES(1)
882 movl %esi, %eax
883 movl $(NPTEPG-1), %ebx /* pte offset = NTEPG-1 */
884 movl $1, %ecx /* one private pt coming right up */
885 fillkpt(R(SMPptpa), $PG_RW)
再分配一个页面,此时physfree指向0x1028000。将SMPptpa(0x1026000)页面中的最后
一个条目用来映射这个新分配的页面,属性为读写。
0x1026000 : 0x01025003 0x00000000 0x00000000 0x00000000
0x1026010 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x1026fe0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x1026ff0 : 0x00000000 0x00000000 0x00000000 0x01027003
888 /*
889 * Create an identity mapping for low physical memory, including the kernel.
890 * The part of this mapping that covers the first 1 MB of physical memory
891 * becomes a permanent part of the kernel's address space. The rest of this
892 * mapping is destroyed in pmap_bootstrap(). Ordinarily, the same page table
893 * pages are shared by the identity mapping and the kernel's native mapping.
894 * However, the permanent identity mapping cannot contain PG_G mappings.
895 * Thus, if the kernel is loaded within the permanent identity mapping, that
896 * page table page must be duplicated and not shared.
897 *
898 * N.B. Due to errata concerning large pages and physical address zero,
899 * a PG_PS mapping is not used.
900 */
901 movl R(KPTphys), %eax
902 xorl %ebx, %ebx
903 movl $NKPT, %ecx
904 fillkpt(R(IdlePTD), $PG_RW)
将IdlePTD(0x101e000)页面中的前NKPT(30)个条目用来映射KPTphys(0x1000000)
指向的30个页面的空间,属性为读写。
0x101e000 : 0x01000003 0x01001003 0x01002003 0x01003003
0x101e010 : 0x01004003 0x01005003 0x01006003 0x01007003
0x101e020 : 0x01008003 0x01009003 0x0100a003 0x0100b003
0x101e030 : 0x0100c003 0x0100d003 0x0100e003 0x0100f003
0x101e040 : 0x01010003 0x01011003 0x01012003 0x01013003
0x101e050 : 0x01014003 0x01015003 0x01016003 0x01017003
0x101e060 : 0x01018003 0x01019003 0x0101a003 0x0101b003
0x101e070 : 0x0101c003 0x0101d003 0x00000000 0x00000000
0x101e080 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101efe0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101eff0 : 0x00000000 0x00000000 0x00000000 0x01026003
920 /*
921 * For the non-PSE case, install PDEs for PTs covering the KVA.
922 * For the PSE case, do the same, but clobber the ones corresponding
923 * to the kernel (from btext to KERNend) with 4M (2M for PAE) ('PS')
924 * PDEs immediately after.
925 */
926 movl R(KPTphys), %eax
927 movl $KPTDI, %ebx
928 movl $NKPT, %ecx
929 fillkpt(R(IdlePTD), $PG_RW)
930 cmpl $0,R(pseflag)
931 je done_pde
KPTDI定义为第一个内核页表目录的索引,即768。926到929行将IdlePTD(0x101e000)
页面中的第768项之后的30个页表目录项用来指向KPTphys(0x1000000)指向的30个
页面空间,属性为读写。
0x101e000 : 0x01000003 0x01001003 0x01002003 0x01003003
0x101e010 : 0x01004003 0x01005003 0x01006003 0x01007003
0x101e020 : 0x01008003 0x01009003 0x0100a003 0x0100b003
0x101e030 : 0x0100c003 0x0100d003 0x0100e003 0x0100f003
0x101e040 : 0x01010003 0x01011003 0x01012003 0x01013003
0x101e050 : 0x01014003 0x01015003 0x01016003 0x01017003
0x101e060 : 0x01018003 0x01019003 0x0101a003 0x0101b003
0x101e070 : 0x0101c003 0x0101d003 0x00000000 0x00000000
0x101e080 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101ebf0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101ec00 : 0x01000003 0x01001003 0x01002003 0x01003003
0x101ec10 : 0x01004003 0x01005003 0x01006003 0x01007003
0x101ec20 : 0x01008003 0x01009003 0x0100a003 0x0100b003
0x101ec30 : 0x0100c003 0x0100d003 0x0100e003 0x0100f003
0x101ec40 : 0x01010003 0x01011003 0x01012003 0x01013003
0x101ec50 : 0x01014003 0x01015003 0x01016003 0x01017003
0x101ec60 : 0x01018003 0x01019003 0x0101a003 0x0101b003
0x101ec70 : 0x0101c003 0x0101d003 0x00000000 0x00000000
0x101ec80 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101efe0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101eff0 : 0x00000000 0x00000000 0x00000000 0x01026003
930 cmpl $0,R(pseflag)
931 je done_pde
若全局变量pseflag为0,则跳转至done_pde,示例中此变量为1。
933 movl R(KERNend), %ecx
934 movl $KERNLOAD, %eax
935 subl %eax, %ecx
936 shrl $PDRSHIFT, %ecx
937 movl $(KPTDI+(KERNLOAD/(1 << PDRSHIFT))), %ebx
938 shll $PDESHIFT, %ebx
939 addl R(IdlePTD), %ebx
940 orl $(PG_V|PG_RW|PG_PS), %eax
941 1: movl %eax, (%ebx)
942 addl $(1 << PDRSHIFT), %eax
943 addl $PDESIZE, %ebx
944 loop 1b
933行将KERNend(0x1000000)写入ecx。934行将KERNLOAD(0x400000)写入eax。
935行从ecx中减去eax,得到0xc00000。936行将ecx右移22比特,得到3。
937行,(KERNLOAD/(1 << PDRSHIFT))表示KRENLOAD中有多少个4M(占用了多少个
页表目录项),因为KERNLOAD就是4M,因此这个计算为1,最终写入ebx的值是769。
938行,PDESHIFT定义为2,将ebx左移2比特之后得到的就是第769个页表目录项在
页表目录页面中的偏移地址。939行将ebx加上页表目录页面的基地址
IdlePTD(0x101e000)之后得到第769个页表目录项的地址0x101ec04。940行,
在eax中构造第769个页表目录项的内容,在已有的KERNLOAD地址的基础上,
再加上属性PG_V|PG_RW|PG_PS(0x83),表示当前在物理内存中、可读写、页面
尺寸为4M。941到944行,将eax中构造好的第769、770、771个页表目录项写入ebx
中的指定位置。
0x101e000 : 0x01000003 0x01001003 0x01002003 0x01003003
0x101e010 : 0x01004003 0x01005003 0x01006003 0x01007003
0x101e020 : 0x01008003 0x01009003 0x0100a003 0x0100b003
0x101e030 : 0x0100c003 0x0100d003 0x0100e003 0x0100f003
0x101e040 : 0x01010003 0x01011003 0x01012003 0x01013003
0x101e050 : 0x01014003 0x01015003 0x01016003 0x01017003
0x101e060 : 0x01018003 0x01019003 0x0101a003 0x0101b003
0x101e070 : 0x0101c003 0x0101d003 0x00000000 0x00000000
0x101e080 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101ebf0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101ec00 : 0x01000003 0x00400083 0x00800083 0x00c00083
0x101ec10 : 0x01004003 0x01005003 0x01006003 0x01007003
0x101ec20 : 0x01008003 0x01009003 0x0100a003 0x0100b003
0x101ec30 : 0x0100c003 0x0100d003 0x0100e003 0x0100f003
0x101ec40 : 0x01010003 0x01011003 0x01012003 0x01013003
0x101ec50 : 0x01014003 0x01015003 0x01016003 0x01017003
0x101ec60 : 0x01018003 0x01019003 0x0101a003 0x0101b003
0x101ec70 : 0x0101c003 0x0101d003 0x00000000 0x00000000
0x101ec80 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101efe0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101eff0 : 0x00000000 0x00000000 0x00000000 0x01026003
946 done_pde:
947 /* install a pde recursively mapping page directory as a page table */
948 movl R(IdlePTD), %eax
949 movl $PTDPTDI, %ebx
950 movl $NPGPTD,%ecx
951 fillkpt(R(IdlePTD), $PG_RW)
将IdlePTD(0x101e000)页面中的第PTDPTDI(767)个页表目录项指向IdelPTD页面,
属性为读写。
0x101e000 : 0x01000003 0x01001003 0x01002003 0x01003003
0x101e010 : 0x01004003 0x01005003 0x01006003 0x01007003
0x101e020 : 0x01008003 0x01009003 0x0100a003 0x0100b003
0x101e030 : 0x0100c003 0x0100d003 0x0100e003 0x0100f003
0x101e040 : 0x01010003 0x01011003 0x01012003 0x01013003
0x101e050 : 0x01014003 0x01015003 0x01016003 0x01017003
0x101e060 : 0x01018003 0x01019003 0x0101a003 0x0101b003
0x101e070 : 0x0101c003 0x0101d003 0x00000000 0x00000000
0x101e080 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101ebe0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101ebf0 : 0x00000000 0x00000000 0x00000000 0x0101e003
0x101ec00 : 0x01000003 0x00400083 0x00800083 0x00c00083
0x101ec10 : 0x01004003 0x01005003 0x01006003 0x01007003
0x101ec20 : 0x01008003 0x01009003 0x0100a003 0x0100b003
0x101ec30 : 0x0100c003 0x0100d003 0x0100e003 0x0100f003
0x101ec40 : 0x01010003 0x01011003 0x01012003 0x01013003
0x101ec50 : 0x01014003 0x01015003 0x01016003 0x01017003
0x101ec60 : 0x01018003 0x01019003 0x0101a003 0x0101b003
0x101ec70 : 0x0101c003 0x0101d003 0x00000000 0x00000000
0x101ec80 : 0x00000000 0x00000000 0x00000000 0x00000000
......
0x101efe0 : 0x00000000 0x00000000 0x00000000 0x00000000
0x101eff0 : 0x00000000 0x00000000 0x00000000 0x01026003
960 ret
返回到btex主流程中。


相关文章:
精通initramfs构建step by step
Linux利用kexec迅速切换内核
进程上下文VS中断上下文
内核通知链 学习笔记
linux spi子系统驱动分析
menuconfig 配置选项
《Linux操作系统内核实习》之练习一
udev详解
什么叫微内核,宏内核?
Linux 信号signal处理机制
开发简单的 Linux2.6 内核模块
删除内核的perl脚本
Linux2.6内核usb gadget驱动移植
GCC hacks in the Linux kernel
iomem
kernel学习的想法
让自己的驱动支持udev
linux内核编译步骤
内核的等待队列
Linux内核wait_queue深入分析
升级和删除内核
SD卡驱动分析2
Linux Kernel VDSO本地权限提升漏洞
内核中的TCP的追踪分析-15-TCP(IPV4)的客户端与
linux 2.6内核可加载模块的编译
内核模块HelloWorld
在环回接口上发送一个数据报
ARP初始化
1分钟编译FreeBSD内核
linux设备模型之uart驱动架构分析