grub2研究(2)

转载时请注明出处和作者联系方式作者联系方式:diablo_work at 126 dot com

Grub为了减少内核的大小,采用了Module的设计。根据需要,动态导入的方法。Module的使用又可以分为两种,一种是在grub还没有文件系统知识时需要使用的,这部分Module是被“原模原样”、连续的写到磁盘上的,是紧跟在kernel.img后面的。该部分典型的就是文件系统Module,例如在linux系统上使用的ext2.mod。另一种是在grub已经具备文件系统知识的情况下,将module以文件的方式在保存在磁盘上的。典型的是normal.mod(关于这部分模块后面还会讲)

现在grub的开始执行kernel.img中的内容。前面提到过,kernel.img中的内容是压缩后放到磁盘上的,但压缩的东西是不可执行的,需要解压缩后才能执行。但由谁来解压缩呢,grub是这样实现的:kernel.img的前0x 4A 0个字节是不进行压缩的,该部分不压缩的代码对应为kern/i386/pc/startup.Sstartup.S的有两个主要任务,1.解压缩内核,将控制权交到grub的内核,也就是将是将控制权交到kern/main.cgrub_main函数。2.提供一些例程。主要是一些很难用c写的代码,比如实模式和保护模式的相互切换。

为便于说明,在原有的英文注释的基础上再增加一些注释。

_start:

       /*

        *  Guarantee that "main" is loaded at 0x0:0x8200.

        */

       ljmp $0, $ABS(codestart)

 

/* the real mode code continues... */

codestart:

       cli           /* we're not safe here! */

 

       /* set up %ds, %ss, and %es */

       /*寄存器ax,ds,ss,es清零*/

       xorw       %ax, %ax

       movw     %ax, %ds

       movw     %ax, %ss

       movw     %ax, %es

 

       /* set up the real mode/BIOS stack */

       movl       $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp

       movl       %ebp, %esp

 

       sti           /* we're safe again */

 

       /* save boot drive reference */

       /*dl保存当前的磁盘驱动器号,可参考boot.S中的代码*/

       ADDR32 movb      %dl, EXT_C(grub_boot_drive)

 

       /* reset disk system (%ah = 0) */

       int    $0x13

      

       /* transition to protected mode */

       DATA32  call real_to_prot

 

       /* The ".code32" directive takes GAS out of 16-bit mode. */

       .code32

 

       incl  %eax

       /*关于a20的问题,可在网上参考,有很多,肯定比我讲得好。*/

       call  EXT_C(grub_gate_a20)

      

       /* decompress the compressed part and put the result at 1MB */

/* START_SYMBOL 的值应该等于_start ,也就是0x8200*/

/* GRUB_KERNEL_MACHINE_RAW_SIZE 的值代表Startup.S代码编译过后的大小*/

/*解压缩后的内容暂时放在0: 0x100000*/

       movl       $0x100000, %esi

       movl       $(START_SYMBOL + GRUB_KERNEL_MACHINE_RAW_SIZE), %edi

       /*参数压栈*/

       pushl       %esi

       pushl       EXT_C(grub_compressed_size)

       pushl       %edi

       call  lzo1x_decompress

       /*调用者负责清理堆栈*/

addl $12, %esp

   

       /* copy back the decompressed part */

       /*查看函数的lzo1x_decompress实现,可以发现,在调用lzo1x_decompress 前后,寄存器ds:esi,es:edi的值不会发生改变,此处将解压缩后代码拷贝到startup.S的后面*/

       movl       %eax, %ecx

       cld

       rep

       movsb

 

       /* copy modules before cleaning out the bss */

       /*将紧跟在解压缩后的module放到kernel的后面*/

       movl       EXT_C(grub_total_module_size), %ecx

       movl       EXT_C(grub_kernel_image_size), %esi

       addl %ecx, %esi

       addl $START_SYMBOL, %esi

       decl %esi

       movl       $END_SYMBOL, %edi

       addl %ecx, %edi

       decl %edi

       std

       rep

       movsb

      

       /* clean out the bss */

       movl       $BSS_START_SYMBOL, %edi

 

       /* compute the bss length */

       movl       $END_SYMBOL, %ecx

       subl %edi, %ecx

                    

       /* clean out */

       xorl  %eax, %eax

       cld

       rep

       stosb

      

       /*

        *  Call the start of main body of C code.

        */

       call EXT_C(grub_main)

  待续。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值