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 stack_bottom
extern long_mode_start
section .text
@ -158,7 +159,7 @@ p3_table:
p2_table:
resb 4096
stack_bottom:
resb 4096 * 4
resb 4096 * 8
stack_top:
section .rodata

@ -27,67 +27,113 @@
%define STA_R 0x2 ; Readable (executable segments)
%define STA_A 0x1 ; Accessed
extern other_main
section .text
bits 16
start:
cli
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
lgdt [gdt.desc]
mov eax, cr0
or eax, CR0_PE
mov cr0, eax
lgdt [gdt.desc]
mov eax, cr0
or eax, CR0_PE
mov cr0, eax
;PAGEBREAK!
jmp gdt.kcode: start32
jmp gdt.code: start32
bits 32
start32:
mov ax, gdt.kdata
mov ds, ax
mov es, ax
mov ss, ax
mov ax, 0
mov fs, 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()
mov esp, [start-4]
; Call mpenter()
call [start-8]
mov ax, 0x8a00
mov dx, ax
out dx, ax
mov ax, 0x8ae0
out dx, ax
mov ax, gdt.data
mov ds, ax
mov es, ax
mov ss, ax
mov ax, 0
mov fs, ax
mov gs, ax
; Switch to the stack allocated by startothers()
mov esp, [start-4]
call enable_paging
; load the 64-bit GDT
lgdt [gdt64.pointer]
jmp gdt64.code: start64
error:
mov ax, 0x8a00
mov dx, ax
out dx, ax
mov ax, 0x8ae0
out dx, ax
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
align 4
gdt:
; NULL
dw 0, 0
db 0, 0, 0, 0
.kcode: equ $ - gdt
dw 0xffff, 0
db 0, (0x90 | STA_X | STA_R), 0xcf, 0
.kdata: equ $ - gdt
dw 0xffff, 0
db 0, (0x90 | STA_W), 0xcf, 0
; NULL
dw 0, 0
db 0, 0, 0, 0
.code: equ $ - gdt
dw 0xffff, 0
db 0, (0x90 | STA_X | STA_R), 0xcf, 0
.data: equ $ - gdt
dw 0xffff, 0
db 0, (0x90 | STA_W), 0xcf, 0
.desc:
dw ($ - gdt - 1)
dq gdt
dw $ - gdt - 1
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 {
// WARNING: Don't change the struct.
// memory mod use the private p4_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_p2v(PhysicalAddress(0));
copy_entryother();
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 {
let apic_id = acpi.cpu_acpi_ids[i as usize];
*args = EntryArgs {
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
};
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() {
use rlibc::memmove;
let entryother_start = entryother_start as usize;
@ -44,6 +42,6 @@ fn copy_entryother() {
#[repr(C)]
struct EntryArgs {
kstack: u64,
next_code: u32,
page_table: u32,
stack: u32,
}

@ -80,6 +80,15 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) {
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;
#[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);
println!("NEW TABLE!!!");
// turn the old p4 page into a guard page
let old_table_p4_frame = unsafe {
&*(&old_table as *const InactivePageTable as *const Frame)
};
let old_p4_page = Page::containing_address(
old_table_p4_frame.start_address().to_kernel_virtual()
);
active_table.unmap(old_p4_page, allocator);
println!("guard page at {:#x}", old_p4_page.start_address());
// turn the stack bottom into a guard page
extern { fn stack_bottom(); }
let stack_bottom = PhysicalAddress(stack_bottom as u64).to_kernel_virtual();
let stack_bottom_page = Page::containing_address(stack_bottom);
active_table.unmap(stack_bottom_page, allocator);
println!("guard page at {:#x}", stack_bottom_page.start_address());
active_table
}

Loading…
Cancel
Save