4
4
5
5
use core:: { arch:: global_asm, slice} ;
6
6
use error:: NO_SECOND_STAGE_PARTITION ;
7
- use fail:: { fail , print_char, UnwrapOrFail } ;
7
+ use fail:: { print_char, UnwrapOrFail } ;
8
8
9
9
global_asm ! ( include_str!( "boot.s" ) ) ;
10
10
@@ -14,15 +14,10 @@ mod fail;
14
14
mod mbr;
15
15
16
16
extern "C" {
17
- static _mbr_start: u8 ;
18
17
static _partition_table: u8 ;
19
18
static _second_stage_start: u8 ;
20
19
}
21
20
22
- unsafe fn mbr_start ( ) -> * const u8 {
23
- unsafe { & _mbr_start }
24
- }
25
-
26
21
unsafe fn partition_table_raw ( ) -> * const u8 {
27
22
unsafe { & _partition_table }
28
23
}
@@ -38,34 +33,46 @@ pub extern "C" fn first_stage(disk_number: u16) {
38
33
print_char ( b'1' ) ;
39
34
let partition_table = & unsafe { slice:: from_raw_parts ( partition_table_raw ( ) , 16 * 4 ) } ;
40
35
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 ) ;
42
38
43
39
// load second stage partition into memory
44
40
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
+ }
59
66
}
60
67
61
68
// jump to second stage
62
69
print_char ( b'3' ) ;
63
70
let second_stage_entry_point: extern "C" fn (
64
71
disk_number : u16 ,
65
72
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 ) ;
69
76
for _ in 0 ..10 {
70
77
print_char ( b'R' ) ;
71
78
}
0 commit comments