Skip to content

Commit ee71376

Browse files
36: convert stage_4 of bootloader to rust r=phil-opp a=acheronfail I've been playing around trying to convert some assembly to Rust in this repository, and I've (almost) managed to convert `stage_4` to a Rust function. The only thing that I can't figure out, is how to calculate the `memory_map_entry_count` argument? I've tried various things and maybe I don't understand something here. 🤔 IIUC `memory_map_entry_count` is defined here in `stage_4.s`: ```asm movzx rcx, word ptr mmap_ent ; If I understand correctly, the `movzx` instruction above is equivalent to: ; xor rcx, rcx ; mov cx, word ptr mmap_ent ``` But, I've even tried changing that completely (to things like `mov rcx, 0x0`) and the result is always `6` when `load_elf` is called, so I'm really quite confused. In any case, I'm putting this PR up to see if you can help me understand that part above, and to try and remove more assembly in favour of more Rust. 😄 Co-authored-by: acheronfail <[email protected]>
2 parents 2674dd2 + cc911c3 commit ee71376

File tree

2 files changed

+38
-26
lines changed

2 files changed

+38
-26
lines changed

src/main.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ global_asm!(include_str!("stage_1.s"));
3030
global_asm!(include_str!("stage_2.s"));
3131
global_asm!(include_str!("e820.s"));
3232
global_asm!(include_str!("stage_3.s"));
33-
global_asm!(include_str!("stage_4.s"));
3433
global_asm!(include_str!("context_switch.s"));
3534

3635
#[cfg(feature = "vga_320x200")]
@@ -63,8 +62,45 @@ impl IdentityMappedAddr {
6362
}
6463
}
6564

65+
// Symbols defined in `linker.ld`
66+
extern {
67+
static mmap_ent: usize;
68+
static _memory_map: usize;
69+
static _kib_kernel_size: usize;
70+
static __page_table_start: usize;
71+
static __page_table_end: usize;
72+
static __bootloader_end: usize;
73+
static __bootloader_start: usize;
74+
}
75+
6676
#[no_mangle]
67-
pub extern "C" fn load_elf(
77+
pub unsafe extern "C" fn stage_4() -> ! {
78+
// Set stack segment
79+
asm!("mov bx, 0x0
80+
mov ss, bx" ::: "bx" : "intel");
81+
82+
let kernel_start = 0x400000;
83+
let kernel_size = _kib_kernel_size as u64;
84+
let memory_map_addr = &_memory_map as *const _ as u64;
85+
let memory_map_entry_count = (mmap_ent & 0xff) as u64; // Extract lower 8 bits
86+
let page_table_start = &__page_table_start as *const _ as u64;
87+
let page_table_end = &__page_table_end as *const _ as u64;
88+
let bootloader_start = &__bootloader_start as *const _ as u64;
89+
let bootloader_end = &__bootloader_end as *const _ as u64;
90+
91+
load_elf(
92+
IdentityMappedAddr(PhysAddr::new(kernel_start)),
93+
kernel_size,
94+
VirtAddr::new(memory_map_addr),
95+
memory_map_entry_count,
96+
PhysAddr::new(page_table_start),
97+
PhysAddr::new(page_table_end),
98+
PhysAddr::new(bootloader_start),
99+
PhysAddr::new(bootloader_end),
100+
)
101+
}
102+
103+
fn load_elf(
68104
kernel_start: IdentityMappedAddr,
69105
kernel_size: u64,
70106
memory_map_addr: VirtAddr,

src/stage_4.s

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)