作者:LLX
代码路径: linux-4.6\linux-4.6\arch\x86\kernel\head_32.S
1、startup_32
1.1、赋值堆栈
这个主要的作用是赋值对应的堆栈,给esp重新的指针,以及如果再bootflag的标志keep_segments里面看是不是进入32要重新初始化段寄存器,
1.2、clear bss段,以及复制boot_param
这段代码主要功能是最开始把bss段的内容设置为0,这里面bss_start到bss_stop表示bss段这一部分的地址
这个地址是在连接脚本里面进行定义的,这里面为什么要对bss_start减去pa地址因为编译好的地址是虚拟地址,这个时候只是进入保护模式,而后面分页开启,这个
可以看到在编译好了对应的内核文件的时候,bss_start的地址是一个虚拟地址,是开启分页之后的地址,那么现在还没有开启分页,那就是真实的物理内存地址,他们之间的联系是虚拟地址-0xc0000000=物理地址,所以代码里面进行pa变成物理地址
141行后面一段boot_params的含义是吧对应的boot参数赋值到boot_params这个变量,
152行可以看到boot_params赋值到edi原来的esi是放着setup里面的boot_params
这两个代码名字一样,不过是不同编译的,也就是不同的变量,
155-161行这个主要是吧原来的boot_params复制到新的boot_params里面
162行,这个是boot_params里面hdr里面的cmd_line_ptr指向的地址了
163行-168行吧boot_params里面的cmd_line_ptr的地址里面的数据复制到boot_command_line变量里面,这里面用pa宏定义,是因为现在开启了保护模式,可以还没有开启分页,
1.3、这里分析没有开启PAE功能
246行,这个pde是页目录表,为什么偏移20位,因为页目录表的格式(引用12):
可以看到directory的地址是在bit22-31的,那么应该pde是右移22位的,
那么他右移20位的原因:
__PAGE_OFFSET>>12>>10计算出在pgd中的页目录项index
(__PAGE_OFFSET>>12>>10)<<2计算出偏移地址(因为每个页目录项4byte)
一个是i