WIP: convert to rust

This commit is contained in:
Jeremy Soller
2022-02-01 16:58:53 -07:00
parent c96eb83d18
commit ab2aaa9c38
29 changed files with 279 additions and 150 deletions
+9
View File
@@ -0,0 +1,9 @@
[build]
rustflags = [
# Kernel should preserve floating-point registers
"-Csoft-float",
]
[unstable]
build-std = ["core", "alloc", "compiler_builtins"]
build-std-features = ["panic-unwind"]
+2
View File
@@ -0,0 +1,2 @@
/build
/target
Generated
+7
View File
@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "redox_bootloader"
version = "0.1.0"
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "redox_bootloader"
version = "0.1.0"
edition = "2018"
[lib]
name = "bootloader"
path = "src/lib.rs"
crate-type = ["staticlib"]
[dependencies]
+51
View File
@@ -0,0 +1,51 @@
ARCH=x86
TARGET=$(ARCH)-unknown-none
export LD=ld -m elf_i386
export OBJCOPY=objcopy
export PARTED=parted
export QEMU=qemu-system-i386
export RUST_TARGET_PATH=$(CURDIR)/targets
all: build/bootloader.bin
clean:
rm -rf build
build/libbootloader.a: Cargo.lock Cargo.toml src/**
mkdir -p build
cargo rustc --lib --target $(TARGET) --release -- -C soft-float -C debuginfo=2 --emit link=$@
build/bootloader.elf: linkers/$(ARCH).ld build/libbootloader.a
mkdir -p build
$(LD) --gc-sections -z max-page-size=0x1000 -T $< -o $@ build/libbootloader.a && \
$(OBJCOPY) --only-keep-debug $@ $@.sym && \
$(OBJCOPY) --strip-debug $@
build/bootloader.bin: build/bootloader.elf $(ARCH)/**
mkdir -p build
nasm -f bin -o $@ -l $@.lst -D ARCH_$(ARCH) -D KERNEL=$< -i$(ARCH) $(ARCH)/disk.asm
build/harddrive.bin: build/bootloader.bin
mkdir -p build
rm -f $@.partial
fallocate -l 256MiB $@.partial
$(PARTED) -s -a minimal $@.partial mklabel msdos
$(PARTED) -s -a minimal $@.partial mkpart primary 1MiB 100%
dd if=$< of=$@.partial bs=1 count=446 conv=notrunc
dd if=$< of=$@.partial bs=512 skip=1 seek=1 conv=notrunc
mv $@.partial $@
qemu: build/harddrive.bin
$(QEMU) \
-d cpu_reset \
-d guest_errors \
-smp 4 -m 2048 \
-chardev stdio,id=debug,signal=off,mux=on \
-serial chardev:debug \
-mon chardev=debug \
-machine q35 \
-net none \
-enable-kvm \
-cpu host \
-drive file=$<,format=raw
+56
View File
@@ -0,0 +1,56 @@
ENTRY(kstart)
OUTPUT_FORMAT(elf32-i386)
SECTIONS {
. = 0x100000;
. += SIZEOF_HEADERS;
. = ALIGN(4096);
.text : {
__text_start = .;
*(.text*)
. = ALIGN(4096);
__text_end = .;
}
.rodata : {
__rodata_start = .;
*(.rodata*)
. = ALIGN(4096);
__rodata_end = .;
}
.data : {
__data_start = .;
*(.data*)
. = ALIGN(4096);
__data_end = .;
__bss_start = .;
*(.bss*)
. = ALIGN(4096);
__bss_end = .;
}
.tdata : {
__tdata_start = .;
*(.tdata*)
. = ALIGN(4096);
__tdata_end = .;
__tbss_start = .;
*(.tbss*)
. += 8;
. = ALIGN(4096);
__tbss_end = .;
}
__end = .;
/DISCARD/ : {
*(.comment*)
*(.eh_frame*)
*(.gcc_except_table*)
*(.note*)
*(.rel.eh_frame*)
}
}
+1
View File
@@ -0,0 +1 @@
nightly-2021-06-15
+10
View File
@@ -0,0 +1,10 @@
#![no_std]
#![feature(lang_items)]
#![feature(llvm_asm)]
mod panic;
#[no_mangle]
pub unsafe extern "C" fn kstart() -> ! {
loop {}
}
+38
View File
@@ -0,0 +1,38 @@
//! Intrinsics for panic handling
use core::alloc::Layout;
use core::panic::PanicInfo;
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}
/// Required to handle panics
#[panic_handler]
#[no_mangle]
pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! {
//println!("BOOTLOADER PANIC: {}", info);
loop {
unsafe {
llvm_asm!("hlt" : : : : "intel", "volatile");
}
}
}
#[lang = "oom"]
#[no_mangle]
#[allow(improper_ctypes_definitions)] // Layout is not repr(C)
pub extern fn rust_oom(_layout: Layout) -> ! {
panic!("kernel memory allocation failed");
}
#[allow(non_snake_case)]
#[no_mangle]
/// Required to handle panics
pub extern "C" fn _Unwind_Resume() -> ! {
loop {
unsafe {
llvm_asm!("hlt" : : : : "intel", "volatile");
}
}
}
+29
View File
@@ -0,0 +1,29 @@
{
"llvm-target": "i686-unknown-none",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
"arch": "x86",
"os": "none",
"env": "",
"vendor": "unknown",
"linker-flavor": "gcc",
"target-family": "redox",
"pre-link-args": {
"gcc": ["-m32", "-nostdlib", "-static"]
},
"features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
"dynamic-linking": false,
"executables": false,
"relocation-model": "pic",
"code-model": "kernel",
"disable-redzone": true,
"eliminate-frame-pointer": false,
"exe-suffix": "",
"has-rpath": false,
"no-compiler-rt": true,
"no-default-libraries": true,
"position-independent-executables": false,
"has-elf-tls": true
}
View File
View File
+2 -2
View File
@@ -3,8 +3,8 @@ sectalign off
%include "bootsector.asm"
startup_start:
%ifdef ARCH_i386
%include "startup-i386.asm"
%ifdef ARCH_x86
%include "startup-x86.asm"
%endif
%ifdef ARCH_x86_64
View File
+63
View File
@@ -0,0 +1,63 @@
%include "startup-common.asm"
startup_arch:
; 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.kernel_code:protected_mode
USE32
protected_mode:
; load all the other segments with 32 bit data segments
mov eax, gdt.kernel_data
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov esp, 0x800000 - 128
; entry point
mov eax, [args.kernel_base]
call [eax + 0x18]
.halt:
cli
hlt
jmp .halt
gdtr:
dw gdt.end + 1 ; size
dd gdt ; offset
gdt:
.null equ $ - gdt
dq 0
.kernel_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 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.kernel_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 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.end equ $ - gdt
View File
View File
-148
View File
@@ -1,148 +0,0 @@
%include "startup-common.asm"
startup_arch:
; load protected mode GDT and IDT
cli
lgdt [gdtr]
lidt [idtr]
; 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.kernel_code:protected_mode
USE32
protected_mode:
; load all the other segments with 32 bit data segments
mov eax, gdt.kernel_data
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov esp, 0x800000 - 128
mov eax, gdt.tss
ltr ax
;rust init
mov eax, [kernel_base + 0x18]
mov [interrupts.handler], eax
mov eax, gdtr
mov ebx, idtr
mov ecx, tss
int 255
.lp:
sti
hlt
jmp .lp
gdtr:
dw gdt.end + 1 ; size
dd gdt ; offset
gdt:
.null equ $ - gdt
dq 0
.kernel_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 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.kernel_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 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.user_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.ring3 | attrib.user | attrib.code | attrib.readable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.user_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.ring3 | attrib.user | attrib.writable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.user_tls 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.ring3 | attrib.user | attrib.writable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.tss equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw (tss.end - tss) & 0xFFFF
at GDTEntry.basel, dw (tss-$$+0x7C00) & 0xFFFF
at GDTEntry.basem, db ((tss-$$+0x7C00) >> 16) & 0xFF
at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.tssAvailabe32
at GDTEntry.flags__limith, db ((tss.end - tss) >> 16) & 0xF
at GDTEntry.baseh, db ((tss-$$+0x7C00) >> 24) & 0xFF
iend
.end equ $ - gdt
struc TSS
.prev_tss resd 1 ;The previous TSS - if we used hardware task switching this would form a linked list.
.esp0 resd 1 ;The stack pointer to load when we change to kernel mode.
.ss0 resd 1 ;The stack segment to load when we change to kernel mode.
.esp1 resd 1 ;everything below here is unused now..
.ss1 resd 1
.esp2 resd 1
.ss2 resd 1
.cr3 resd 1
.eip resd 1
.eflags resd 1
.eax resd 1
.ecx resd 1
.edx resd 1
.ebx resd 1
.esp resd 1
.ebp resd 1
.esi resd 1
.edi resd 1
.es resd 1
.cs resd 1
.ss resd 1
.ds resd 1
.fs resd 1
.gs resd 1
.ldt resd 1
.trap resw 1
.iomap_base resw 1
endstruc
tss:
istruc TSS
at TSS.esp0, dd 0x800000 - 128
at TSS.ss0, dd gdt.kernel_data
at TSS.iomap_base, dw 0xFFFF
iend
.end: