本文共 1663 字,大约阅读时间需要 5 分钟。
grub 在加载linux内核之前已经进入保护段式映射模式
/* The code segment of the protected mode. */#define CODE_SEGMENT 0x10 // 0b'000 10 000 => 01 => 2, 第2个段选择子/* The data segment of the protected mode. */#define DATA_SEGMENT 0x18 // 0b'000 11 000 => 11 => 3, 第3个段选择子.byte 0xea // 跳到linux内核VARIABLE(grub_relocator32_eip) .long 0 .word CODE_SEGMENT.byte 0xeaVARIABLE(grub_relocator32_eip) .long 0 .word CODE_SEGMENT /* GDT. Copied from loader/i386/linux.c. */ .p2align 4LOCAL(gdt): /* NULL. */ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 第0个描述符 /* Reserved. */ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 第1个描述符 /* Code segment. */ .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 // 第2个描述符 /* Data segment. */ .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 // 第3个描述符LOCAL(gdt_end):VARIABLE(grub_relocator32_end)
进入linux内核之后
#define GDT_ENTRY_KERNEL_DS 3#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8) .code32ENTRY(startup_32) cld /* * Test KEEP_SEGMENTS flag to see if the bootloader is asking * us to not reload segments */ testb $(1<<6), BP_loadflags(%esi) jnz 1f cli movl $(__KERNEL_DS), %eax movl %eax, %ds movl %eax, %es movl %eax, %ss ... .../* * Prepare for entering 64 bit mode */ /* Load new GDT with the 64bit segments using 32bit descriptor */ leal gdt(%ebp), %eax movl %eax, gdt+2(%ebp) lgdt gdt(%ebp)... ... .datagdt: .word gdt_end - gdt // 第0个描述符 .long gdt .word 0 .quad 0x0000000000000000 /* NULL descriptor */ // 第1个描述符 .quad 0x00af9a000000ffff /* __KERNEL_CS */ // 第2个描述符 .quad 0x00cf92000000ffff /* __KERNEL_DS */ // 第3个描述符 .quad 0x0080890000000000 /* TS descriptor */ .quad 0x0000000000000000 /* TS continued */gdt_end:
转载地址:http://bblji.baihongyu.com/