Skip to content

Commit aa568b0

Browse files
committed
Update lib.rs
1 parent 417ec7f commit aa568b0

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

crates/dust_codegen/src/lib.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,9 @@ fn build_object_for_triple_with_config(
919919

920920
let mut module = ObjectModule::new(builder);
921921
let ptr_ty = module.target_config().pointer_type();
922+
let emit_kernel_handoff = emit_strings
923+
.iter()
924+
.any(|s| s == "xdv-boot: handoff to kernel.bin");
922925

923926
// For bare-metal, we don't declare puts - kernel handles output differently
924927
let puts_func = if config.mode == BuildMode::BareMetal {
@@ -1028,6 +1031,9 @@ fn build_object_for_triple_with_config(
10281031
break;
10291032
}
10301033
}
1034+
if emit_kernel_handoff {
1035+
emit_boot_kernel_handoff_call(&mut b, ptr_ty)?;
1036+
}
10311037
}
10321038

10331039
let zero = b.ins().iconst(cranelift_codegen::ir::types::I32, 0);
@@ -1047,6 +1053,33 @@ fn build_object_for_triple_with_config(
10471053
Ok(obj.write().context("emit object")?)
10481054
}
10491055

1056+
/// In boot.bin mode, transfer control to preloaded kernel image.
1057+
/// Reads entry offset from boot record (0x0600 + 44), adds kernel image base
1058+
/// (0x00020000), and performs an indirect call.
1059+
fn emit_boot_kernel_handoff_call(
1060+
b: &mut FunctionBuilder<'_>,
1061+
ptr_ty: cranelift_codegen::ir::Type,
1062+
) -> Result<()> {
1063+
let bootrec_kernel_entry_ptr = b.ins().iconst(ptr_ty, i64::from(0x0600 + 44));
1064+
let kernel_entry_off_i32 = b.ins().load(
1065+
cranelift_codegen::ir::types::I32,
1066+
cranelift_codegen::ir::MemFlags::new(),
1067+
bootrec_kernel_entry_ptr,
1068+
0,
1069+
);
1070+
let kernel_entry_off_ptr = b.ins().uextend(ptr_ty, kernel_entry_off_i32);
1071+
let kernel_image_base = b.ins().iconst(ptr_ty, 0x0002_0000);
1072+
let kernel_entry_addr = b.ins().iadd(kernel_image_base, kernel_entry_off_ptr);
1073+
1074+
let mut kernel_sig = Signature::new(b.func.signature.call_conv);
1075+
kernel_sig
1076+
.returns
1077+
.push(AbiParam::new(cranelift_codegen::ir::types::I32));
1078+
let kernel_sig_ref = b.import_signature(kernel_sig);
1079+
b.ins().call_indirect(kernel_sig_ref, kernel_entry_addr, &[]);
1080+
Ok(())
1081+
}
1082+
10501083
/// Kernel sector window reserved by xdv-os boot stage (128 * 512 bytes).
10511084
const KERNEL_MAX_BYTES: usize = 128 * 512;
10521085
/// VGA text mode base physical address.

0 commit comments

Comments
 (0)