Now CPU1 can enter Rust. Change kernel guard page.

CPU1 is sharing page table with CPU0
master
WangRunji 7 years ago
parent 1e293763bc
commit 3e9ee46850

@ -1,4 +1,5 @@
global start global start
global stack_bottom
extern long_mode_start extern long_mode_start
section .text section .text
@ -158,7 +159,7 @@ p3_table:
p2_table: p2_table:
resb 4096 resb 4096
stack_bottom: stack_bottom:
resb 4096 * 4 resb 4096 * 8
stack_top: stack_top:
section .rodata section .rodata

@ -27,6 +27,8 @@
%define STA_R 0x2 ; Readable (executable segments) %define STA_R 0x2 ; Readable (executable segments)
%define STA_A 0x1 ; Accessed %define STA_A 0x1 ; Accessed
extern other_main
section .text section .text
bits 16 bits 16
start: start:
@ -42,12 +44,11 @@ start:
or eax, CR0_PE or eax, CR0_PE
mov cr0, eax mov cr0, eax
;PAGEBREAK! jmp gdt.code: start32
jmp gdt.kcode: start32
bits 32 bits 32
start32: start32:
mov ax, gdt.kdata mov ax, gdt.data
mov ds, ax mov ds, ax
mov es, ax mov es, ax
mov ss, ax mov ss, ax
@ -55,19 +56,17 @@ start32:
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
; debug
mov dword [0xb8000], 0x2f4b2f4f
hlt
; defer paging until we switch to 64bit mode
; set ebx=1 so shared boot code knows we're booting a secondary core
mov ebx, 1
; Switch to the stack allocated by startothers() ; Switch to the stack allocated by startothers()
mov esp, [start-4] mov esp, [start-4]
; Call mpenter()
call [start-8]
call enable_paging
; load the 64-bit GDT
lgdt [gdt64.pointer]
jmp gdt64.code: start64
error:
mov ax, 0x8a00 mov ax, 0x8a00
mov dx, ax mov dx, ax
out dx, ax out dx, ax
@ -76,18 +75,65 @@ start32:
spin: spin:
jmp spin jmp spin
enable_paging:
; load P4 to cr3 register (cpu uses this to access the P4 table)
mov eax, [start-8]
mov cr3, eax
; enable PAE-flag in cr4 (Physical Address Extension)
mov eax, cr4
or eax, 1 << 5
mov cr4, eax
; set the long mode bit in the EFER MSR (model specific register)
mov ecx, 0xC0000080
rdmsr
or eax, 1 << 8
wrmsr
; enable paging in the cr0 register
mov eax, cr0
or eax, 1 << 31
mov cr0, eax
ret
bits 64
start64:
; load 0 into all data segment registers
mov ax, 0
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; obtain kstack from data block before entryother
mov rsp, [0x7000 - 16]
mov rax, other_main
call rax
; section .rodata ; section .rodata
align 4 align 4
gdt: gdt:
; NULL ; NULL
dw 0, 0 dw 0, 0
db 0, 0, 0, 0 db 0, 0, 0, 0
.kcode: equ $ - gdt .code: equ $ - gdt
dw 0xffff, 0 dw 0xffff, 0
db 0, (0x90 | STA_X | STA_R), 0xcf, 0 db 0, (0x90 | STA_X | STA_R), 0xcf, 0
.kdata: equ $ - gdt .data: equ $ - gdt
dw 0xffff, 0 dw 0xffff, 0
db 0, (0x90 | STA_W), 0xcf, 0 db 0, (0x90 | STA_W), 0xcf, 0
.desc: .desc:
dw ($ - gdt - 1) dw $ - gdt - 1
dq gdt dq gdt
gdt64:
dq 0 ; zero entry
.code: equ $ - gdt64 ; new
dq (1<<43) | (1<<44) | (1<<47) | (1<<53) ; code segment
.pointer:
dw $ - gdt64 - 1
dq gdt64

@ -151,8 +151,6 @@ impl ActivePageTable {
} }
pub struct InactivePageTable { pub struct InactivePageTable {
// WARNING: Don't change the struct.
// memory mod use the private p4_frame.
p4_frame: Frame, p4_frame: Frame,
} }

@ -14,12 +14,14 @@ pub fn start_other_cores(acpi: &ACPI_Result, mc: &mut MemoryController) {
mc.map_page_identity(entryother_start as usize); mc.map_page_identity(entryother_start as usize);
mc.map_page_p2v(PhysicalAddress(0)); mc.map_page_p2v(PhysicalAddress(0));
copy_entryother(); copy_entryother();
let args = unsafe{ &mut *(ENTRYOTHER_ADDR as *mut EntryArgs).offset(-1) }; let args = unsafe{ &mut *(ENTRYOTHER_ADDR as *mut EntryArgs).offset(-1) };
let page_table = unsafe{ *(0xFFFF_FFFF_FFFF_FFF8 as *const u32) } & 0xFFFF_F000;
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];
*args = EntryArgs { *args = EntryArgs {
kstack: mc.alloc_stack(1).unwrap().top() as u64, kstack: mc.alloc_stack(1).unwrap().top() as u64,
next_code: 0, page_table: page_table,
stack: 0x8000, // just enough stack to get us to entry64mp stack: 0x8000, // just enough stack to get us to entry64mp
}; };
start_ap(apic_id, ENTRYOTHER_ADDR); start_ap(apic_id, ENTRYOTHER_ADDR);
@ -28,10 +30,6 @@ pub fn start_other_cores(acpi: &ACPI_Result, mc: &mut MemoryController) {
} }
fn hello_world() {
println!("Hello world!");
}
fn copy_entryother() { fn copy_entryother() {
use rlibc::memmove; use rlibc::memmove;
let entryother_start = entryother_start as usize; let entryother_start = entryother_start as usize;
@ -44,6 +42,6 @@ fn copy_entryother() {
#[repr(C)] #[repr(C)]
struct EntryArgs { struct EntryArgs {
kstack: u64, kstack: u64,
next_code: u32, page_table: u32,
stack: u32, stack: u32,
} }

@ -80,6 +80,15 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) {
test_end!(); test_end!();
} }
#[no_mangle]
pub extern "C" fn other_main() {
// print OK
unsafe{ *(0xb8000 as *mut u32) = 0x2f4b2f4f; }
loop {}
// FIXME: Page Fault
println!("Hello world! from AP!");
}
use linked_list_allocator::LockedHeap; use linked_list_allocator::LockedHeap;
#[global_allocator] #[global_allocator]

@ -132,15 +132,12 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
let old_table = active_table.switch(new_table); let old_table = active_table.switch(new_table);
println!("NEW TABLE!!!"); println!("NEW TABLE!!!");
// turn the old p4 page into a guard page // turn the stack bottom into a guard page
let old_table_p4_frame = unsafe { extern { fn stack_bottom(); }
&*(&old_table as *const InactivePageTable as *const Frame) let stack_bottom = PhysicalAddress(stack_bottom as u64).to_kernel_virtual();
}; let stack_bottom_page = Page::containing_address(stack_bottom);
let old_p4_page = Page::containing_address( active_table.unmap(stack_bottom_page, allocator);
old_table_p4_frame.start_address().to_kernel_virtual() println!("guard page at {:#x}", stack_bottom_page.start_address());
);
active_table.unmap(old_p4_page, allocator);
println!("guard page at {:#x}", old_p4_page.start_address());
active_table active_table
} }

Loading…
Cancel
Save