mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
Fix and simplify SMP
This commit is contained in:
parent
2e9ffb84fa
commit
8d6663edb0
@ -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
|
||||
@ -137,3 +137,5 @@ gdt64:
|
||||
.pointer:
|
||||
dw $ - gdt64 - 1
|
||||
dq gdt64
|
||||
|
||||
top: equ start + 0x1000
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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 {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user