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
|
mov gs, ax
|
||||||
|
|
||||||
; Switch to the stack allocated by startothers()
|
; Switch to the stack allocated by startothers()
|
||||||
mov esp, [start-4]
|
mov esp, [top - 4]
|
||||||
|
|
||||||
call enable_paging
|
call enable_paging
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ spin:
|
|||||||
|
|
||||||
enable_paging:
|
enable_paging:
|
||||||
; load P4 to cr3 register (cpu uses this to access the P4 table)
|
; load P4 to cr3 register (cpu uses this to access the P4 table)
|
||||||
mov eax, [start-8]
|
mov eax, [top - 8]
|
||||||
mov cr3, eax
|
mov cr3, eax
|
||||||
|
|
||||||
; enable PAE-flag in cr4 (Physical Address Extension)
|
; enable PAE-flag in cr4 (Physical Address Extension)
|
||||||
@ -109,7 +109,7 @@ start64:
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
; obtain kstack from data block before entryother
|
; obtain kstack from data block before entryother
|
||||||
mov rsp, [0x7000 - 16]
|
mov rsp, [top - 16]
|
||||||
|
|
||||||
mov rax, other_main
|
mov rax, other_main
|
||||||
call rax
|
call rax
|
||||||
@ -136,4 +136,6 @@ gdt64:
|
|||||||
dq (1<<43) | (1<<44) | (1<<47) | (1<<53) ; code segment
|
dq (1<<43) | (1<<44) | (1<<47) | (1<<53) ; code segment
|
||||||
.pointer:
|
.pointer:
|
||||||
dw $ - gdt64 - 1
|
dw $ - gdt64 - 1
|
||||||
dq gdt64
|
dq gdt64
|
||||||
|
|
||||||
|
top: equ start + 0x1000
|
@ -6,14 +6,29 @@ KERNEL_OFFSET = 0xffffff0000000000;
|
|||||||
|
|
||||||
SECTIONS {
|
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 */
|
/* bootloader for first processor */
|
||||||
|
|
||||||
. = BOOT_OFFSET;
|
. = BOOT_OFFSET;
|
||||||
|
|
||||||
.rodata.32 :
|
.rodata.32 :
|
||||||
{
|
{
|
||||||
/* ensure that the multiboot header is at the beginning */
|
|
||||||
KEEP(*(.multiboot_header))
|
|
||||||
*/boot.o (.rodata)
|
*/boot.o (.rodata)
|
||||||
. = ALIGN(4K);
|
. = ALIGN(4K);
|
||||||
}
|
}
|
||||||
@ -29,18 +44,6 @@ SECTIONS {
|
|||||||
. = ALIGN(4K);
|
. = 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 */
|
||||||
|
|
||||||
. += KERNEL_OFFSET;
|
. += KERNEL_OFFSET;
|
||||||
|
@ -3,28 +3,21 @@ use memory::*;
|
|||||||
use core::ptr::{read_volatile, write_volatile};
|
use core::ptr::{read_volatile, write_volatile};
|
||||||
use x86_64::registers::control_regs::cr3;
|
use x86_64::registers::control_regs::cr3;
|
||||||
|
|
||||||
extern {
|
|
||||||
fn entryother_start(); // physical addr of entryother
|
|
||||||
fn entryother_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const ENTRYOTHER_ADDR: u32 = 0x7000;
|
const ENTRYOTHER_ADDR: u32 = 0x7000;
|
||||||
|
|
||||||
pub fn start_other_cores(acpi: &AcpiResult, ms: &mut MemorySet) {
|
pub fn start_other_cores(acpi: &AcpiResult, ms: &mut MemorySet) {
|
||||||
use consts::KERNEL_OFFSET;
|
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_ADDR as usize, ENTRYOTHER_ADDR as usize + 1, MemoryAttr::default().execute(), "entry_other.text"));
|
||||||
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_other.ctrl"));
|
||||||
ms.push(MemoryArea::new_kernel(KERNEL_OFFSET, KERNEL_OFFSET + 1, MemoryAttr::default(), "entry_other3"));
|
|
||||||
copy_entryother();
|
|
||||||
|
|
||||||
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 {
|
for i in 1 .. acpi.cpu_num {
|
||||||
let apic_id = acpi.cpu_acpi_ids[i as usize];
|
let apic_id = acpi.cpu_acpi_ids[i as usize];
|
||||||
let ms = MemorySet::new(7);
|
let ms = MemorySet::new(7);
|
||||||
*args = EntryArgs {
|
*args = EntryArgs {
|
||||||
kstack: ms.kstack_top() as u64,
|
kstack: ms.kstack_top() as u64,
|
||||||
page_table: ms._page_table_addr().0 as u32,
|
page_table: cr3().0 as u32,
|
||||||
stack: 0x8000, // just enough stack to get us to entry64mp
|
stack: args as *const _ as u32, // just enough stack to get us to entry64mp
|
||||||
};
|
};
|
||||||
unsafe { MS = Some(ms); }
|
unsafe { MS = Some(ms); }
|
||||||
start_ap(apic_id, ENTRYOTHER_ADDR);
|
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)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct EntryArgs {
|
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"))
|
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);
|
process::init(kernel_memory);
|
||||||
|
|
||||||
fs::load_sfs();
|
fs::load_sfs();
|
||||||
@ -128,8 +127,9 @@ pub extern "C" fn other_main() -> ! {
|
|||||||
arch::idt::init();
|
arch::idt::init();
|
||||||
arch::driver::apic::other_init();
|
arch::driver::apic::other_init();
|
||||||
let cpu_id = arch::driver::apic::lapic_id();
|
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) };
|
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
|
// unsafe{ let a = *(0xdeadbeaf as *const u8); } // Page fault
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user