Add some long mode support
This commit is contained in:
@@ -1,19 +1,23 @@
|
||||
TARGET?=x86-unknown-none
|
||||
|
||||
ifeq ($(TARGET),x86-unknown-none)
|
||||
export LD=ld -m elf_i386
|
||||
export OBJCOPY=objcopy
|
||||
export PARTED=parted
|
||||
export QEMU=qemu-system-x86_64
|
||||
else
|
||||
$(error target $(TARGET) not supported by bootloader yet)
|
||||
endif
|
||||
|
||||
BUILD=build/$(TARGET)
|
||||
export RUST_TARGET_PATH=$(CURDIR)/targets
|
||||
|
||||
ifeq ($(TARGET),x86-unknown-none)
|
||||
|
||||
export LD=ld -m elf_i386
|
||||
export OBJCOPY=objcopy
|
||||
export PARTED=parted
|
||||
export QEMU=qemu-system-x86_64
|
||||
|
||||
all: $(BUILD)/bootloader.bin
|
||||
|
||||
else
|
||||
|
||||
all:
|
||||
$(error target $(TARGET) not supported by bootloader yet)
|
||||
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
|
||||
@@ -61,6 +65,7 @@ qemu: $(BUILD)/harddrive.bin
|
||||
$(QEMU) \
|
||||
-d cpu_reset \
|
||||
-d guest_errors \
|
||||
-no-reboot \
|
||||
-smp 4 -m 2048 \
|
||||
-chardev stdio,id=debug,signal=off,mux=on \
|
||||
-serial chardev:debug \
|
||||
|
||||
@@ -8,7 +8,7 @@ stage2:
|
||||
stage2.end:
|
||||
|
||||
stage3:
|
||||
%defstr STAGE3_STR %[STAGE3]
|
||||
incbin STAGE3_STR
|
||||
align 512, db 0
|
||||
%defstr STAGE3_STR %[STAGE3]
|
||||
incbin STAGE3_STR
|
||||
align 512, db 0
|
||||
.end:
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
attrib:
|
||||
.present equ 1 << 7
|
||||
.ring1 equ 1 << 5
|
||||
.ring2 equ 1 << 6
|
||||
.ring3 equ 1 << 5 | 1 << 6
|
||||
.user equ 1 << 4
|
||||
;user
|
||||
.code equ 1 << 3
|
||||
; code
|
||||
.conforming equ 1 << 2
|
||||
.readable equ 1 << 1
|
||||
; data
|
||||
.expand_down equ 1 << 2
|
||||
.writable equ 1 << 1
|
||||
.accessed equ 1 << 0
|
||||
;system
|
||||
; legacy
|
||||
.tssAvailabe16 equ 0x1
|
||||
.ldt equ 0x2
|
||||
.tssBusy16 equ 0x3
|
||||
.call16 equ 0x4
|
||||
.task equ 0x5
|
||||
.interrupt16 equ 0x6
|
||||
.trap16 equ 0x7
|
||||
.tssAvailabe32 equ 0x9
|
||||
.tssBusy32 equ 0xB
|
||||
.call32 equ 0xC
|
||||
.interrupt32 equ 0xE
|
||||
.trap32 equ 0xF
|
||||
; long mode
|
||||
.ldt32 equ 0x2
|
||||
.tssAvailabe64 equ 0x9
|
||||
.tssBusy64 equ 0xB
|
||||
.call64 equ 0xC
|
||||
.interrupt64 equ 0xE
|
||||
.trap64 equ 0xF
|
||||
|
||||
flags:
|
||||
.granularity equ 1 << 7
|
||||
.available equ 1 << 4
|
||||
;user
|
||||
.default_operand_size equ 1 << 6
|
||||
; code
|
||||
.long_mode equ 1 << 5
|
||||
; data
|
||||
.reserved equ 1 << 5
|
||||
@@ -0,0 +1,128 @@
|
||||
SECTION .text ; cannot use .data
|
||||
|
||||
struc GDTEntry
|
||||
.limitl resw 1
|
||||
.basel resw 1
|
||||
.basem resb 1
|
||||
.attribute resb 1
|
||||
.flags__limith resb 1
|
||||
.baseh resb 1
|
||||
endstruc
|
||||
|
||||
gdt_attr:
|
||||
.present equ 1 << 7
|
||||
.ring1 equ 1 << 5
|
||||
.ring2 equ 1 << 6
|
||||
.ring3 equ 1 << 5 | 1 << 6
|
||||
.user equ 1 << 4
|
||||
;user
|
||||
.code equ 1 << 3
|
||||
; code
|
||||
.conforming equ 1 << 2
|
||||
.readable equ 1 << 1
|
||||
; data
|
||||
.expand_down equ 1 << 2
|
||||
.writable equ 1 << 1
|
||||
.accessed equ 1 << 0
|
||||
;system
|
||||
; legacy
|
||||
.tssAvailabe16 equ 0x1
|
||||
.ldt equ 0x2
|
||||
.tssBusy16 equ 0x3
|
||||
.call16 equ 0x4
|
||||
.task equ 0x5
|
||||
.interrupt16 equ 0x6
|
||||
.trap16 equ 0x7
|
||||
.tssAvailabe32 equ 0x9
|
||||
.tssBusy32 equ 0xB
|
||||
.call32 equ 0xC
|
||||
.interrupt32 equ 0xE
|
||||
.trap32 equ 0xF
|
||||
; long mode
|
||||
.ldt32 equ 0x2
|
||||
.tssAvailabe64 equ 0x9
|
||||
.tssBusy64 equ 0xB
|
||||
.call64 equ 0xC
|
||||
.interrupt64 equ 0xE
|
||||
.trap64 equ 0xF
|
||||
|
||||
gdt_flag:
|
||||
.granularity equ 1 << 7
|
||||
.available equ 1 << 4
|
||||
;user
|
||||
.default_operand_size equ 1 << 6
|
||||
; code
|
||||
.long_mode equ 1 << 5
|
||||
; data
|
||||
.reserved equ 1 << 5
|
||||
|
||||
gdtr:
|
||||
dw gdt.end + 1 ; size
|
||||
dd gdt ; offset
|
||||
|
||||
gdt:
|
||||
.null equ $ - gdt
|
||||
dq 0
|
||||
|
||||
.lm64_code equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.code
|
||||
at GDTEntry.flags__limith, db gdt_flag.long_mode
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.lm64_data equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
; AMD System Programming Manual states that the writeable bit is ignored in long mode, but ss can not be set to this descriptor without it
|
||||
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.writable
|
||||
at GDTEntry.flags__limith, db 0
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.pm32_code equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.code | gdt_attr.readable
|
||||
at GDTEntry.flags__limith, db 0xF | gdt_flag.granularity | gdt_flag.default_operand_size
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.pm32_data equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.writable
|
||||
at GDTEntry.flags__limith, db 0xF | gdt_flag.granularity | gdt_flag.default_operand_size
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.pm16_code equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.code | gdt_attr.readable
|
||||
at GDTEntry.flags__limith, db 0xF
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.pm16_data equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.writable
|
||||
at GDTEntry.flags__limith, db 0xF
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.end equ $ - gdt
|
||||
@@ -1,8 +0,0 @@
|
||||
struc GDTEntry
|
||||
.limitl resw 1
|
||||
.basel resw 1
|
||||
.basem resb 1
|
||||
.attribute resb 1
|
||||
.flags__limith resb 1
|
||||
.baseh resb 1
|
||||
endstruc
|
||||
@@ -0,0 +1,56 @@
|
||||
SECTION .text
|
||||
USE32
|
||||
|
||||
long_mode:
|
||||
.func: dq 0
|
||||
.page_table: dd 0
|
||||
|
||||
.entry:
|
||||
; disable interrupts
|
||||
cli
|
||||
|
||||
;disable paging
|
||||
mov eax, cr0
|
||||
and eax, 0x7FFFFFFF
|
||||
mov cr0, eax
|
||||
|
||||
;cr3 holds pointer to PML4
|
||||
mov eax, [.page_table]
|
||||
mov cr3, eax
|
||||
|
||||
;enable OSXSAVE, FXSAVE/FXRSTOR, Page Global, Page Address Extension, and Page Size Extension
|
||||
mov eax, cr4
|
||||
or eax, 1 << 18 | 1 << 9 | 1 << 7 | 1 << 5 | 1 << 4
|
||||
mov cr4, eax
|
||||
|
||||
; load long mode GDT
|
||||
lgdt [gdtr]
|
||||
|
||||
; enable long mode
|
||||
mov ecx, 0xC0000080 ; Read from the EFER MSR.
|
||||
rdmsr
|
||||
or eax, 1 << 11 | 1 << 8 ; Set the Long-Mode-Enable and NXE bit.
|
||||
wrmsr
|
||||
|
||||
; enabling paging and protection simultaneously
|
||||
mov eax, cr0
|
||||
or eax, 1 << 31 | 1 << 16 | 1 ;Bit 31: Paging, Bit 16: write protect kernel, Bit 0: Protected Mode
|
||||
mov cr0, eax
|
||||
|
||||
; far jump to enable Long Mode and load CS with 64 bit segment
|
||||
jmp gdt.lm64_code:.inner
|
||||
|
||||
USE64
|
||||
|
||||
.inner:
|
||||
; load all the other segments with 64 bit data segments
|
||||
mov rax, gdt.lm64_data
|
||||
mov ds, rax
|
||||
mov es, rax
|
||||
mov fs, rax
|
||||
mov gs, rax
|
||||
mov ss, rax
|
||||
|
||||
; jump to specified function
|
||||
mov rax, [.func]
|
||||
jmp rax
|
||||
@@ -1,5 +1,6 @@
|
||||
SECTION .text
|
||||
USE16
|
||||
|
||||
;Generate a memory map at 0x500 to 0x5000 (available memory not used for kernel or bootloader)
|
||||
memory_map:
|
||||
.start equ 0x0500
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
SECTION .text
|
||||
USE16
|
||||
|
||||
; provide function for printing in x86 real mode
|
||||
|
||||
; print a string and a newline
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
SECTION .text
|
||||
USE16
|
||||
|
||||
protected_mode:
|
||||
|
||||
.func: dd 0
|
||||
|
||||
.entry:
|
||||
; disable interrupts
|
||||
cli
|
||||
|
||||
; load protected mode GDT
|
||||
lgdt [gdtr]
|
||||
|
||||
; set protected mode bit of cr0
|
||||
mov eax, cr0
|
||||
or eax, 1
|
||||
mov cr0, eax
|
||||
|
||||
; far jump to load CS with 32 bit segment
|
||||
jmp gdt.pm32_code:.inner
|
||||
|
||||
USE32
|
||||
|
||||
.inner:
|
||||
; load all the other segments with 32 bit data segments
|
||||
mov eax, gdt.pm32_data
|
||||
mov ds, eax
|
||||
mov es, eax
|
||||
mov fs, eax
|
||||
mov gs, eax
|
||||
mov ss, eax
|
||||
|
||||
; jump to specified function
|
||||
mov eax, [.func]
|
||||
jmp eax
|
||||
@@ -20,16 +20,8 @@ stage2.entry:
|
||||
shr ecx, 9
|
||||
call load_extent
|
||||
|
||||
; load protected mode GDT and IDT
|
||||
cli
|
||||
lgdt [gdtr]
|
||||
; set protected mode bit of cr0
|
||||
mov eax, cr0
|
||||
or eax, 1
|
||||
mov cr0, eax
|
||||
|
||||
; far jump to load CS with 32 bit segment
|
||||
jmp gdt.pm32_code:protected_mode
|
||||
mov dword [protected_mode.func], stage3.entry
|
||||
jmp protected_mode.entry
|
||||
|
||||
args:
|
||||
.stage3_base dq 0x100000
|
||||
@@ -108,22 +100,15 @@ load_extent:
|
||||
call print_line
|
||||
ret
|
||||
|
||||
%include "descriptor_flags.inc"
|
||||
%include "gdt_entry.inc"
|
||||
%include "gdt.asm"
|
||||
%include "memory_map.asm"
|
||||
%include "thunk.asm"
|
||||
%include "unreal.asm"
|
||||
%include "protected_mode.asm"
|
||||
%include "long_mode.asm"
|
||||
|
||||
USE32
|
||||
protected_mode:
|
||||
; load all the other segments with 32 bit data segments
|
||||
mov eax, gdt.pm32_data
|
||||
mov ds, eax
|
||||
mov es, eax
|
||||
mov fs, eax
|
||||
mov gs, eax
|
||||
mov ss, eax
|
||||
|
||||
stage3.entry:
|
||||
mov esp, 0x800000 - 128
|
||||
|
||||
; entry point
|
||||
@@ -144,53 +129,3 @@ protected_mode:
|
||||
cli
|
||||
hlt
|
||||
jmp .halt
|
||||
|
||||
gdtr:
|
||||
dw gdt.end + 1 ; size
|
||||
dd gdt ; offset
|
||||
|
||||
gdt:
|
||||
.null equ $ - gdt
|
||||
dq 0
|
||||
|
||||
.pm32_code equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.code | attrib.readable
|
||||
at GDTEntry.flags__limith, db 0xF | flags.granularity | flags.default_operand_size
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.pm32_data equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable
|
||||
at GDTEntry.flags__limith, db 0xF | flags.granularity | flags.default_operand_size
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.pm16_code equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.code | attrib.readable
|
||||
at GDTEntry.flags__limith, db 0xF
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.pm16_data equ $ - gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0
|
||||
at GDTEntry.basem, db 0
|
||||
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable
|
||||
at GDTEntry.flags__limith, db 0xF
|
||||
at GDTEntry.baseh, db 0
|
||||
iend
|
||||
|
||||
.end equ $ - gdt
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
SECTION .text
|
||||
USE32
|
||||
|
||||
thunk:
|
||||
.int10:
|
||||
mov dword [.func], .int10_real
|
||||
@@ -55,6 +57,7 @@ thunk:
|
||||
ret
|
||||
|
||||
USE16
|
||||
|
||||
.int10_real:
|
||||
int 0x10
|
||||
ret
|
||||
|
||||
@@ -5,7 +5,7 @@ USE16
|
||||
unreal:
|
||||
cli
|
||||
|
||||
lgdt [unreal_gdtr]
|
||||
lgdt [gdtr]
|
||||
|
||||
push es
|
||||
push ds
|
||||
@@ -22,7 +22,7 @@ unreal:
|
||||
; the switch back to real mode, these values are not modified, regardless of
|
||||
; what value is in the 16-bit segment register. So the 64k limit is no longer
|
||||
; valid and 32-bit offsets can be used with the real-mode addressing rules
|
||||
mov bx, unreal_gdt.data
|
||||
mov bx, gdt.pm32_data
|
||||
mov es, bx
|
||||
mov ds, bx
|
||||
|
||||
@@ -33,22 +33,3 @@ unreal:
|
||||
pop es
|
||||
sti
|
||||
ret
|
||||
|
||||
|
||||
unreal_gdtr:
|
||||
dw unreal_gdt.end + 1 ; size
|
||||
dd unreal_gdt ; offset
|
||||
|
||||
unreal_gdt:
|
||||
.null equ $ - unreal_gdt
|
||||
dq 0
|
||||
.data equ $ - unreal_gdt
|
||||
istruc GDTEntry
|
||||
at GDTEntry.limitl, dw 0xFFFF
|
||||
at GDTEntry.basel, dw 0x0
|
||||
at GDTEntry.basem, db 0x0
|
||||
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable
|
||||
at GDTEntry.flags__limith, db 0xF | flags.granularity | flags.default_operand_size
|
||||
at GDTEntry.baseh, db 0x0
|
||||
iend
|
||||
.end equ $ - unreal_gdt
|
||||
|
||||
+7
-1
@@ -24,6 +24,7 @@ use self::vga::{VgaTextBlock, VgaTextColor, Vga};
|
||||
|
||||
mod disk;
|
||||
mod logger;
|
||||
mod paging;
|
||||
mod panic;
|
||||
mod thunk;
|
||||
mod vbe;
|
||||
@@ -43,6 +44,8 @@ static ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||
|
||||
static mut VGA: Vga = unsafe { Vga::new(VGA_ADDR as *mut VgaTextBlock, 80, 25) };
|
||||
|
||||
static mut KERNEL_PHYS: u64 = 0;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn kstart(
|
||||
boot_disk: usize,
|
||||
@@ -77,7 +80,8 @@ pub unsafe extern "C" fn kstart(
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize allocator at the end of stage 3 with a meager 1 MiB
|
||||
// Initialize allocator at the end of stage 3 with a meager 1 MiB, which we can be pretty
|
||||
// sure will be available.
|
||||
extern "C" {
|
||||
static mut __end: u8;
|
||||
}
|
||||
@@ -119,6 +123,8 @@ pub unsafe extern "C" fn kstart(
|
||||
}
|
||||
}
|
||||
|
||||
//let page_phys = paging::paging_create(KERNEL_PHYS);
|
||||
|
||||
let mut modes = Vec::new();
|
||||
{
|
||||
// Get card info
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
use core::slice;
|
||||
|
||||
unsafe fn paging_allocate() -> Option<&'static mut [u64]> {
|
||||
let ptr = crate::ALLOCATOR.alloc_zeroed(
|
||||
Layout::from_size_align(4096, 4096).unwrap()
|
||||
);
|
||||
if ! ptr.is_null() {
|
||||
Some(slice::from_raw_parts_mut(
|
||||
ptr as *mut u64,
|
||||
512 // page size divided by u64 size
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn paging_create(kernel_phys: u64) -> Option<u64> {
|
||||
// Create PML4
|
||||
let pml4 = paging_allocate()?;
|
||||
|
||||
// Recursive mapping for compatibility
|
||||
pml4[511] = pml4.as_ptr() as u64 | 1 << 1 | 1;
|
||||
|
||||
{
|
||||
// Create PDP for identity mapping
|
||||
let pdp = paging_allocate()?;
|
||||
|
||||
// Link first user and first kernel PML4 entry to PDP
|
||||
pml4[0] = pdp.as_ptr() as u64 | 1 << 1 | 1;
|
||||
pml4[256] = pdp.as_ptr() as u64 | 1 << 1 | 1;
|
||||
|
||||
// Identity map 8 GiB pages
|
||||
for pdp_i in 0..8 {
|
||||
let pd = paging_allocate()?;
|
||||
pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1;
|
||||
for pd_i in 0..pd.len() {
|
||||
let pt = paging_allocate()?;
|
||||
pd[pd_i] = pt.as_ptr() as u64 | 1 << 1 | 1;
|
||||
for pt_i in 0..pt.len() {
|
||||
let addr =
|
||||
pdp_i as u64 * 0x4000_0000 +
|
||||
pd_i as u64 * 0x20_0000 +
|
||||
pt_i as u64 * 0x1000;
|
||||
pt[pt_i] = addr | 1 << 1 | 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Create PDP for kernel mapping
|
||||
let pdp = paging_allocate()?;
|
||||
|
||||
// Link second to last PML4 entry to PDP
|
||||
pml4[510] = pdp.as_ptr() as u64 | 1 << 1 | 1;
|
||||
|
||||
// Map 1 GiB at kernel offset
|
||||
for pdp_i in 0..1 {
|
||||
let pd = paging_allocate()?;
|
||||
pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1;
|
||||
for pd_i in 0..pd.len() {
|
||||
let pt = paging_allocate()?;
|
||||
pd[pd_i] = pt.as_ptr() as u64 | 1 << 1 | 1;
|
||||
for pt_i in 0..pt.len() {
|
||||
let addr =
|
||||
pdp_i as u64 * 0x4000_0000 +
|
||||
pd_i as u64 * 0x20_0000 +
|
||||
pt_i as u64 * 0x1000 +
|
||||
kernel_phys;
|
||||
pt[pt_i] = addr | 1 << 1 | 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(pml4.as_ptr() as u64)
|
||||
}
|
||||
+2
-2
@@ -11,7 +11,7 @@ pub extern "C" fn rust_eh_personality() {}
|
||||
#[panic_handler]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! {
|
||||
//println!("BOOTLOADER PANIC: {}", info);
|
||||
log::error!("BOOTLOADER PANIC: {}", info);
|
||||
loop {
|
||||
unsafe {
|
||||
llvm_asm!("hlt" : : : : "intel", "volatile");
|
||||
@@ -23,7 +23,7 @@ pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! {
|
||||
#[no_mangle]
|
||||
#[allow(improper_ctypes_definitions)] // Layout is not repr(C)
|
||||
pub extern fn rust_oom(_layout: Layout) -> ! {
|
||||
panic!("kernel memory allocation failed");
|
||||
panic!("memory allocation failed");
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
||||
Reference in New Issue
Block a user