44
55use core:: { arch:: global_asm, slice} ;
66use error:: NO_SECOND_STAGE_PARTITION ;
7- use fail:: { fail , print_char, UnwrapOrFail } ;
7+ use fail:: { print_char, UnwrapOrFail } ;
88
99global_asm ! ( include_str!( "boot.s" ) ) ;
1010
@@ -14,15 +14,10 @@ mod fail;
1414mod mbr;
1515
1616extern "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-
2621unsafe 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