stage0: more bugfixes, size improvements
This commit is contained in:
parent
6886d43eef
commit
cb7eb4ec22
1 changed files with 23 additions and 11 deletions
|
@ -224,10 +224,10 @@ GLOBL _start
|
|||
push %ax /* save CRC[15:0] */ /* '1 v */
|
||||
xor %si, %si
|
||||
mov $0x5c, %cl
|
||||
call crc32
|
||||
call crc32 /* %ebx = ~CRC, CF = 1 */
|
||||
pop %ax /* restore CRC[15:0] */ /* '1 ^ */
|
||||
test %eax, %ebx
|
||||
jnz err_bad_gpt_csum
|
||||
adc %eax, %ebx /* check CRC and set %ebx = 0 if equal */
|
||||
jne err_bad_gpt_csum
|
||||
|
||||
/* store everything we need to rember from the GPT header (we assert there
|
||||
* to be no more than 65535 partitions and that each entry is no more than
|
||||
|
@ -332,10 +332,10 @@ LOCAL start2
|
|||
pop %cx /* restore table size in bytes */ /* '3 ^ */
|
||||
push %si /* save entry count */ /* '3 v */
|
||||
xor %si, %si
|
||||
call crc32
|
||||
call crc32 /* %ebx = ~CRC, CF = 1 */
|
||||
pop %cx /* restore entry count */ /* '3 ^ */
|
||||
pop %di /* restore CRC[15:0] */ /* '2 ^ */
|
||||
and %ebx, %edi /* %edi = 0 (crc32 returns the inverted value) */
|
||||
adc %ebx, %edi /* %edi = 0 if checksum matches */
|
||||
jnz err_bad_gpt_csum
|
||||
|
||||
/*
|
||||
|
@ -358,10 +358,18 @@ LOCAL start2
|
|||
|
||||
/*
|
||||
* Step 6: Load stage1 to the beginning of low memory (0x0500)
|
||||
*
|
||||
* stage1 must not exceed 32 K because some BIOSes freak out when asked
|
||||
* to load 64 K or more at once (which would cross a segment boundary).
|
||||
* We take advantage of that fact by "hardcoding" the number of bytes to
|
||||
* be loaded: We start with 64 K - 1 B, and divide that through the
|
||||
* logical sector size. The result is a sector count that definitely
|
||||
* spans at least 32 K unless we're dealing with 64 K sectors or larger,
|
||||
* in which case we wouldn't have made it this far anyway.
|
||||
*/
|
||||
|
||||
2: push %dx /* save drive number */ /* '1 v */
|
||||
mov $0x8000, %ax
|
||||
or $-1, %ax
|
||||
xor %dx, %dx
|
||||
divw (drive_params + 0x18) /* %ax = 0x8000 / sector size = sector count */
|
||||
xchg %ax, %cx /* %cx = sector count (xchg saves 1 byte) */
|
||||
|
@ -387,9 +395,9 @@ LOCAL start2
|
|||
xor %eax, %eax
|
||||
xchg %fs:0x04(%si), %eax /* offset 0x04: CRC (replace with 0) */
|
||||
push %ax /* save CRC[15:0] (crc32 clobbers %al) */ /* '4 v */
|
||||
call crc32
|
||||
call crc32 /* %ebx = ~CRC, CF = 1 */
|
||||
pop %ax /* restore CRC[15:0] */ /* '4 ^ */
|
||||
xor %ebx, %eax /* check CRC and clear %eax */
|
||||
adc %ebx, %eax /* check CRC */
|
||||
jnz err_bad_stage1_csum
|
||||
|
||||
/*
|
||||
|
@ -449,11 +457,13 @@ LOCAL read_lba
|
|||
END read_lba
|
||||
|
||||
/*
|
||||
* Do a CCITT32 ANSI CRC (polynomial 0x04c11db7) of %cx bytes at %fs:%si
|
||||
* and return THE COMPLEMENT (i.e. bitwise NOT of the CRC) in %ebx.
|
||||
* Calculate the CCITT32 ANSI CRC (polynomial 0x04c11db7) of %cx bytes
|
||||
* at %fs:%si and return THE COMPLEMENT of the result in %ebx.
|
||||
* Clobbers %al, %cx, and %si. Does not check for overflows (%si + %cx
|
||||
* must be <= 0x10000). If %cx is 0, the size is 64 KiB (0x10000), in
|
||||
* which case %si should also be 0 because of the missing wrap check.
|
||||
* This also sets CF = 1 because that allows for comparing the CRC with
|
||||
* the expected value through a single `adc` instruction.
|
||||
*
|
||||
* Stolen from "Hacker's Delight", second edition by Henry S. Warren, Jr.
|
||||
* and painstakingly ported to x86 assembly with focus on minimum size.
|
||||
|
@ -461,10 +471,11 @@ END read_lba
|
|||
* optimizations.
|
||||
*
|
||||
* %al: clobber
|
||||
* %ebx: return value (ATTENTION: COMPLEMENT of CRC)
|
||||
* %ebx: return value
|
||||
* %cx: byte count (clobber)
|
||||
* %si: data (clobber)
|
||||
* %fs: data segment
|
||||
* CF = 1
|
||||
*/
|
||||
LOCAL crc32
|
||||
/* this is expressed as an imm8 w/ sign extension */
|
||||
|
@ -483,6 +494,7 @@ LOCAL crc32
|
|||
|
||||
loop 1b
|
||||
|
||||
stc
|
||||
ret
|
||||
END crc32
|
||||
|
||||
|
|
Loading…
Reference in a new issue