grub stage 1.5


stage1的代码文件,是源码目录下 stage1/stage1.S,汇编后便成了一个512字节的 img,
被写在硬盘的0面0道第1扇区,作为硬盘的主引导扇区。


注意,硬盘主引导扇区 = 硬盘主引导记录(MBR)+ 硬盘分区表(DPT)


stage1的工作并不是加载什么 stage1.5或者 stage2,而是加载0面0道第2扇区上的512字
节代码至0x8000,然后跳至0x8000执行。


这里我们提及的另一个512字节代码,是来
自源码目录下 stage2/start.S 文件的,而 start.S 的作用是作为 stage1.5或者 stage2(视乎
编译 grub 时的指定)的总入口,它才是 stage1.5或者 stage2的真正加载器。


总结起来,那么就是 stage1加载 start,然后将执行权交给 start,由start 来加载 stage1.5
或者 stage2。所以,斑竹说的“安装程序会在 stage1中嵌入 stage1.5或者 stage2的磁盘
位置信息”这句话是错误的。






  stage1.S 被放在  0 面 0 道的第  1 扇区,
 start.S 被放在  0 面 0 道的第 2 扇区,而与 boot 分区相
关的文件系统的 xxfs_stage1_5 被放在 0 面 0 道第 3 扇
区开始的扇区里,其占据的扇区数目与该 stage1_5  文
件的大小有关。


而其余的 stage1_5 以及 stage2  都作为文件被存放在   boot 分区里。


+------------+
| stage1     | <-- 0 面 0 道第 1 扇区
+------------+
| start      | <-- 0 面 0 道第 2 扇区
+------------+
| stage1_5   | <-- 0 面 0 道第 3 扇区
| ...        |
| ...        |
+------------+


stage1.S被放在0面0道的第1扇区,start.S被放在0面0道的第2扇区,而与boot分区相关的文件系统的xxfs_stage1_5被放在0面0道第3扇区开始的扇区里,其占据的扇区数目与该stage1_5文件的大小有关。而其余的stage1_5以及stage2都作为文件被存放在boot分区里。




grub stage1_5 的运行流程 (2009-09-25 15:21:11)转载▼
标签: 杂谈
1.   ../stage2/asm.s
当define了STAGE1_5标识后,start.s文件依然会被编译成一个sector(放在0面0道第2扇区),但是会被加载到内存的0x2000的地方,整个文件占据了0x2000到0x21ff的位置
由于定义了STAGE1_5,这个文件最后的list会是这样:
  lastlist:
      .word 0
      .word 0
      . = _start + 0x200 - BOOTSEC_LISTSIZE
       
  blocklist_default_start:
      .long 2  
  blocklist_default_len:
                       
      .word 0  
  blocklist_default_seg:
      .word 0x220
  firstlist: 
程序开头
  movw $ABS(firstlist - BOOTSEC_LISTSIZE), %di
di=fistlist-BOOTSEC_LISTSIZE,BOOTSEC_LISTSIZE=8,所以di指向list当中的第四行“blocklist_default_start”起始位置,随后将di中的内容保存到堆栈中
在bootloop中
  cmpw $0, 4(%di)
di+4刚好是0,所以没有load任何东西,直接跳到bootit
  ljmp $0, $0x2200
0x2200,这个地址在内存中是紧跟着start.s的,是由../stage2/asm.s编译得到的
2.   ../stage2/asm.s
asm.s以及其他一些必须的文件会被编译为一个模块加载到0x2200的地方。
由于定义了STAGE1_5,asm.s也没有干很多事。首先定义了一堆常量,需要注意的是config_file
  VARIABLE(config_file)
  #ifndef STAGE1_5
        .string "/boot/grub/menu.lst"
  #else  
        .long 0xffffffff
        .string "/boot/grub/stage2"
  #endif 
然后执行了两个函数,估计是驱动一类,不是很了解
  ADDR32 movl %ebp, EXT_C(install_second_sector)
  ADDR32 movb %dl, EXT_C(boot_drive)
由实模式切换到保护模式
最后call EXT_C(init_bios_info),这个函数不会return
3. ../stage2/common.c init_bios_info 
同样,由于设置了STAGE1_5,这个函数的任务也减少了一大半
*get_memsize
*set boot drive and partiton
*set cdrom
*get geometry
最后,执行cmain


4. ../stage/stage1_5.c cmain
stage1_5.c的cmain程序的任务就是通过文件系统读取stage2的kernel,将其加载的0x8000,然后跳转到0x8200的地方开始stage2的代码执行(那200个字节的内容是被编译到stage2中的start.s文件)
首先grub_open (config_file),config_file已经由前面设置成/boot/grub/stage2了
然后读取到0x8000的地方,grub_read ((char *) 0x8000, SECTOR_SIZE * 2);
这里只读入2个扇区,第一个是start.s,后面执行的时候会被跳过;第二个应该是asm.s,它来负责读入stage2 kernel
最后跳到0x8200的地方开始执行stage2的代码,chain_stage2 (0, 0x8200, saved_sector);
stage1_5光荣退休


stage2 就是接受命令,解析命令,执行命令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值