Skip to content

Commit

Permalink
Fixed "jc fail" instructions not working properly and updated README.…
Browse files Browse the repository at this point in the history
…md (#453)

* Fixed "jc fail" instructions not working properly and updated README.md

* Fixed stage 2 fail calls and removed additional asm label
  • Loading branch information
spencer3035 authored Aug 25, 2024
1 parent 96f58f2 commit ea3f61a
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 11 deletions.
8 changes: 4 additions & 4 deletions bios/boot_sector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
7 changes: 6 additions & 1 deletion bios/boot_sector/src/boot.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions bios/boot_sector/src/dap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions bios/boot_sector/src/mbr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
6 changes: 4 additions & 2 deletions bios/stage-2/src/dap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit ea3f61a

Please sign in to comment.