Thomas Schmitt said:> I am wondering about the meaning or reason of "+20" in this
assembler line:
>
> movl (32+20)(%si), %ecx
>
> Why that extra offset 20 on the byte offset 32 which is specified by
> GPT specs (UEFI 2.4, 5.3.3) ? (Do i get the language wrong ?)
Well I've been looking at this. It seems gptmbr.S
(<http://git.zytor.com/syslinux/syslinux.git/tree/mbr/gptmbr.S>)
builds up a fake MBR GPT protective entry in memory at offset
0x1be (lines 196-212) and then puts the bootable GPT entry directly
after (lines 191, 217). The comments says so. The comments aren't
clear about also adding the GPT entry length between the MBR and GPT
entries. That's four more bytes. So 16+4=20.
I think si points at the fake MBR entry at the insruction you ask
about.
But isohdpfx.S is buggy:
/* Check to see if we have a partition table entry */
xorl %ebx, %ebx
xorl %ecx, %ecx
#ifdef PARTITION_SUPPORT
andw %si, %si /* %si == 0 -> no partition data */
jz 1f
testb $0x7f, (%si) /* Invalid active flag field? */
jnz 1f
cmpb %cl, 4(%si) /* Partition type zero == invalid? */
je 1f
cmpl $0x58504721, %eax /* !GPT signature in EAX? */
jne 2f
cmpb $0xed, 4(%si) /* EFI partition type? */
jne 2f
/* We have GPT partition information */
movl (32+20)(%si), %ecx
movl (36+20)(%si), %ebx
jmp 1f
/* We have non-GPT partition information */
2:
movl 8(%si), %ecx
#endif
1:
/* We have no partition information */
pushl %ebx /* -4: partoffset_hi */
pushl %ecx /* -8: partoffset_lo */
pushw %es /* -10: es:di -> $PnP header */
pushw %di /* -12: es:di -> $PnP header */
movw %bp, %ds
movw %bp, %es
ADJUST_DRIVE
pushw %dx /* -14: dl -> drive number */
/* Copy down to 0:0x600 */
movw $0x7c00, %si
movw $_start, %di
movw $(512/2), %cx
rep; movsw
ljmpw $0, $next
next:
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
movb $0x41, %ah /* %al == 0 already */
Here it claims that al is zero. This is not true. Especially if you
look at the line that says "cmpl $0x58504721, %eax" earlier. That
code is looking for a signature in eax! ADJUST_DRIVE marco doesn't
touch al.
So "movb $0x41, %ah" should be "movw $0x4100, %ax".
Also besides the 16/32 confusion in gptmbr.S there's more weirdness
that looks like a bug:
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
movb $0x41, %ah /* %al == 0 already */
movw $0x55aa, %bx
xorw %cx, %cx
xorb %dh, %dh
stc
int $0x13
popw %dx /* restore drive */
movb $0x08, %ah /* get CHS geometry */
jc 1f
cmpw $0xaa55, %bx
jne 1f
shrw %cx /* Bit 0 = fixed disk subset */
jnc 1f
/* We have EBIOS; patch in the following code at
read_sector_cbios: movb $0x42, %ah ; jmp read_common */
movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
(read_sector_cbios)
/*
* read sector size.
* Should not fail but if it does I assume that at least
* previous 512 value is not overridden
*/
movb $0x48, %ah
movw %sp, %si
1:
/* Get (C)HS geometry */
int $0x13
Assuming the check EBIOS call failed and returned carry, ah will be 1
(according to RBIL) so this last int 0x13 will execute "INT 13 - DISK
- GET STATUS OF LAST OPERATION" not "INT 13 - DISK - GET DRIVE
PARAMETERS" which is called with ah=8, which I think was the
intention.
Similarly if any other condition that are checked for a successful
EBIOS check fails, this int 0x13 will be called with rubbish.
I'd change the last lines to:
movw %sp, %si
jmp 2f
1:
mov $8, %ah
2:
/* Get (C)HS geometry */
int $0x13
--
MartinS