diff --git a/src/arch/x86_64/boot/entryother.asm b/src/arch/x86_64/boot/entryother.asm index 9b8733b..9604de0 100644 --- a/src/arch/x86_64/boot/entryother.asm +++ b/src/arch/x86_64/boot/entryother.asm @@ -57,7 +57,7 @@ start32: mov gs, ax ; Switch to the stack allocated by startothers() - mov esp, [start-4] + mov esp, [top - 4] call enable_paging @@ -77,7 +77,7 @@ spin: enable_paging: ; load P4 to cr3 register (cpu uses this to access the P4 table) - mov eax, [start-8] + mov eax, [top - 8] mov cr3, eax ; enable PAE-flag in cr4 (Physical Address Extension) @@ -109,7 +109,7 @@ start64: mov gs, ax ; obtain kstack from data block before entryother - mov rsp, [0x7000 - 16] + mov rsp, [top - 16] mov rax, other_main call rax @@ -136,4 +136,6 @@ gdt64: dq (1<<43) | (1<<44) | (1<<47) | (1<<53) ; code segment .pointer: dw $ - gdt64 - 1 - dq gdt64 \ No newline at end of file + dq gdt64 + +top: equ start + 0x1000 \ No newline at end of file diff --git a/src/arch/x86_64/boot/linker.ld b/src/arch/x86_64/boot/linker.ld index f43f4ec..67be813 100644 --- a/src/arch/x86_64/boot/linker.ld +++ b/src/arch/x86_64/boot/linker.ld @@ -6,14 +6,29 @@ KERNEL_OFFSET = 0xffffff0000000000; SECTIONS { + /* ensure that the multiboot header is at the beginning */ + + .multiboot_header : + { + KEEP(*(.multiboot_header)) + } + + /* bootloader for other processors */ + + . = OTHER_OFFSET; + + .text.other : AT(OTHER_OFFSET) + { + KEEP(*/entryother.o (.text)) + . = ALIGN(4K); + } + /* bootloader for first processor */ . = BOOT_OFFSET; .rodata.32 : { - /* ensure that the multiboot header is at the beginning */ - KEEP(*(.multiboot_header)) */boot.o (.rodata) . = ALIGN(4K); } @@ -29,18 +44,6 @@ SECTIONS { . = ALIGN(4K); } - /* bootloader for other processors */ - - entryother_start = .; /* backup va */ - . = OTHER_OFFSET; - .text.other : AT(entryother_start) - { - KEEP(*/entryother.o (.text)) - . = ALIGN(4K); - } - entryother_end = . - OTHER_OFFSET + entryother_start; - . = entryother_end; /* recover va */ - /* kernel */ . += KERNEL_OFFSET; diff --git a/src/arch/x86_64/smp.rs b/src/arch/x86_64/smp.rs index 2bd15e0..bcd5b23 100644 --- a/src/arch/x86_64/smp.rs +++ b/src/arch/x86_64/smp.rs @@ -3,28 +3,21 @@ use memory::*; use core::ptr::{read_volatile, write_volatile}; use x86_64::registers::control_regs::cr3; -extern { - fn entryother_start(); // physical addr of entryother - fn entryother_end(); -} - const ENTRYOTHER_ADDR: u32 = 0x7000; pub fn start_other_cores(acpi: &AcpiResult, ms: &mut MemorySet) { use consts::KERNEL_OFFSET; - ms.push(MemoryArea::new_identity(ENTRYOTHER_ADDR as usize - 1, ENTRYOTHER_ADDR as usize + 1, MemoryAttr::default(), "entry_other")); - ms.push(MemoryArea::new_identity(entryother_start as usize, entryother_start as usize + 1, MemoryAttr::default(), "entry_other")); - ms.push(MemoryArea::new_kernel(KERNEL_OFFSET, KERNEL_OFFSET + 1, MemoryAttr::default(), "entry_other3")); - copy_entryother(); + ms.push(MemoryArea::new_identity(ENTRYOTHER_ADDR as usize, ENTRYOTHER_ADDR as usize + 1, MemoryAttr::default().execute(), "entry_other.text")); + ms.push(MemoryArea::new_kernel(KERNEL_OFFSET, KERNEL_OFFSET + 1, MemoryAttr::default(), "entry_other.ctrl")); - let args = unsafe{ &mut *(ENTRYOTHER_ADDR as *mut EntryArgs).offset(-1) }; + let args = unsafe { &mut *(0x8000 as *mut EntryArgs).offset(-1) }; for i in 1 .. acpi.cpu_num { let apic_id = acpi.cpu_acpi_ids[i as usize]; let ms = MemorySet::new(7); *args = EntryArgs { kstack: ms.kstack_top() as u64, - page_table: ms._page_table_addr().0 as u32, - stack: 0x8000, // just enough stack to get us to entry64mp + page_table: cr3().0 as u32, + stack: args as *const _ as u32, // just enough stack to get us to entry64mp }; unsafe { MS = Some(ms); } start_ap(apic_id, ENTRYOTHER_ADDR); @@ -32,16 +25,6 @@ pub fn start_other_cores(acpi: &AcpiResult, ms: &mut MemorySet) { } } -fn copy_entryother() { - use rlibc::memmove; - let entryother_start = entryother_start as usize; - let entryother_end = entryother_end as usize; - let size = entryother_end - entryother_start; - assert!(size <= 0x1000, "entryother code is too large, not supported."); - unsafe{ memmove(ENTRYOTHER_ADDR as *mut u8, entryother_start as *mut u8, size); } - debug!("smp: copied entryother code to 0x7000"); -} - #[repr(C)] #[derive(Debug)] struct EntryArgs { diff --git a/src/lib.rs b/src/lib.rs index f85dbb8..37a3ce2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,8 +84,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { kernel_memory.push(MemoryArea::new_identity(addr, addr + count * 0x1000, MemoryAttr::default(), "acpi")) }); - // FIXME: PageFault when SMP -// arch::smp::start_other_cores(&acpi, &mut kernel_memory); + arch::smp::start_other_cores(&acpi, &mut kernel_memory); process::init(kernel_memory); fs::load_sfs(); @@ -128,8 +127,9 @@ pub extern "C" fn other_main() -> ! { arch::idt::init(); arch::driver::apic::other_init(); let cpu_id = arch::driver::apic::lapic_id(); - println!("Hello world! from CPU {}!", arch::driver::apic::lapic_id()); let ms = unsafe { arch::smp::notify_started(cpu_id) }; + ms.switch(); + println!("Hello world! from CPU {}!", arch::driver::apic::lapic_id()); // unsafe{ let a = *(0xdeadbeaf as *const u8); } // Page fault loop {} }