From 7bc03d37a270b5a281b36b4f43b6913bf98f5e74 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 14 Jan 2007 02:20:10 +0000 Subject: [PATCH] Select a PXE network device before starting PXE NBP. Move pxe_boot() code to pxe_image.c --- src/arch/i386/image/pxe_image.c | 32 +++++++++++- src/arch/i386/include/pxe_call.h | 15 +++++- src/arch/i386/interface/pxe/pxe_call.c | 66 ++++++------------------- src/arch/i386/interface/pxe/pxe_entry.S | 10 ++-- 4 files changed, 64 insertions(+), 59 deletions(-) diff --git a/src/arch/i386/image/pxe_image.c b/src/arch/i386/image/pxe_image.c index f88c4597..27a7e42d 100644 --- a/src/arch/i386/image/pxe_image.c +++ b/src/arch/i386/image/pxe_image.c @@ -23,10 +23,12 @@ * */ +#include +#include #include #include #include -#include +#include /** PXE load address segment */ #define PXE_LOAD_SEGMENT 0 @@ -43,7 +45,33 @@ struct image_type pxe_image_type __image_type ( PROBE_PXE ); * @ret rc Return status code */ static int pxe_exec ( struct image *image __unused ) { - return pxe_boot(); + struct net_device *netdev; + int discard_b, discard_c; + uint16_t rc; + + /* Ensure that PXE stack is ready to use */ + pxe_init_structures(); + pxe_hook_int1a(); + + /* Arbitrarily pick the first open network device to use for PXE */ + for_each_netdev ( netdev ) { + pxe_netdev = netdev; + break; + } + + /* Far call to PXE NBP */ + __asm__ __volatile__ ( REAL_CODE ( "pushw %%cx\n\t" + "pushw %%ax\n\t" + "movw %%cx, %%es\n\t" + "lcall $0, $0x7c00\n\t" ) + : "=a" ( rc ), "=b" ( discard_b ), + "=c" ( discard_c ) + : "a" ( & __from_text16 ( ppxe ) ), + "b" ( & __from_text16 ( pxenv ) ), + "c" ( rm_cs ) + : "edx", "esi", "edi", "ebp", "memory" ); + + return rc; } /** diff --git a/src/arch/i386/include/pxe_call.h b/src/arch/i386/include/pxe_call.h index 84893b55..c6c1c6d8 100644 --- a/src/arch/i386/include/pxe_call.h +++ b/src/arch/i386/include/pxe_call.h @@ -6,6 +6,19 @@ * PXE API entry point */ -extern int pxe_boot ( void ); +#include +#include + +/** !PXE structure */ +extern struct s_PXE __text16 ( ppxe ); +#define ppxe __use_text16 ( ppxe ) + +/** PXENV+ structure */ +extern struct s_PXENV __text16 ( pxenv ); +#define pxenv __use_text16 ( pxenv ) + +extern void pxe_hook_int1a ( void ); +extern int pxe_unhook_int1a ( void ); +extern void pxe_init_structures ( void ); #endif /* _PXE_CALL_H */ diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c index d39c65aa..7a185155 100644 --- a/src/arch/i386/interface/pxe/pxe_call.c +++ b/src/arch/i386/interface/pxe/pxe_call.c @@ -34,14 +34,6 @@ extern struct segoff __text16 ( pxe_int_1a_vector ); /** INT 1A handler */ extern void pxe_int_1a ( void ); -/** !PXE structure */ -extern struct s_PXE __text16 ( pxe ); -#define pxe __use_text16 ( pxe ) - -/** PXENV+ structure */ -extern struct s_PXENV __text16 ( pxenv ); -#define pxenv __use_text16 ( pxenv ) - /** A function pointer to hold any PXE API call * * Used by pxe_api_call() to avoid large swathes of duplicated code. @@ -310,7 +302,7 @@ void pxe_api_call ( struct i386_all_regs *ix86 ) { * Hook INT 1A for PXE * */ -void pxe_hook_int ( void ) { +void pxe_hook_int1a ( void ) { hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a, &pxe_int_1a_vector ); } @@ -320,7 +312,7 @@ void pxe_hook_int ( void ) { * * @ret rc Return status code */ -int pxe_unhook_int ( void ) { +int pxe_unhook_int1a ( void ) { return unhook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a, &pxe_int_1a_vector ); } @@ -343,24 +335,24 @@ static uint8_t pxe_checksum ( void *data, size_t size ) { } /** - * Initialise PXE stack + * Initialise !PXE and PXENV+ structures * */ -void init_pxe ( void ) { +void pxe_init_structures ( void ) { uint32_t rm_cs_phys = ( rm_cs << 4 ); uint32_t rm_ds_phys = ( rm_ds << 4 ); /* Fill in missing segment fields */ - pxe.EntryPointSP.segment = rm_cs; - pxe.EntryPointESP.segment = rm_cs; - pxe.Stack.segment_address = rm_ds; - pxe.Stack.Physical_address = rm_ds_phys; - pxe.UNDIData.segment_address = rm_ds; - pxe.UNDIData.Physical_address = rm_ds_phys; - pxe.UNDICode.segment_address = rm_cs; - pxe.UNDICode.Physical_address = rm_cs_phys; - pxe.UNDICodeWrite.segment_address = rm_cs; - pxe.UNDICodeWrite.Physical_address = rm_cs_phys; + ppxe.EntryPointSP.segment = rm_cs; + ppxe.EntryPointESP.segment = rm_cs; + ppxe.Stack.segment_address = rm_ds; + ppxe.Stack.Physical_address = rm_ds_phys; + ppxe.UNDIData.segment_address = rm_ds; + ppxe.UNDIData.Physical_address = rm_ds_phys; + ppxe.UNDICode.segment_address = rm_cs; + ppxe.UNDICode.Physical_address = rm_cs_phys; + ppxe.UNDICodeWrite.segment_address = rm_cs; + ppxe.UNDICodeWrite.Physical_address = rm_cs_phys; pxenv.RMEntry.segment = rm_cs; pxenv.StackSeg = rm_ds; pxenv.UNDIDataSeg = rm_ds; @@ -368,34 +360,6 @@ void init_pxe ( void ) { pxenv.PXEPtr.segment = rm_cs; /* Update checksums */ - pxe.StructCksum -= pxe_checksum ( &pxe, sizeof ( pxe ) ); + ppxe.StructCksum -= pxe_checksum ( &ppxe, sizeof ( ppxe ) ); pxenv.Checksum -= pxe_checksum ( &pxenv, sizeof ( pxenv ) ); } - -/** - * Boot via PXE NBP - * - * @ret rc Return status code - */ -int pxe_boot ( void ) { - int discard_b, discard_c; - uint16_t rc; - - /* Ensure that PXE stack is ready to use */ - init_pxe(); - pxe_hook_int(); - - /* Far call to PXE NBP */ - __asm__ __volatile__ ( REAL_CODE ( "pushw %%cx\n\t" - "pushw %%ax\n\t" - "movw %%cx, %%es\n\t" - "lcall $0, $0x7c00\n\t" ) - : "=a" ( rc ), "=b" ( discard_b ), - "=c" ( discard_c ) - : "a" ( & __from_text16 ( pxe ) ), - "b" ( & __from_text16 ( pxenv ) ), - "c" ( rm_cs ) - : "edx", "esi", "edi", "ebp", "memory" ); - - return rc; -} diff --git a/src/arch/i386/interface/pxe/pxe_entry.S b/src/arch/i386/interface/pxe/pxe_entry.S index 065fe755..204894ef 100644 --- a/src/arch/i386/interface/pxe/pxe_entry.S +++ b/src/arch/i386/interface/pxe/pxe_entry.S @@ -27,9 +27,9 @@ **************************************************************************** */ .section ".text16.data" - .globl pxe + .globl ppxe .align 16 -pxe: +ppxe: .ascii "!PXE" /* Signature */ .byte pxe_length /* StructLength */ .byte 0 /* StructCksum */ @@ -52,8 +52,8 @@ pxe_segments: .word 0, 0, 0, 0 /* BC_Code */ .word 0, 0, 0, 0 /* BC_CodeWrite */ .equ SegDescCnt, ( ( . - pxe_segments ) / 8 ) - .equ pxe_length, . - pxe - .size pxe, . - pxe + .equ pxe_length, . - ppxe + .size ppxe, . - ppxe /**************************************************************************** * PXENV+ structure @@ -80,7 +80,7 @@ pxenv: .word _data16_size /* UNDIDataSize */ .word 0 /* UNDICodeSeg */ .word _text16_size /* UNDICodeSize */ - .word pxe, 0 /* PXEPtr */ + .word ppxe, 0 /* PXEPtr */ .equ pxenv_length, . - pxenv .size pxenv, . - pxenv