Skip to content

Commit 3b6aa00

Browse files
committed
WIP: try to start loading FAT partition in second stage
1 parent 13c4d5e commit 3b6aa00

File tree

17 files changed

+1587
-235
lines changed

17 files changed

+1587
-235
lines changed

Cargo.lock

Lines changed: 24 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bios/boot_sector/src/main.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@ mod fail;
1414
mod mbr;
1515

1616
extern "C" {
17+
static _mbr_start: u8;
1718
static _partition_table: u8;
1819
static _second_stage_start: u8;
1920
}
2021

21-
unsafe fn partition_table() -> *const u8 {
22+
unsafe fn mbr_start() -> *const u8 {
23+
unsafe { &_mbr_start }
24+
}
25+
26+
unsafe fn partition_table_raw() -> *const u8 {
2227
unsafe { &_partition_table }
2328
}
2429

@@ -31,7 +36,7 @@ fn second_stage_start() -> *const () {
3136
pub extern "C" fn first_stage(disk_number: u16) {
3237
// read partition table and look for second stage partition
3338
print_char(b'1');
34-
let partition_table = &unsafe { slice::from_raw_parts(partition_table(), 16 * 4) };
39+
let partition_table = &unsafe { slice::from_raw_parts(partition_table_raw(), 16 * 4) };
3540
let second_stage_partition =
3641
mbr::boot_partition(partition_table).unwrap_or_fail(NO_SECOND_STAGE_PARTITION);
3742

@@ -55,9 +60,12 @@ pub extern "C" fn first_stage(disk_number: u16) {
5560

5661
// jump to second stage
5762
print_char(b'3');
58-
let second_stage_entry_point: extern "C" fn(disk_number: u16) =
59-
unsafe { core::mem::transmute(target_addr as *const ()) };
60-
second_stage_entry_point(disk_number);
63+
let second_stage_entry_point: extern "C" fn(
64+
disk_number: u16,
65+
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);
6169
for _ in 0..10 {
6270
print_char(b'R');
6371
}

bios/second_stage/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ edition = "2021"
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10+
fatfs = { git = "https://github.com/rafalh/rust-fatfs.git", default-features = false }
11+
mbr-nostd = "0.1.0"
12+
byteorder = { version = "1.4.3", default-features = false }

bios/second_stage/build.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use std::path::Path;
2+
3+
fn main() {
4+
let local_path = Path::new(env!("CARGO_MANIFEST_DIR"));
5+
println!(
6+
"cargo:rustc-link-arg-bins=--script={}",
7+
local_path.join("second-stage-link.ld").display()
8+
)
9+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
ENTRY(_start)
2+
3+
SECTIONS {
4+
. = 0x7c00 + 512;
5+
6+
.start : {
7+
*(.start)
8+
}
9+
.rodata : {
10+
*(.rodata .rodata.*)
11+
}
12+
.text : {
13+
*(.text .text.*)
14+
}
15+
16+
. = ALIGN(512);
17+
18+
_second_stage_end = .;
19+
}

bios/second_stage/src/dap.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use core::arch::{asm, global_asm};
22

3+
#[derive(Debug, Clone, Copy)]
34
#[repr(packed)]
45
pub struct DiskAddressPacket {
56
/// Size of the DAP structure

bios/second_stage/src/disk.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use crate::{dap, screen, second_stage_end};
2+
use core::{fmt::Write as _, slice};
3+
4+
pub struct DiskAccess {
5+
pub disk_number: u16,
6+
pub base_offset: u64,
7+
pub current_offset: u64,
8+
}
9+
10+
impl fatfs::IoBase for DiskAccess {
11+
type Error = ();
12+
}
13+
14+
impl fatfs::Read for DiskAccess {
15+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
16+
writeln!(screen::Writer, "read {} bytes", buf.len()).unwrap();
17+
18+
let end_addr = self.base_offset + self.current_offset + u64::try_from(buf.len()).unwrap();
19+
let start_lba = (self.base_offset + self.current_offset) / 512;
20+
let end_lba = (end_addr - 1) / 512;
21+
22+
let target_addr = u16::try_from(second_stage_end() as usize).unwrap();
23+
let dap = dap::DiskAddressPacket::from_lba(
24+
target_addr,
25+
start_lba,
26+
u16::try_from(end_lba + 1 - start_lba).unwrap(),
27+
);
28+
writeln!(screen::Writer, "dap: {dap:?}").unwrap();
29+
unsafe {
30+
dap.perform_load(self.disk_number);
31+
}
32+
33+
let data = unsafe { slice::from_raw_parts(target_addr as *const u8, buf.len()) };
34+
buf.copy_from_slice(data);
35+
36+
self.current_offset = end_addr;
37+
Ok(buf.len())
38+
}
39+
}
40+
41+
impl fatfs::Seek for DiskAccess {
42+
fn seek(&mut self, pos: fatfs::SeekFrom) -> Result<u64, Self::Error> {
43+
writeln!(screen::Writer, "seek to {pos:?}").unwrap();
44+
match pos {
45+
fatfs::SeekFrom::Start(offset) => {
46+
self.current_offset = offset;
47+
Ok(self.current_offset)
48+
}
49+
fatfs::SeekFrom::Current(offset) => {
50+
self.current_offset = (i64::try_from(self.current_offset).unwrap() + offset)
51+
.try_into()
52+
.unwrap();
53+
Ok(self.current_offset)
54+
}
55+
fatfs::SeekFrom::End(_) => Err(()),
56+
}
57+
}
58+
}
59+
60+
impl fatfs::Write for DiskAccess {
61+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
62+
unimplemented!()
63+
}
64+
65+
fn flush(&mut self) -> Result<(), Self::Error> {
66+
unimplemented!()
67+
}
68+
}

bios/second_stage/src/fail.rs

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

bios/second_stage/src/fat.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,16 +204,11 @@ impl BiosParameterBlock {
204204

205205
/// Returns a root directory object allowing for futher penetration of a filesystem structure.
206206
pub fn check_root_dir(&self) {
207-
match self.fat_type() {
208-
FatType::Fat12 | FatType::Fat16 => crate::fail(b'y'),
209-
FatType::Fat32 => {
210-
self.root_dir_first_cluster;
211-
crate::fail(b'z');
212-
}
213-
}
207+
panic!("check_root_dir: fat type {:?}", self.fat_type())
214208
}
215209
}
216210

211+
#[derive(Debug)]
217212
pub enum FatType {
218213
/// 12 bits per FAT entry
219214
Fat12,

0 commit comments

Comments
 (0)