mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 14:27:49 +00:00
Pass multiboot pointer as argument to rust_main
This commit is contained in:
@@ -8,6 +8,25 @@ TODO
|
||||
## The Multiboot Information Structure
|
||||
When a Multiboot compliant bootloader loads a kernel, it passes a pointer to a boot information structure in the `ebx` register. We can use it to get information about available memory and loaded kernel sections.
|
||||
|
||||
First, we need to pass this pointer to our kernel as an argument to `rust_main`. To find out how arguments are passed to functions, we can look at the [calling convention of Linux]:
|
||||
|
||||
[calling convention of Linux]: https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI
|
||||
|
||||
> The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, and R9
|
||||
|
||||
So to pass the pointer to our kernel, we need to move it to `rdi` before calling the kernel. Since we're not using the `rdi`/`edi` register in our bootstrap code right now, we can simply set the `edi` register right after booting (in `boot.asm`):
|
||||
|
||||
```nasm
|
||||
start:
|
||||
mov esp, stack_top
|
||||
mov edi, ebx ; Move Multiboot info pointer to edi
|
||||
```
|
||||
Now we can add the argument to our `rust_main`:
|
||||
|
||||
```rust
|
||||
pub extern fn rust_main(multiboot_information_address: usize) { ... }
|
||||
```
|
||||
|
||||
## Start and End of Kernel
|
||||
We can now use the ELF section tag to calculate the start and end address of our loaded kernel:
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ section .text
|
||||
bits 32
|
||||
start:
|
||||
mov esp, stack_top
|
||||
; Move Multiboot info pointer to edi to pass it to the kernel. We must not
|
||||
; modify the `edi` register until the kernel it called.
|
||||
mov edi, ebx
|
||||
|
||||
call test_multiboot
|
||||
call test_cpuid
|
||||
|
||||
@@ -20,7 +20,7 @@ bits 64
|
||||
long_mode_start:
|
||||
call setup_SSE
|
||||
|
||||
; call rust main
|
||||
; call rust main (with multiboot pointer in rdi)
|
||||
call rust_main
|
||||
.os_returned:
|
||||
; rust main returned, print `OS returned!`
|
||||
|
||||
@@ -23,7 +23,7 @@ extern crate spin;
|
||||
mod vga_buffer;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn rust_main() {
|
||||
pub extern fn rust_main(multiboot_information_address: usize) {
|
||||
// ATTENTION: we have a very small stack and no guard page
|
||||
vga_buffer::clear_screen();
|
||||
println!("Hello World{}", "!");
|
||||
|
||||
Reference in New Issue
Block a user