X86内核启动分析三 内核的实模式阶段

时间:2022-09-01 08:03:47
**header.S (c:\linux\linux-2.6.23\arch\i386\boot) //真正的入口是从第二个512字节开始的,bootloader(lilo/grub/uboot)会将控制权交给它
_start**
=>.byte 0xeb # short (2-byte) jump
.byte start_of_setup-1f //跳转到start_of_setup
=>
start_of_setup:
#ifdef SAFE_RESET_DISK_CONTROLLER
# Reset the disk controller.//复位硬盘控制器
movw $0x0000, %ax # Reset disk controller
movb $0x80, %dl # All disks
int $0x13
#endif
=># We will have entered with %cs = %ds+0x20, normalize %cs so
# it is on par with the other segments.
pushw %ds
pushw $setup2 //跳转到setup2
lretw
=>
setup2:
# Force %es = %ds
movw %ds, %ax
movw %ax, %es
cld
=>
andw $~3, %sp # dword align (might as well...) //对齐堆栈到16B或者32B
jnz 1f
movw $0xfffc, %sp # Make sure we're not zero
1: movzwl %sp, %esp # Clear upper half of %esp
sti
=>
# Check signature at end of setup //检查55AA
cmpl $0x5a5aaa55, 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



**machine_specific_memory_setup**
=>who = "BIOS-e820";
=>sanitize_e820_map(E820_MAP, &E820_MAP_NR);//去掉重叠的entry
=>
if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0)// Copy the BIOS e820 map into a safe place.
copy_e820_map
=>
do {//循环所有的entry,加入到map表里面
unsigned long long start = biosmap->addr;
unsigned long long size = biosmap->size;
unsigned long long end = start + size;
unsigned long type = biosmap->type;
add_memory_region(start, size, type);
} while (biosmap++,--nr_map);
if (ALT_MEM_K < EXT_MEM_K) {////如果e820不可获取,那么按照默认方式构建可用物理内存
mem_size = EXT_MEM_K;
who = "BIOS-88";
} else {
mem_size = ALT_MEM_K;
who = "BIOS-e801";
}
e820.nr_map = 0;
add_memory_region(0, LOWMEMSIZE(), E820_RAM);
add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);