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