Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
"clippy",
"--quiet",
"--message-format=json",
"--target=aarch64-unknown-none-softfloat",
"--target=riscv64imac-unknown-none-elf",
// "--target=aarch64-unknown-none-softfloat",
// "--target=riscv64imac-unknown-none-elf",
"--target=x86_64-unknown-none",
"--target=x86_64-unknown-uefi",
// "--target=x86_64-unknown-uefi",
],
"rust-analyzer.check.targets": [
"aarch64-unknown-none-softfloat",
"riscv64imac-unknown-none-elf",
// "aarch64-unknown-none-softfloat",
// "riscv64imac-unknown-none-elf",
"x86_64-unknown-none",
"x86_64-unknown-uefi",
// "x86_64-unknown-uefi",
]
}
34 changes: 32 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sbi-rt = "0.0.3"
[target.'cfg(target_arch = "x86_64")'.dependencies]
linux-boot-params = { version = "0.17", optional = true }
multiboot = { version = "0.8", optional = true }
pvh = { path = "../pvh", optional = true }
uart_16550 = "0.4"
x86_64 = { version = "0.15", default-features = false, features = ["instructions"] }

Expand All @@ -46,13 +47,15 @@ built = { version = "0.8", features = ["git2", "chrono"] }
# FIXME: When target-specific features exist, remove the workaround features.
# https://github.com/rust-lang/cargo/issues/1197
[features]
default = []
default = ["x86_64-pvh"]
elf = []
linux = []
multiboot = []
pvh = []
sbi = []
x86_64-linux = ["linux", "dep:linux-boot-params"]
x86_64-multiboot = ["multiboot", "dep:multiboot"]
x86_64-pvh = ["pvh", "dep:pvh"]

[profile.dev]
# This is a workaround for the loader growing too large to boot with QEMU's multiboot.
Expand Down
3 changes: 3 additions & 0 deletions src/arch/x86_64/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ cfg_if::cfg_if! {
} else if #[cfg(feature = "multiboot")] {
mod multiboot;
pub use self::multiboot::*;
} else if #[cfg(feature = "pvh")] {
mod pvh;
pub use self::pvh::*;
}
}
12 changes: 12 additions & 0 deletions src/arch/x86_64/platform/pvh/entry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![allow(bad_asm_style)]

core::arch::global_asm!(
include_str!("entry.s"),
rust_start = sym super::rust_start,
stack = sym crate::arch::x86_64::stack::STACK,
stack_top_offset = const crate::arch::x86_64::stack::Stack::top_offset(),
level_4_table = sym crate::arch::x86_64::page_tables::LEVEL_4_TABLE,
gdt_ptr = sym crate::arch::x86_64::gdt::GDT_PTR,
kernel_code_selector = const crate::arch::x86_64::gdt::Gdt::kernel_code_selector().0,
kernel_data_selector = const crate::arch::x86_64::gdt::Gdt::kernel_data_selector().0,
);
141 changes: 141 additions & 0 deletions src/arch/x86_64/platform/pvh/entry.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# This is the kernel's entry point. We could either call main here,
# or we can use this to setup the stack or other nice stuff, like
# perhaps setting up the GDT and segments. Please note that interrupts
# are disabled at this point: More on interrupts later!

.code32

.macro gotpcrel reg, sym
call 2f
2:
pop eax
3:
.att_syntax prefix
addl $_GLOBAL_OFFSET_TABLE_ + (3b - 2b), %eax
.intel_syntax noprefix
mov \reg, dword ptr [eax + \sym@GOT]
.endm

.section .text
.align 4
.global _start
_start:
mov edi, ebx
cli # avoid any interrupt

call 2f
2:
pop eax
3:
.att_syntax prefix
addl $_GLOBAL_OFFSET_TABLE_ + (3b - 2b), %eax
.intel_syntax noprefix
mov esp, dword ptr [eax + {stack}@GOT]


# Initialize stack pointer
add esp, {stack_top_offset}

# Move the 32-bit physical address of the Multiboot information structure into `RDI` as first argument to `rust_start`.
mov edi, ebx

# This will set up the x86 control registers:
# Caching and the floating point unit are enabled
# Bootstrap page tables are loaded and page size
# extensions (huge pages) enabled.
cpu_init:
# check for long mode

# do we have the instruction cpuid?
pushfd
pop eax
mov ecx, eax
xor eax, 1 << 21
push eax
popfd
pushfd
pop eax
push ecx
popfd
xor eax, ecx
jz Linvalid

# cpuid > 0x80000000?
mov eax, 0x80000000
cpuid
cmp eax, 0x80000001
jb Linvalid # It is less, there is no long mode.

# do we have a long mode?
mov eax, 0x80000001
cpuid
test edx, 1 << 29 # Test if the LM-bit, which is bit 29, is set in the D-register.
jz Linvalid # They aren't, there is no long mode.

# Set CR3
gotpcrel eax, {level_4_table}
mov cr3, eax

# we need to enable PAE modus
mov eax, cr4
or eax, 1 << 5
mov cr4, eax

# switch to the compatibility mode (which is part of long mode)
mov ecx, 0xC0000080
rdmsr
or eax, 1 << 8
wrmsr

# Set CR4
mov eax, cr4
and eax, 0xfffbf9ff # disable SSE
# or eax, (1 << 7) # enable PGE
mov cr4, eax

# Set CR0 (PM-bit is already set)
mov eax, cr0
and eax, ~(1 << 2) # disable FPU emulation
or eax, (1 << 1) # enable FPU montitoring
and eax, ~(1 << 30) # enable caching
and eax, ~(1 << 29) # disable write through caching
and eax, ~(1 << 16) # allow kernel write access to read-only pages
or eax, (1 << 31) # enable paging
mov cr0, eax

gotpcrel eax, {gdt_ptr}

lgdt [eax] # Load the 64-bit global descriptor table.

push {kernel_code_selector}
gotpcrel eax, start64
push eax
retf
# https://github.com/llvm/llvm-project/issues/46048
.att_syntax prefix
# Set the code segment and enter 64-bit long mode.
# ljmp ${kernel_code_selector}, $start64
.intel_syntax noprefix

# there is no long mode
Linvalid:
jmp Linvalid

.code64
start64:
# initialize segment registers
mov ax, {kernel_data_selector}
mov ds, eax
mov es, eax
mov ss, eax
xor ax, ax
mov fs, eax
mov gs, eax
cld
# set default stack pointer
mov rsp, [rip + {stack}@GOTPCREL]
add rsp, {stack_top_offset}

# jump to the boot processors's C code
jmp {rust_start}
jmp start64+0x28
Loading
Loading