Skip to content

Commit eef2109

Browse files
committed
Use segment-based addressing for DAP to support loading larger second stages
1 parent 96d2bdb commit eef2109

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

bios/boot_sector/src/dap.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,18 @@ pub struct DiskAddressPacket {
1818
}
1919

2020
impl DiskAddressPacket {
21-
pub fn from_lba(memory_buffer_start: u16, start_lba: u64, number_of_sectors: u16) -> Self {
21+
pub fn from_lba(
22+
start_lba: u64,
23+
number_of_sectors: u16,
24+
target_offset: u16,
25+
target_segment: u16,
26+
) -> Self {
2227
Self {
2328
packet_size: 0x10,
2429
zero: 0,
2530
number_of_sectors,
26-
offset: memory_buffer_start,
27-
segment: 0,
31+
offset: target_offset,
32+
segment: target_segment,
2833
start_lba,
2934
}
3035
}

bios/boot_sector/src/main.rs

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use core::{arch::global_asm, slice};
66
use error::NO_SECOND_STAGE_PARTITION;
7-
use fail::{fail, print_char, UnwrapOrFail};
7+
use fail::{print_char, UnwrapOrFail};
88

99
global_asm!(include_str!("boot.s"));
1010

@@ -14,15 +14,10 @@ mod fail;
1414
mod mbr;
1515

1616
extern "C" {
17-
static _mbr_start: u8;
1817
static _partition_table: u8;
1918
static _second_stage_start: u8;
2019
}
2120

22-
unsafe fn mbr_start() -> *const u8 {
23-
unsafe { &_mbr_start }
24-
}
25-
2621
unsafe fn partition_table_raw() -> *const u8 {
2722
unsafe { &_partition_table }
2823
}
@@ -38,34 +33,46 @@ pub extern "C" fn first_stage(disk_number: u16) {
3833
print_char(b'1');
3934
let partition_table = &unsafe { slice::from_raw_parts(partition_table_raw(), 16 * 4) };
4035
let second_stage_partition =
41-
mbr::boot_partition(partition_table).unwrap_or_fail(NO_SECOND_STAGE_PARTITION);
36+
// mbr::boot_partition(partition_table).unwrap_or_fail(NO_SECOND_STAGE_PARTITION);
37+
mbr::get_partition(partition_table, 0);
4238

4339
// load second stage partition into memory
4440
print_char(b'2');
45-
let target_addr = u16::try_from(second_stage_start() as usize).unwrap_or_fail(b'a');
46-
let dap = dap::DiskAddressPacket::from_lba(
47-
target_addr,
48-
second_stage_partition.logical_block_address.into(),
49-
second_stage_partition
50-
.sector_count
51-
.try_into()
52-
.unwrap_or_fail(b'b'),
53-
);
54-
unsafe {
55-
dap.perform_load(disk_number);
56-
}
57-
if second_stage_partition.sector_count == 0 {
58-
fail(b'c');
41+
let entry_point_address = second_stage_start() as u32;
42+
43+
let mut start_lba = second_stage_partition.logical_block_address.into();
44+
let mut number_of_sectors = second_stage_partition.sector_count;
45+
let mut target_addr = entry_point_address;
46+
47+
loop {
48+
let sectors = u32::min(number_of_sectors, 32) as u16;
49+
let dap = dap::DiskAddressPacket::from_lba(
50+
start_lba,
51+
sectors,
52+
(target_addr & 0b1111) as u16,
53+
(target_addr >> 4).try_into().unwrap_or_fail(b'a'),
54+
);
55+
unsafe {
56+
dap.perform_load(disk_number);
57+
}
58+
59+
start_lba += u64::from(sectors);
60+
number_of_sectors -= u32::from(sectors);
61+
target_addr = target_addr + u32::from(sectors) * 512;
62+
63+
if number_of_sectors == 0 {
64+
break;
65+
}
5966
}
6067

6168
// jump to second stage
6269
print_char(b'3');
6370
let second_stage_entry_point: extern "C" fn(
6471
disk_number: u16,
6572
partition_table_start: *const u8,
66-
) = unsafe { core::mem::transmute(target_addr as *const ()) };
67-
let mbr_start = unsafe { partition_table_raw() };
68-
second_stage_entry_point(disk_number, mbr_start);
73+
) = unsafe { core::mem::transmute(entry_point_address as *const ()) };
74+
let partition_table_start = unsafe { partition_table_raw() };
75+
second_stage_entry_point(disk_number, partition_table_start);
6976
for _ in 0..10 {
7077
print_char(b'R');
7178
}

0 commit comments

Comments
 (0)