diff --git a/bios/boot_sector/README.md b/bios/boot_sector/README.md index 5c9cf4e6..a783d80e 100644 --- a/bios/boot_sector/README.md +++ b/bios/boot_sector/README.md @@ -4,13 +4,13 @@ This executable needs to fit into the 512-byte boot sector, so we need to use al ## Build Commands -1. `cargo build --release -Zbuild-std=core --target x86-16bit.json -Zbuild-std-features=compiler-builtins-mem` -2. `objcopy -I elf32-i386 -O binary target/x86-16bit/release/first_stage target/disk_image.bin +1. `cargo build --profile=stage-1 -Zbuild-std=core --target ../../i386-code16-boot-sector.json -Zbuild-std-features=compiler-builtins-mem` +2. `objcopy -I elf32-i386 -O binary ../../target/i386-code16-boot-sector/stage-1/bootloader-x86_64-bios-boot-sector ../../target/disk_image.img` To run in QEMU: -- `qemu-system-x86_64 -drive format=raw,file=target/disk_image.bin` +- `qemu-system-x86_64 -drive format=raw,file=../../target/disk_image.img` To print the contents of the ELF file, e.g. for trying to bring the size down: -- `objdump -xsdS -M i8086,intel target/x86-16bit/release/first_stage` +- `objdump -xsdS -M i8086,intel ../../target/i386-code16-boot-sector/stage-1/bootloader-x86_64-bios-boot-sector` diff --git a/bios/boot_sector/src/boot.s b/bios/boot_sector/src/boot.s index 992ce693..1544cac2 100644 --- a/bios/boot_sector/src/boot.s +++ b/bios/boot_sector/src/boot.s @@ -36,13 +36,18 @@ check_int13h_extensions: mov bx, 0x55aa # dl contains drive number int 0x13 - jc fail + jnc .int13_pass + call fail +.int13_pass: pop ax # pop error code again rust: # push arguments push dx # disk number call first_stage + # Fail code if first stage returns + push 'x' + call fail spin: hlt diff --git a/bios/boot_sector/src/dap.rs b/bios/boot_sector/src/dap.rs index da72b777..11e8a853 100644 --- a/bios/boot_sector/src/dap.rs +++ b/bios/boot_sector/src/dap.rs @@ -38,11 +38,13 @@ impl DiskAddressPacket { let self_addr = self as *const Self as u16; unsafe { asm!( - "push 0x7a", // error code `z`, passed to `fail` on error + "push 'z'", // error code `z`, passed to `fail` on error "mov {1:x}, si", // backup the `si` register, whose contents are required by LLVM "mov si, {0:x}", "int 0x13", - "jc fail", + "jnc 2f", // carry is set on fail + "call fail", + "2:", "pop si", // remove error code again "mov si, {1:x}", // restore the `si` register to its prior state in(reg) self_addr, diff --git a/bios/boot_sector/src/mbr.rs b/bios/boot_sector/src/mbr.rs index 1f7eed52..05382d28 100644 --- a/bios/boot_sector/src/mbr.rs +++ b/bios/boot_sector/src/mbr.rs @@ -16,14 +16,14 @@ pub(crate) fn get_partition(partitions_raw: &[u8], index: usize) -> PartitionTab .get(8..) .and_then(|s| s.get(..4)) .and_then(|s| s.try_into().ok()) - .unwrap_or_fail(b'e'), + .unwrap_or_fail(b'f'), ); let len = u32::from_le_bytes( buffer .get(12..) .and_then(|s| s.get(..4)) .and_then(|s| s.try_into().ok()) - .unwrap_or_fail(b'f'), + .unwrap_or_fail(b'g'), ); PartitionTableEntry::new(bootable, partition_type, lba, len) } diff --git a/bios/stage-2/src/dap.rs b/bios/stage-2/src/dap.rs index 00bd1268..f94b7fde 100644 --- a/bios/stage-2/src/dap.rs +++ b/bios/stage-2/src/dap.rs @@ -38,11 +38,13 @@ impl DiskAddressPacket { pub unsafe fn perform_load(&self, disk_number: u16) { let self_addr = self as *const Self as u16; asm!( - "push 0x7a", // error code `z`, passed to `fail` on error + "push 'z'", // error code `z`, passed to `fail` on error "mov {1:x}, si", "mov si, {0:x}", "int 0x13", - "jc fail", + "jnc 2f", // carry is set on fail + "call fail", + "2:", "pop si", // remove error code again "mov si, {1:x}", in(reg) self_addr,