X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/fedfd71f5492177a7c7d7fd2bd1529a832106395..48b4a227035048fdebcd32532deb7a857c6199ac:/lunaix-os/arch/x86/boot.S diff --git a/lunaix-os/arch/x86/boot.S b/lunaix-os/arch/x86/boot.S index 1eddb52..9c86bbc 100644 --- a/lunaix-os/arch/x86/boot.S +++ b/lunaix-os/arch/x86/boot.S @@ -1,55 +1,89 @@ -#include "multiboot.h" +#define __ASM__ 1 +#include + +#define MB_FLAGS MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN +#define KPG_SIZE 10*4096 .section .multiboot - .long MB_MAGIC - .long MB_ALIGNED_4K_MEM_MAP - .long CHECKSUM(MB_ALIGNED_4K_MEM_MAP) + .long MULTIBOOT_MAGIC + .long MB_FLAGS + .long CHECKSUM(MB_FLAGS) .section .bss - /* According to System V ABI, the stack must be aligned at 16 bytes boundary */ + .global mb_info .align 16 + /* 为Multiboot info struct 预留空间 */ + mb_info: + .skip 4096 + /* 根据System V ABI,栈地址必须16字节对齐 */ + /* 这里只是一个临时栈,在_hhk_init里面我们会初始化内核专用栈 */ stack_bottom: - .skip 16318, 0 + .skip 16318 * 2, 0 stack_top: -.section .text + +/* + 1 page directory, + 9 page tables: + 1. Mapping reserved area and hhk_init + 2-9. Remapping the kernels +*/ + +.section .kpg + .global _k_ptd + _k_ptd: + .skip KPG_SIZE, 0 + + +.section .hhk_init .global start_ .type start_, @function /* Optional, this just give the * linker more knowledge about the label */ - start_: + start_: + cld + # 确保屏蔽所有外中断,直到我们准备好PIC为止 + cli movl $stack_top, %esp + + subl $16, %esp + /* - TODO: kernel init - 1. Load GDT - 2. Load IDT - 3. Enable paging + 将咱们的 multiboot_info 挪个地儿,就是上述预留的空间里 + 而后在_hhk_init里,我们会对所有的高半核初始化代码(arch/x86下的所有)进行Identity map + 这样,我们能够保证当分页与虚拟地址开启后,我们的内核能够访问到multiboot info table + */ + + movl $mb_info, 4(%esp) + movl %ebx, (%esp) + call _save_multiboot_info + + /* + _hhk_init用来初始化我们高半核: + 1. 初始化最简单的PD与PT(重新映射我们的内核至3GiB处,以及对相应的地方进行Identity Map) */ - call _kernel_init - - subl $0x6, %esp - movl $_gdt, 2(%esp) - movw _gdt_limit, %ax - movw %ax, (%esp) - lgdt (%esp) - addl $0x6, %esp - - movw $0x10, %cx - movw %cx, %es - movw %cx, %ds - movw %cx, %fs - movw %cx, %gs - movw %cx, %ss - - pushw $0x08 - pushl $_after_gdt - retf - - _after_gdt: - pushl %ebx - call _kernel_main - cli - j_: - hlt - jmp j_ \ No newline at end of file + movl $(KPG_SIZE), 4(%esp) + movl $(_k_ptd - 0xC0000000), (%esp) /* PTD物理地址 */ + call _hhk_init + + /* + 基本的映射定义好了,我们可以放心的打开分页了 + 我们只需要把PTD的基地址加载进CR3就好了。 + */ + + /* 加载PTD基地址(物理地址) */ + movl (%esp), %eax + andl $0xfffff000, %eax # 有点多余,但写上还算明白一点 + movl %eax, %cr3 + + /* 开启分页与地址转换 (CR0.PG=1, PG.WP=1) */ + movl %cr0, %eax + orl $0x80010000, %eax + movl %eax, %cr0 + + addl $16, %esp + + /* 进入高半核! */ + pushl $hhk_entry_ + ret \ No newline at end of file