[PXE] Improve PnP/BBS detection

Use BBS installation check to see if we need to hook INT19 even on a PnP
BIOS.

Verify that $PnP signature is paragraph-aligned; bochs/qemu BIOS provides
a dummy $PnP signature with no valid entry point, and deliberately
unaligns the signature to indicate that it is not properly valid.

Print message if INT19 is hooked.

Attempt to use PMM even if BBS check failed.
This commit is contained in:
Michael Brown
2008-03-11 12:02:12 +00:00
parent 297002d7bd
commit 9c86a39551

View File

@@ -9,6 +9,7 @@
#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) ) #define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) ) #define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) ) #define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
#define PNP_GET_BBS_VERSION 0x60
.text .text
.code16 .code16
@@ -123,23 +124,41 @@ init:
movw $init_message, %si movw $init_message, %si
call print_message call print_message
/* Check for PnP BIOS */ /* Check for PnP BIOS */
testw $0x0f, %di /* PnP signature must be aligned - bochs */
jnz hook_int19 /* uses unalignment to indicate 'fake' PnP. */
cmpl $PNP_SIGNATURE, %es:0(%di) cmpl $PNP_SIGNATURE, %es:0(%di)
je ispnp jne hook_int19
notpnp: /* Not PnP: hook INT19 */ /* Is PnP: print PnP message */
movw $init_message_pnp, %si
call print_message
xchgw %bx, %bx
/* Check for BBS */
pushw %es:0x1b(%di) /* Real-mode data segment */
pushw %ds /* &(bbs_version) */
pushw $bbs_version
pushw $PNP_GET_BBS_VERSION
lcall *%es:0xd(%di)
addw $16, %sp
testw %ax, %ax
jne hook_int19
movw $init_message_bbs, %si
call print_message
jmp hook_bbs
/* Not BBS-compliant - must hook INT 19 */
hook_int19:
movw $init_message_int19, %si
call print_message
xorw %ax, %ax xorw %ax, %ax
movw %ax, %es movw %ax, %es
pushw %cs pushw %cs
pushw $int19_entry pushw $int19_entry
popl %es:( 0x19 * 4 ) popl %es:( 0x19 * 4 )
jmp 99f hook_bbs:
ispnp: /* Is PnP: print PnP message */
movw $init_message_pnp, %si
call print_message
/* Check for PMM */ /* Check for PMM */
movw $( 0xe000 - 1 ), %di movw $( 0xe000 - 1 ), %di
pmm_scan: pmm_scan:
incw %di incw %di
jz 99f jz no_pmm
movw %di, %es movw %di, %es
cmpl $PMM_SIGNATURE, %es:0 cmpl $PMM_SIGNATURE, %es:0
jne pmm_scan jne pmm_scan
@@ -158,13 +177,13 @@ pmm_scan:
pushl $0xffffffff /* No handle */ pushl $0xffffffff /* No handle */
pushl $( 0x00200000 / 16 ) /* 2MB in paragraphs */ pushl $( 0x00200000 / 16 ) /* 2MB in paragraphs */
pushw $0x0000 /* pmmAllocate */ pushw $0x0000 /* pmmAllocate */
lcall %es:*(7) lcall *%es:7
addw $12, %sp addw $12, %sp
testw %dx, %dx /* %ax==0 even on success, since align=2MB */ testw %dx, %dx /* %ax==0 even on success, since align=2MB */
jnz gotpmm jnz gotpmm
movw $init_message_pmm_failed, %si movw $init_message_pmm_failed, %si
call print_message call print_message
jmp 99f jmp no_pmm
gotpmm: /* PMM allocation succeeded: copy ROM to PMM block */ gotpmm: /* PMM allocation succeeded: copy ROM to PMM block */
pushal /* PMM presence implies 1kB stack */ pushal /* PMM presence implies 1kB stack */
movw %ax, %es /* %ax=0 already - see above */ movw %ax, %es /* %ax=0 already - see above */
@@ -188,10 +207,10 @@ gotpmm: /* PMM allocation succeeded: copy ROM to PMM block */
loop 1b loop 1b
subb %bl, checksum subb %bl, checksum
popal popal
99: no_pmm:
/* Print CRLF to terminate messages */ /* Print CRLF to terminate messages */
movw $init_message_crlf, %si movw $'\n', %ax
call print_message call print_character
/* Restore registers */ /* Restore registers */
popw %es popw %es
popw %ds popw %ds
@@ -202,20 +221,23 @@ gotpmm: /* PMM allocation succeeded: copy ROM to PMM block */
.size init, . - init .size init, . - init
init_message: init_message:
.asciz "gPXE (http://etherboot.org)" .asciz "gPXE (http://etherboot.org) -"
.size init_message, . - init_message .size init_message, . - init_message
init_message_pnp: init_message_pnp:
.asciz " - PnP BIOS detected" .asciz " PnP"
.size init_message_pnp, . - init_message_pnp .size init_message_pnp, . - init_message_pnp
init_message_bbs:
.asciz " BBS"
.size init_message_bbs, . - init_message_bbs
init_message_pmm: init_message_pmm:
.asciz ", using PMM" .asciz " PMM"
.size init_message_pmm, . - init_message_pmm .size init_message_pmm, . - init_message_pmm
init_message_pmm_failed: init_message_pmm_failed:
.asciz " (failed)" .asciz "(failed)"
.size init_message_pmm_failed, . - init_message_pmm_failed .size init_message_pmm_failed, . - init_message_pmm_failed
init_message_crlf: init_message_int19:
.asciz "\n" .asciz " INT19"
.size init_message_crlf, . - init_message_crlf .size init_message_int19, . - init_message_int19
/* ROM image location /* ROM image location
* *
@@ -224,6 +246,7 @@ init_message_crlf:
image_source: image_source:
.long 0 .long 0
.size image_source, . - image_source .size image_source, . - image_source
/* Temporary decompression area /* Temporary decompression area
* *
* May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block. * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
@@ -232,6 +255,13 @@ decompress_to:
.long HIGHMEM_LOADPOINT .long HIGHMEM_LOADPOINT
.size decompress_to, . - decompress_to .size decompress_to, . - decompress_to
/* BBS version
*
* Filled in by BBS BIOS. We ignore the value.
*/
bbs_version:
.word 0
/* Boot Execution Vector entry point /* Boot Execution Vector entry point
* *
* Called by the PnP BIOS when it wants to boot us. * Called by the PnP BIOS when it wants to boot us.