全部博文(92)
分类: LINUX
2006-09-14 17:19:46
Linux 运行时内核分析(二版)
我们基于RH9 内核从两部分来分析Linux系统动态运行过程
一:系统初始化开始,Linux进入保护模式,初始内存系统、中断系统、文件系
统等,直到创建第一个用户进程。
二:用户进程通过系统调用主动进入内核,CPU 接受中断请求被动执行各种中
断服务。
第一部分 系统初始化
进入保护模式 Arch/i386/boot/Setup.s
gdt:
.fill GDT_ENTRY_KERNEL_CS,8,0 #空12×(8个字节=2个双字),用0 填充。
.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
.word 0x9A00 # code read/exec
.word 0x00CF # granularity = 4096, 386
# (+5th nibble of limit)
.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
.word 0x9200 # data read/write
.word 0x00CF # granularity = 4096, 386
gdt_48:
.word 0x8000 # gdt limit=2048,
# 256 GDT entries
我们进入保护模式之后选择子首先应该是0x60 = 1100000b, 右移3 位为1100 =
0xC = 12 ,这就是code在GDT里的位置。当然这只是第一次进入保护模式,以
后还会调整。
进入分页模式 arch/i386/kernel/head.S
.org 0x1000
ENTRY(swapper_pg_dir)
.long 0x00102007 #基地址为0x00102000,就是下面pg0,0x00100000是内核
加载的地方,1M的位置
.long 0x00103007
.fill BOOT_USER_PGD_PTRS-2,4,0 #768-2 (long) 0
/* default: 766 entries */
.long 0x00102007
.long 0x00103007
/* default: 254 entries */
.fill BOOT_KERNEL_PGD_PTRS-2,4,0 #256-2(long) 0
# 这个说明了内核是1G,用户就3G。
.org 0x2000
ENTRY(pg0)
.org 0x3000
ENTRY(pg1)
说明映射了两个页面,一个页面代表4M, 每个pg0 里的一项代表4K。具体pg0
数据是用程序填充的 参考L82。L101 通过短跳转进入分页(但eip 还不是),L104
通过绝对地址完全进入分页。比如L105的地址是0xC0100058 =1100 0000 0001
0000 0000 0000 0101 1000B,高10 位为1100 0000 00 = 0x300 = 768。从
swapper_pg_dir里找768项就是0x00102007,检查之后基地址为0x00102000;就是
pg0,再看0xC0100058 中间10位01 0000 0000B = 0x100 = 256,再找pg0 的256项
应该为00100***,那么最后的物理地址为0x00100058,所以内核里的虚拟地址换
物理地址很简单,就是0xC0100058 - 0xC0000000 = 0x00100058 就是物理地址。
现在系统只是映射了8M的内存空间,之后还会调整。
内存管理
物理内存管理
第一次探测 Arch/i386/boot/setup.S L281
在这里使用了三种方法,通过调用0x15 中断:
E820H 得到memory map。
E801H 得到大小。
88H 0-64M.
第二次探测
start_kernel() -> setup_arch()
这里主要是对物?E