1 | FILE_LICENCE ( GPL2_OR_LATER ) |
---|
2 | |
---|
3 | #define BOOT_SEG 0x07c0 |
---|
4 | #define EXEC_SEG 0x0100 |
---|
5 | #define STACK_SEG 0x0200 |
---|
6 | #define STACK_SIZE 0x2000 |
---|
7 | |
---|
8 | .text |
---|
9 | .arch i386 |
---|
10 | .section ".prefix", "awx", @progbits |
---|
11 | .code16 |
---|
12 | |
---|
13 | /* |
---|
14 | * Find active partition |
---|
15 | * |
---|
16 | * Parameters: |
---|
17 | * %dl : BIOS drive number |
---|
18 | * %bp : Active partition handler routine |
---|
19 | */ |
---|
20 | find_active_partition: |
---|
21 | /* Set up stack at STACK_SEG:STACK_SIZE */ |
---|
22 | movw $STACK_SEG, %ax |
---|
23 | movw %ax, %ss |
---|
24 | movw $STACK_SIZE, %sp |
---|
25 | |
---|
26 | /* Relocate self to EXEC_SEG */ |
---|
27 | pushw $BOOT_SEG |
---|
28 | popw %ds |
---|
29 | pushw $EXEC_SEG |
---|
30 | popw %es |
---|
31 | xorw %si, %si |
---|
32 | xorw %di, %di |
---|
33 | movw $0x200, %cx |
---|
34 | rep movsb |
---|
35 | ljmp $EXEC_SEG, $1f |
---|
36 | 1: pushw %ds |
---|
37 | popw %es |
---|
38 | pushw %cs |
---|
39 | popw %ds |
---|
40 | |
---|
41 | /* Check for LBA extensions */ |
---|
42 | movb $0x41, %ah |
---|
43 | movw $0x55aa, %bx |
---|
44 | stc |
---|
45 | int $0x13 |
---|
46 | jc 1f |
---|
47 | cmpw $0xaa55, %bx |
---|
48 | jne 1f |
---|
49 | movw $read_lba, read_sectors |
---|
50 | 1: |
---|
51 | /* Read and process root partition table */ |
---|
52 | xorb %dh, %dh |
---|
53 | movw $0x0001, %cx |
---|
54 | xorl %esi, %esi |
---|
55 | xorl %edi, %edi |
---|
56 | call process_table |
---|
57 | |
---|
58 | /* Print failure message */ |
---|
59 | movw $10f, %si |
---|
60 | jmp boot_error |
---|
61 | 10: .asciz "Could not locate active partition\r\n" |
---|
62 | |
---|
63 | /* |
---|
64 | * Print failure message and boot next device |
---|
65 | * |
---|
66 | * Parameters: |
---|
67 | * %si : Failure string |
---|
68 | */ |
---|
69 | boot_error: |
---|
70 | cld |
---|
71 | movw $0x0007, %bx |
---|
72 | movb $0x0e, %ah |
---|
73 | 1: lodsb |
---|
74 | testb %al, %al |
---|
75 | je 99f |
---|
76 | int $0x10 |
---|
77 | jmp 1b |
---|
78 | 99: /* Boot next device */ |
---|
79 | int $0x18 |
---|
80 | |
---|
81 | /* |
---|
82 | * Process partition table |
---|
83 | * |
---|
84 | * Parameters: |
---|
85 | * %dl : BIOS drive number |
---|
86 | * %dh : Head |
---|
87 | * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) |
---|
88 | * %ch : Low eight bits of cylinder |
---|
89 | * %esi:%edi : LBA address |
---|
90 | * %bp : Active partition handler routine |
---|
91 | * |
---|
92 | * Returns: |
---|
93 | * CF set on error |
---|
94 | */ |
---|
95 | process_table: |
---|
96 | pushal |
---|
97 | call read_boot_sector |
---|
98 | jc 99f |
---|
99 | movw $446, %bx |
---|
100 | 1: call process_partition |
---|
101 | addw $16, %bx |
---|
102 | cmpw $510, %bx |
---|
103 | jne 1b |
---|
104 | 99: popal |
---|
105 | ret |
---|
106 | |
---|
107 | /* |
---|
108 | * Process partition |
---|
109 | * |
---|
110 | * Parameters: |
---|
111 | * %dl : BIOS drive number |
---|
112 | * %dh : Head |
---|
113 | * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) |
---|
114 | * %ch : Low eight bits of cylinder |
---|
115 | * %esi:%edi : LBA address |
---|
116 | * %bx : Offset within partition table |
---|
117 | * %bp : Active partition handler routine |
---|
118 | */ |
---|
119 | process_partition: |
---|
120 | pushal |
---|
121 | /* Load C/H/S values from partition entry */ |
---|
122 | movb %es:1(%bx), %dh |
---|
123 | movw %es:2(%bx), %cx |
---|
124 | /* Update LBA address from partition entry */ |
---|
125 | addl %es:8(%bx), %edi |
---|
126 | adcl $0, %esi |
---|
127 | /* Check active flag */ |
---|
128 | testb $0x80, %es:(%bx) |
---|
129 | jz 1f |
---|
130 | call read_boot_sector |
---|
131 | jc 99f |
---|
132 | jmp *%bp |
---|
133 | 1: /* Check for extended partition */ |
---|
134 | movb %es:4(%bx), %al |
---|
135 | cmpb $0x05, %al |
---|
136 | je 2f |
---|
137 | cmpb $0x0f, %al |
---|
138 | je 2f |
---|
139 | cmpb $0x85, %al |
---|
140 | jne 99f |
---|
141 | 2: call process_table |
---|
142 | 99: popal |
---|
143 | /* Reload original partition table */ |
---|
144 | call read_boot_sector |
---|
145 | ret |
---|
146 | |
---|
147 | /* |
---|
148 | * Read single sector to %es:0000 and verify 0x55aa signature |
---|
149 | * |
---|
150 | * Parameters: |
---|
151 | * %dl : BIOS drive number |
---|
152 | * %dh : Head |
---|
153 | * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) |
---|
154 | * %ch : Low eight bits of cylinder |
---|
155 | * %esi:%edi : LBA address |
---|
156 | * |
---|
157 | * Returns: |
---|
158 | * CF set on error |
---|
159 | */ |
---|
160 | read_boot_sector: |
---|
161 | pushw %ax |
---|
162 | movw $1, %ax |
---|
163 | call *read_sectors |
---|
164 | jc 99f |
---|
165 | cmpw $0xaa55, %es:(510) |
---|
166 | je 99f |
---|
167 | stc |
---|
168 | 99: popw %ax |
---|
169 | ret |
---|
170 | |
---|
171 | /* |
---|
172 | * Read sectors to %es:0000 |
---|
173 | * |
---|
174 | * Parameters: |
---|
175 | * %dl : BIOS drive number |
---|
176 | * %dh : Head |
---|
177 | * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7) |
---|
178 | * %ch : Low eight bits of cylinder |
---|
179 | * %esi:%edi : LBA address |
---|
180 | * %ax : Number of sectors (max 127) |
---|
181 | * |
---|
182 | * Returns: |
---|
183 | * CF set on error |
---|
184 | */ |
---|
185 | read_sectors: .word read_chs |
---|
186 | |
---|
187 | read_chs: |
---|
188 | /* Read sectors using C/H/S address */ |
---|
189 | pushal |
---|
190 | xorw %bx, %bx |
---|
191 | movb $0x02, %ah |
---|
192 | stc |
---|
193 | int $0x13 |
---|
194 | sti |
---|
195 | popal |
---|
196 | ret |
---|
197 | |
---|
198 | read_lba: |
---|
199 | /* Read sectors using LBA address */ |
---|
200 | pushal |
---|
201 | movw %ax, (lba_desc + 2) |
---|
202 | pushw %es |
---|
203 | popw (lba_desc + 6) |
---|
204 | movl %edi, (lba_desc + 8) |
---|
205 | movl %esi, (lba_desc + 12) |
---|
206 | movw $lba_desc, %si |
---|
207 | movb $0x42, %ah |
---|
208 | int $0x13 |
---|
209 | popal |
---|
210 | ret |
---|
211 | |
---|
212 | lba_desc: |
---|
213 | .byte 0x10 |
---|
214 | .byte 0 |
---|
215 | .word 1 |
---|
216 | .word 0x0000 |
---|
217 | .word 0x0000 |
---|
218 | .long 0, 0 |
---|