linux 2.6源代码情景分析笔记之系统启动2

Linux内核启动解析

linux/arch/i386/boot/compressed/head.S
在setup()结束后,此函数就被移动到物理地址0x00100000处或者0x00001000处,这取决于内核映像是被高装载到ram中还是低装载到ram中。
解读函数:

startup_32:
        cld
        cli
        movl $(__BOOT_DS),%eax
        movl %eax,%ds
        movl %eax,%es
        movl %eax,%fs
        movl %eax,%gs

        lss stack_start,%esp
其中的boot_ds内存中已经有谈及。初始化了段寄存器和一个临时队栈。

        xorl %eax,%eax
1:      incl %eax               # check that A20 really IS enabled
        movl %eax,0x000000      # loop forever if it isn't
        cmpl %eax,0x100000
        je 1b

测试A20是否真的置位。前面在切换到保护模式之前,已经将A20引脚正式置位,不然每个物理地址第21位都会被cpu看作0.此时再验证。

        xorl %eax,%eax
        movl $_edata,%edi
        movl $_end,%ecx
        subl %edi,%ecx
        cld
        rep
        stosb

用0填充_edata和_end符号标识的内核未初始化数据区。在linux填充ram时分几个部分。符号_text对应于物理地址0x00100000,表示内核代码的第一个字节的地址。内核代码的结束位置由另外一个类似的符号_etext表示。内核数据分两组,初始化的数据和没初始化的数据。初始化的数据在_etext后开始,在_edata处结束。紧接着是未初始化的数据并以_end结束。这些符号在编译内核时产生,可以在system.map文件中找到这些符号的线性地址。

        subl $16,%esp   # place for structure on the stack
        movl %esp,%eax
        pushl %esi      # real mode pointer as second arg
        pushl %eax      # address of structure as first arg
        call decompress_kernel
        orl  %eax,%eax
        jnz  3f
        popl %esi       # discard address
        popl %esi       # real mode pointer
        xorl %ebx,%ebx
        ljmp $(__BOOT_CS), $0x100000

decompress_kernel是解压内核映像的。完成解压后内核被放在合适的位置,如果是低装载的在0x00100000,如果是高装载,则在这个压缩映像之后的临时缓冲区中,解压后的映像就被移动到从物理地址0x00100000开始的最终位置。
然后跳转到0x00100000.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值