慢慢欣赏linux x86 uImage实模式启动

24 篇文章 0 订阅
22 篇文章 1 订阅

header.S (c:\linux\linux-2.6.23\arch\i386\boot)    

//在X+0x9000+512的位置,也就是X+0x20:0x90000处的位置
    # offset 512, entry point

    .globl    _start
_start:
    =>.byte    0xeb        # short (2-byte) jump //跳转指令,跳转出hdr的第二部分
        .byte    start_of_setup-1f
        .... ...//part2 of hdr
    => //lretw长返回,堆栈的两个数分别赋值给CS:IP,也就是cs=ds, ip=setup2,因为bootloader跳转到内核实模式的时候,cs可能为X+0x20
start_of_setup:
    pushw    %ds
    pushw    $setup2
    lretw
    =>Force %es = %ds
setup2:
    movw    %ds, %ax
    movw    %ax, %es
    cld
    =>    //sp初始化,ss应该是X的位置
    andw    $~3, %sp    # dword align (might as well...)
    jnz    1f
    movw    $0xfffc, %sp    # Make sure we're not zero
1:    movzwl    %sp, %esp    # Clear upper half of %esp
    sti
    =>//检查setup.bin是否合法
    # Check signature at end of setup
    cmpl    $0x5a5aavoid main(void)//Main.c (c:\linux\linux-2.6.23\arch\i386\boot)
    =>copy_boot_params();
    =>validate_cpu()
    =>detect_memory()
        =>detect_memory_e820()
            =>int $0x15//获取内存情况
    =>go_to_protected_mode();
        =>realmode_switch_hook();
        =>enable_a20()
        =>reset_coprocessor();
        =>mask_all_interrupts();
        =>setup_idt();
        =>setup_gdt();
        =>protected_mode_jump(boot_params.hdr.code32_start,  (u32)&boot_params + (ds() << 4));a55, setup_sig
    jne    setup_bad
    =># Zero the bss
    movw    $__bss_start, %di
    movw    $_end+3, %cx
    xorl    %eax, %eax
    subw    %di, %cx
    shrw    $2, %cx
    rep; stosl
    =># Jump to C code (should not return)
    calll    main

-----------------------------------------------------------------------------------------------------

void main(void)//Main.c (c:\linux\linux-2.6.23\arch\i386\boot)
    =>copy_boot_params();
    =>validate_cpu()
    =>detect_memory()
        =>detect_memory_e820()
            =>int $0x15//获取内存情况
    =>go_to_protected_mode();
        =>realmode_switch_hook();
        =>enable_a20()
        =>reset_coprocessor();
        =>mask_all_interrupts();
        =>setup_idt();
            =>static const struct gdt_ptr null_idt = {0, 0};
            asm volatile("lidtl %0" : : "m" (null_idt));
        =>setup_gdt();
            =>static const u64 boot_gdt[] __attribute__((aligned(16))) = {
                /* CS: code, read/execute, 4 GB, base 0 */
                [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
                /* DS: data, read/write, 4 GB, base 0 */
                [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
            };
            =>static struct gdt_ptr gdt;

            gdt.len = sizeof(boot_gdt)-1;
            gdt.ptr = (u32)&boot_gdt + (ds() << 4);
            =>asm volatile("lgdtl %0" : : "m" (gdt));
        =>protected_mode_jump(boot_params.hdr.code32_start,  (u32)&boot_params + (ds() << 4));

---------------------------------------------------------------------------------------------------------------------

而对于保护模式的入口地址,定义如下:

code32_start:                # here loaders can put a different
                    # start address for 32-bit code.
#ifndef __BIG_KERNEL__
        .long    0x1000        #   0x1000 = default for zImage
#else
        .long    0x100000    # 0x100000 = default for big kernel
#endif

 

实模式代码main函数
https://blog.csdn.net/yunsongice/article/details/6110549

 

从开机到加载操作系统计算机究竟干了啥?
https://blog.csdn.net/xiaoyuaifuxiao/article/details/63711015

 

linux系统启动过程详解-开机加电后发生了什么 --linux内核剖析(零)
https://blog.csdn.net/gatieme/article/details/50914250

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值