Linux0.11内核--启动代码分析setup.s 建立页目录和页表
2011-05-19 22:25
579 查看
head.s开始
pg_dir
....
....
....
....
.org 0x1000
pg0:
.org 0x2000
pg1:
.org 0x3000
pg2:
.org 0x4000
pg3:
.org 0x5000
后面是setup_paging代码
setup_paging: movl $1024*5,%ecx /* 5 pages - pg_dir+4 page tables */ xorl %eax,%eax xorl %edi,%edi /* pg_dir is at 0x000 */ cld;rep;stosl movl $pg0+7,pg_dir /* set present bit/user r/w */ movl $pg1+7,pg_dir+4 /* --------- " " --------- */ movl $pg2+7,pg_dir+8 /* --------- " " --------- */ movl $pg3+7,pg_dir+12 /* --------- " " --------- */ movl $pg3+4092,%edi movl $0xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) */ std 1: stosl /* fill pages backwards - more efficient :-) */ subl $0x1000,%eax jge 1b xorl %eax,%eax /* pg_dir is at 0x0000 */ movl %eax,%cr3 /* cr3 - page directory start */ movl %cr0,%eax orl $0x80000000,%eax movl %eax,%cr0 /* set paging (PG) bit */ ret /* this also flushes prefetch-queue */
其中:
movl $pg0+7,pg_dir /* set present bit/user r/w */
movl $pg1+7,pg_dir+4 /* --------- " " --------- */
movl $pg2+7,pg_dir+8 /* --------- " " --------- */
movl $pg3+7,pg_dir+12 /* --------- " " --------- */
设置页目录表中的项
由于pg0的地址在0x1000位置,则$pg0+7表示的是0x00001007
第 1 个页表的属性标志 = 0x00001007 & 0x00000fff = 0x007,表示该页存在、用户可读写。(由于每个页大小为4K,用12 bit位表
示)
然后
movl $pg3+4092,%edi
movl $0xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) */
std
1: stosl /* fill pages backwards - more efficient :-) */
subl $0x1000,%eax
jge 1b
填写4个也表的内容
由于每个页表有1024项*4个页表=4096项,4096*4K=16M,正好完全覆盖地址空间。
Linus是从后向前设置页表,最后一个页表的最后一项对应的地址为16M-4096,即0xFFF000,然后加上属性标志0x007,得0xFFF007
每写一项地址减0x1000,也就是减去4K,正好对应一个页。
这程序循环0xFFF+1次
最后:
设置页目录基址寄存器 cr3 的值,指向页目录表
xorl %eax,%eax /* pg_dir is at 0x0000 */ movl %eax,%cr3 /* cr3 - page directory start */
设置启动使用分页处理(cr0 的 PG 标志,位 31)
movl %cr0,%eax orl $0x80000000,%eax movl %eax,%cr0 /* set paging (PG) bit */ ret /* this also flushes prefetch-queue */
使用ret指令,将main函数地址从栈中弹出至CS,跳转到main去执行。
相关文章推荐
- Linux0.11内核--启动代码分析setup.s 建立页目录和页表
- linux-3.2.36内核启动3-setup_arch中的内存初始化2(arm平台 分析建立页表)
- Linux0.11内核--启动引导代码分析setup.s
- Linux0.11内核--启动引导代码分析setup.s
- linux-3.2.36内核启动3-setup_arch中的内存初始化2(arm平台 分析建立页表)
- Linux0.11内核--启动引导代码分析setup.s
- linux0.11 内核启动代码分析(二)
- Linux0.11内核--启动引导代码分析bootsect.s
- Linux0.11内核--启动引导代码分析bootsect.s
- Linux0.11内核--启动引导代码分析bootsect.s
- linux0.11 内核启动代码分析(一)
- linux i2c子系统代码分析8 ---i2c子系统内核目录介绍
- Linux 0.11中的页目录表及页表内容分析
- linux 0.11 version 启动代码分析(bootsect.s)
- linux-3.2.36内核启动2-setup_arch中的内存初始化1(arm平台 分析高端内存和初始化memblock)【转】
- linux-3.2.36内核启动1-启动参数(arm平台 启动参数的获取和处理,分析setup_arch)
- linux-3.2.36内核启动4-setup_arch中的内存初始化3(arm平台 bootmem_init源码分析)
- ARM架构内核启动分析-head.S(1.3、stext分析之内存临时页表建立)
- arm-linux内核start_kernel之前启动分析(2)- 页表的准备
- linux非解压代码的启动过程分析 unicore head.S vmlinux解压后的代码运行 临时MMU的建立