From: acevest Date: Sat, 27 Dec 2025 13:08:05 +0000 (+0800) Subject: 未进入页映射的时候的代码还是用物理地址 X-Git-Url: http://repos.zhaoyanbai.com/?a=commitdiff_plain;h=862fb2af3b34956f557f3ee22bf79ed6e67e901e;p=kernel.git 未进入页映射的时候的代码还是用物理地址 --- diff --git a/.gitignore b/.gitignore index bd17c85..6b0ccfb 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ bochsout.txt *.lock *.DS_Store .vscode/settings.json +.vscode/* *.iso **/serial_monitor/serial_monitor **/mkrootfs/mkrootfs @@ -44,3 +45,4 @@ initrd initfs rootfs **/init + diff --git a/boot/boot.c b/boot/boot.c index b006e98..e4d5214 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -16,6 +16,8 @@ #include #include #include +#include + struct boot_params boot_params __attribute__((aligned(32))); @@ -244,6 +246,42 @@ extern void *kernel_begin; extern void *kernel_end; extern void *bootmem_bitmap_begin; + +#include + +__attribute__((section(".unpaged_text"))) +void test_unpaged_break() { + // printk("test unpaged break\n"); +} + + +void lapic_init() { + cpuid_regs_t r; + r = cpuid(1); + if(r.edx & (1 << 9)) { + printk("local apic supported\n"); + if(r.ecx & (1 << 21)) { + printk("x2apic supported\n"); + } else { + panic("x2apic not supported\n"); + } + } else { + panic("local apic not supported\n"); + } + + uint64_t apic_base = read_msr(MSR_IA32_APIC_BASE); + printk("apic base: %016lx\n", apic_base); + + // 开启2xapic + apic_base |= (1 << 10); + write_msr(MSR_IA32_APIC_BASE, apic_base); + + apic_base = read_msr(MSR_IA32_APIC_BASE); + printk("after 2xapic enable apic base: %016lx\n", apic_base); + + test_unpaged_break(); +} + void init_system_info() { system.kernel_begin = &kernel_begin; system.kernel_end = &kernel_end; @@ -257,4 +295,6 @@ void init_system_info() { printk("mem lower %uKB upper %uKB\n", boot_params.mem_lower >> 10, boot_params.mem_upper >> 10); boot_delay(DEFAULT_BOOT_DELAY_TICKS); + + lapic_init(); } diff --git a/boot/multiboot.S b/boot/multiboot.S index 0d43837..2e9f7e6 100644 --- a/boot/multiboot.S +++ b/boot/multiboot.S @@ -45,7 +45,7 @@ main: .align 4 real_kernel_entry: # Load GDT's Information To GDTR - lgdt GDTR-KRNLADDR + lgdt boot_gdtr movw $0x10, %dx movw %dx,%ds @@ -54,12 +54,21 @@ real_kernel_entry: movw %dx,%fs movw %dx,%gs - movl $(stack + MULTIBOOT_STACK_SIZE - KRNLADDR), %esp + + nop + nop + nop + nop + movl $(stack + MULTIBOOT_STACK_SIZE), %esp + #leal stack, %esp + #addl MULTIBOOT_STACK_SIZE, %esp # Reset EFLAGS pushl $0 popf + call test_unpaged_break + # Save Multiboot Infomation... pushl %eax addl $KRNLADDR,%ebx @@ -129,33 +138,38 @@ real_kernel_entry: jmp 4f 4: + # 准备切保护模式 + # 此时esp的地址还需要再调整一下 + addl $KRNLADDR, %esp + ljmp $0x08,$Label+KRNLADDR - ljmp $0x08,$Label Label: - call check_kernel - addl $8, %esp + leal check_kernel, %eax + call *%eax movl $root_task + TASK_SIZE, %esp - call init_system_info + leal init_system_info, %eax + call *%eax; - call setup_kernel + leal setup_kernel, %eax + call *%eax subl $128, %esp // ss esp eip - movl $root_task_entry, %eax + leal root_task_entry, %eax jmpl *%eax -Die: - jmp Die # Should never come to here. +die: + jmp die # Should never come to here. .align 32 -BootGDT: +boot_gdt: EMPT: .long 0x00000000, 0x00000000 Code: .long 0x0000FFFF, 0x00CF9B00 Data: .long 0x0000FFFF, 0x00CF9300 -BootGDTEnd: -GDTR: - GDTRLimit: .word BootGDTEnd-BootGDT - GDTRBase: .long BootGDT-KRNLADDR +boot_gdt_end: +boot_gdtr: + boot_gdtr_limit: .word boot_gdt_end-boot_gdt + boot_gdtr_base: .long boot_gdt .comm stack, MULTIBOOT_STACK_SIZE diff --git a/gdbscript b/gdbscript index c509829..e36ea99 100644 --- a/gdbscript +++ b/gdbscript @@ -1,6 +1,12 @@ # 避免退出gdb时二次确认 set confirm off +set architecture i386 + +#b *0x100000 +b multiboot.S:60 +b multiboot.S:136 + #b *0x7c00 # watch point diff --git a/include/cpuid.h b/include/cpuid.h new file mode 100644 index 0000000..522ad4c --- /dev/null +++ b/include/cpuid.h @@ -0,0 +1,18 @@ +/* + * ------------------------------------------------------------------------ + * File Name: include/cpuid.h + * Author: Zhao Yanbai + * 2025-12-27 16:13:55 Saturday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#pragma once + + +typedef struct cpuid_regs { + unsigned long eax, ebx, ecx, edx; +} cpuid_regs_t; + + +cpuid_regs_t cpuid(unsigned long op); diff --git a/include/msr.h b/include/msr.h index 7348d77..d312989 100644 --- a/include/msr.h +++ b/include/msr.h @@ -19,6 +19,10 @@ #include +#define MSR_IA32_APIC_BASE 0x1B + + + #define MSR_SYSENTER_CS 0x174 #define MSR_SYSENTER_ESP 0x175 #define MSR_SYSENTER_EIP 0x176 @@ -26,6 +30,10 @@ #define MSR_IA32_PERF_STATUS 0x198 #define MSR_IA32_PERF_CRTL 0x199 + +// 本地APIC的版本寄存器 +#define MSR_IA32_LOCAL_APIC_VERSION 0x803 + #define rdmsr(msr, lowval, highval) \ do { \ asm("rdmsr;" : "=a"(lowval), "=d"(highval) : "c"(msr)); \ diff --git a/kernel/cpuid.c b/kernel/cpuid.c index e64fc69..57e1874 100644 --- a/kernel/cpuid.c +++ b/kernel/cpuid.c @@ -16,24 +16,22 @@ #include #include #include +#include #define TEST_FEATURE(val, bit, fea) \ do { \ if (ISSET_BIT(val, bit)) printk(" %s", fea); \ } while (0); -typedef struct reg { - unsigned long eax, ebx, ecx, edx; -} reg_t; -reg_t cpuid(unsigned long op) { - reg_t r; +cpuid_regs_t cpuid(unsigned long op) { + cpuid_regs_t r; asm("cpuid;" : "=a"(r.eax), "=b"(r.ebx), "=c"(r.ecx), "=d"(r.edx) : "a"(op)); return r; } void detect_cpu() { - reg_t r; + cpuid_regs_t r; unsigned short int cpu_sn[6]; // serial number int i; @@ -72,6 +70,11 @@ void detect_cpu() { r = cpuid(1); pn = ((r.ebx & 0x00FF0000) >> 16); printk(" x %d Cores\n", pn); + if(((r.ecx >> 21) & 0x01) == 1) { + printk("x2APIC\n"); + } + printk("ECX %x\n", r.ecx); + printk("APIC ID: %x\n", (r.ebx >> 24) & 0xFF); /**********************Get the CPU's Feature***********************/ int fv = r.edx; diff --git a/qemu.sh b/qemu.sh index f1b5adf..d129fdd 100755 --- a/qemu.sh +++ b/qemu.sh @@ -20,6 +20,8 @@ set -m qemu-system-i386 \ -boot d \ -m 128 \ + -smp 2 \ + -cpu qemu32,+x2apic \ -serial tcp::6666,server,nowait \ -drive file=hd.img,format=raw,index=0,media=disk \ -drive file=kernel.iso,index=1,media=cdrom \ @@ -30,6 +32,10 @@ qemu-system-i386 \ -s -S \ & + + # -cpu qemu32,+apic \ + # -cpu qemu32,+x2apic \ + #-cpu core2duo-v1,+apic \ #-drive file=HDb.IMG,format=raw,index=2,media=disk \ #-cpu qemu32,+apic \ #-cpu core2duo-v1,+apic \ @@ -55,4 +61,3 @@ i386-elf-gdb KERNEL.ELF -x gdbscript kill -9 $pid echo "kill pid ${pid}" - diff --git a/scripts/link.ld b/scripts/link.ld index 0bf67e7..36e87a8 100644 --- a/scripts/link.ld +++ b/scripts/link.ld @@ -27,14 +27,30 @@ kernel_begin = kernel_virtual_addr_start + kernel_loaded_physic_addr; SECTIONS { - . = kernel_begin; - .text : AT(kernel_loaded_physic_addr) ALIGN(0x1000) + . = kernel_loaded_physic_addr; + .unpagged_text : { - code = .; *(.kernel_entry_text) *(.multiboot2_header) - /* 单独把 multiboot.S 的 .text 放在这个位置是为了便于调试,实际是可以不写这一句的 */ boot/multiboot.S.o(.text) + *(.unpaged_text) + } + eunpagged_text = .; + . = ALIGN(0x1000); + .unpaged_data : + { + boot/multiboot.S.o(COMMON) + *(.unpaged_data) + } + eunpagged_data = .; + + /* . = kernel_begin; */ + . += kernel_virtual_addr_start; + . = ALIGN(0x1000); + .text : AT(ADDR(.text)-kernel_virtual_addr_start) ALIGN(0x1000) + { + code = .; + /* 单独把 multiboot.S 的 .text 放在这个位置是为了便于调试,实际是可以不写这一句的 */ *(.text) *(.ring3.text); *(.sysexit) /* last */