先前GRUB已经把我们的操作系统加载到内存了;
此处二级引导器的作用:先驱,收集机器信息,看计算机能否运行我们的操作系统,对CPU、内存、显卡等进行配置,放置好内核相关文件;不执行具体的加载任务;
中心思想(把处理操作系统运行环境的工作独立出来,交给二级引导器来做,这回大大减低后面开发操作系统的难度,增加操作系统的通用性;针对不同的硬件平台,只要开发不同的二级引导器就行)
实现GRUB头:
GRUB头有两个文件组成:imginithead.asm汇编文件:让GRUB识别,设置c语言运行环境,调用c函数; inithead.c文件:查找二级引导器的核心文件initldrkrl.bin;将它放置到特定的内存地址上;
imginithead.asm文件主要的工作是:初始化CPU寄存器,关中断并加载GDT,切换到CPU的保护模式,最后初始化段寄存器和通用寄存器、栈寄存器,并调用了inithead_entry函数;这个函数在inithead.c中实现的;inithead_entry函数主要工作:分别调用write_realintsvefile();write_ldrkrlfile()函数;把映像文件中的initldrsve.bin文件和initldrkrl.bin文件写入到特定的内存中;这两个函数依赖于find_file和m2mcopy函数;find_file函数负责扫描映像文件中的文件头描述符,对比其中的文件名,然后返回对应的文件头描述符的地址,这样就得到文件在映像文件中的位置和大小了;m2mcopy函数负责把映像文件复制到具体的内存空间中;
进入二级引导器:
jmp 0x200000地址,正是inithead.c中由wirte_ldrkrlfile()函数放置的initldrkrl.bin文件;进入二级引导器的主模块了;
需要重新初始化CPU寄存器,加载GDTR、IDTR寄存器,最后调用二级引导器的主函数ldrkrl_entry。
调用BIOS中断:
这时需要设置中断服务,为后面内存布局、显卡图形模式等依赖这个中断;;
c函数中调用BIOS中断处理的问题:c工作在32位保护模式,BIOS中断工作在16位实模式;
先要保存c语言环境下的CPU上下文;即保护模式下的所有寄存器都保存在内存中;
接着切换回实模式,掉哟BIOS中断,返回相关结果;
切换会保护模式,重新加载保存的寄存器,恢复c语言环境;
这儿是ldrkrl32.asm文件完成,并且建立一个realintsve.asm文件,将它编译为16位 的二进制文件,放在0x1000开始的地方;
二级引导器主函数:
建立c文件ldrkrlentry.c,其中有一个函数,ldrkrl_entry函数,调用init_bstartparm函数,就是收集机器环境信息的;
思考题:
GRUB头中为什么需要 _entry 标号, _start 标号的地址???
标签:03,函数,GRUB,文件,环境,二级,寄存器,引导 From: https://www.cnblogs.com/xuan01/p/17334596.html