mirror of https://github.com/ipxe/ipxe.git
Select a PXE network device before starting PXE NBP.
Move pxe_boot() code to pxe_image.cpull/1/head
parent
98240d99f0
commit
7bc03d37a2
|
@ -23,10 +23,12 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <pxe.h>
|
||||||
|
#include <pxe_call.h>
|
||||||
#include <gpxe/uaccess.h>
|
#include <gpxe/uaccess.h>
|
||||||
#include <gpxe/image.h>
|
#include <gpxe/image.h>
|
||||||
#include <gpxe/segment.h>
|
#include <gpxe/segment.h>
|
||||||
#include <pxe_call.h>
|
#include <gpxe/netdevice.h>
|
||||||
|
|
||||||
/** PXE load address segment */
|
/** PXE load address segment */
|
||||||
#define PXE_LOAD_SEGMENT 0
|
#define PXE_LOAD_SEGMENT 0
|
||||||
|
@ -43,7 +45,33 @@ struct image_type pxe_image_type __image_type ( PROBE_PXE );
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int pxe_exec ( struct image *image __unused ) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,6 +6,19 @@
|
||||||
* PXE API entry point
|
* PXE API entry point
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern int pxe_boot ( void );
|
#include <pxe_api.h>
|
||||||
|
#include <realmode.h>
|
||||||
|
|
||||||
|
/** !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 */
|
#endif /* _PXE_CALL_H */
|
||||||
|
|
|
@ -34,14 +34,6 @@ extern struct segoff __text16 ( pxe_int_1a_vector );
|
||||||
/** INT 1A handler */
|
/** INT 1A handler */
|
||||||
extern void pxe_int_1a ( void );
|
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
|
/** A function pointer to hold any PXE API call
|
||||||
*
|
*
|
||||||
* Used by pxe_api_call() to avoid large swathes of duplicated code.
|
* 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
|
* Hook INT 1A for PXE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void pxe_hook_int ( void ) {
|
void pxe_hook_int1a ( void ) {
|
||||||
hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
|
hook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
|
||||||
&pxe_int_1a_vector );
|
&pxe_int_1a_vector );
|
||||||
}
|
}
|
||||||
|
@ -320,7 +312,7 @@ void pxe_hook_int ( void ) {
|
||||||
*
|
*
|
||||||
* @ret rc Return status code
|
* @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,
|
return unhook_bios_interrupt ( 0x1a, ( unsigned int ) pxe_int_1a,
|
||||||
&pxe_int_1a_vector );
|
&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_cs_phys = ( rm_cs << 4 );
|
||||||
uint32_t rm_ds_phys = ( rm_ds << 4 );
|
uint32_t rm_ds_phys = ( rm_ds << 4 );
|
||||||
|
|
||||||
/* Fill in missing segment fields */
|
/* Fill in missing segment fields */
|
||||||
pxe.EntryPointSP.segment = rm_cs;
|
ppxe.EntryPointSP.segment = rm_cs;
|
||||||
pxe.EntryPointESP.segment = rm_cs;
|
ppxe.EntryPointESP.segment = rm_cs;
|
||||||
pxe.Stack.segment_address = rm_ds;
|
ppxe.Stack.segment_address = rm_ds;
|
||||||
pxe.Stack.Physical_address = rm_ds_phys;
|
ppxe.Stack.Physical_address = rm_ds_phys;
|
||||||
pxe.UNDIData.segment_address = rm_ds;
|
ppxe.UNDIData.segment_address = rm_ds;
|
||||||
pxe.UNDIData.Physical_address = rm_ds_phys;
|
ppxe.UNDIData.Physical_address = rm_ds_phys;
|
||||||
pxe.UNDICode.segment_address = rm_cs;
|
ppxe.UNDICode.segment_address = rm_cs;
|
||||||
pxe.UNDICode.Physical_address = rm_cs_phys;
|
ppxe.UNDICode.Physical_address = rm_cs_phys;
|
||||||
pxe.UNDICodeWrite.segment_address = rm_cs;
|
ppxe.UNDICodeWrite.segment_address = rm_cs;
|
||||||
pxe.UNDICodeWrite.Physical_address = rm_cs_phys;
|
ppxe.UNDICodeWrite.Physical_address = rm_cs_phys;
|
||||||
pxenv.RMEntry.segment = rm_cs;
|
pxenv.RMEntry.segment = rm_cs;
|
||||||
pxenv.StackSeg = rm_ds;
|
pxenv.StackSeg = rm_ds;
|
||||||
pxenv.UNDIDataSeg = rm_ds;
|
pxenv.UNDIDataSeg = rm_ds;
|
||||||
|
@ -368,34 +360,6 @@ void init_pxe ( void ) {
|
||||||
pxenv.PXEPtr.segment = rm_cs;
|
pxenv.PXEPtr.segment = rm_cs;
|
||||||
|
|
||||||
/* Update checksums */
|
/* Update checksums */
|
||||||
pxe.StructCksum -= pxe_checksum ( &pxe, sizeof ( pxe ) );
|
ppxe.StructCksum -= pxe_checksum ( &ppxe, sizeof ( ppxe ) );
|
||||||
pxenv.Checksum -= pxe_checksum ( &pxenv, sizeof ( pxenv ) );
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
*/
|
*/
|
||||||
.section ".text16.data"
|
.section ".text16.data"
|
||||||
.globl pxe
|
.globl ppxe
|
||||||
.align 16
|
.align 16
|
||||||
pxe:
|
ppxe:
|
||||||
.ascii "!PXE" /* Signature */
|
.ascii "!PXE" /* Signature */
|
||||||
.byte pxe_length /* StructLength */
|
.byte pxe_length /* StructLength */
|
||||||
.byte 0 /* StructCksum */
|
.byte 0 /* StructCksum */
|
||||||
|
@ -52,8 +52,8 @@ pxe_segments:
|
||||||
.word 0, 0, 0, 0 /* BC_Code */
|
.word 0, 0, 0, 0 /* BC_Code */
|
||||||
.word 0, 0, 0, 0 /* BC_CodeWrite */
|
.word 0, 0, 0, 0 /* BC_CodeWrite */
|
||||||
.equ SegDescCnt, ( ( . - pxe_segments ) / 8 )
|
.equ SegDescCnt, ( ( . - pxe_segments ) / 8 )
|
||||||
.equ pxe_length, . - pxe
|
.equ pxe_length, . - ppxe
|
||||||
.size pxe, . - pxe
|
.size ppxe, . - ppxe
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* PXENV+ structure
|
* PXENV+ structure
|
||||||
|
@ -80,7 +80,7 @@ pxenv:
|
||||||
.word _data16_size /* UNDIDataSize */
|
.word _data16_size /* UNDIDataSize */
|
||||||
.word 0 /* UNDICodeSeg */
|
.word 0 /* UNDICodeSeg */
|
||||||
.word _text16_size /* UNDICodeSize */
|
.word _text16_size /* UNDICodeSize */
|
||||||
.word pxe, 0 /* PXEPtr */
|
.word ppxe, 0 /* PXEPtr */
|
||||||
.equ pxenv_length, . - pxenv
|
.equ pxenv_length, . - pxenv
|
||||||
.size pxenv, . - pxenv
|
.size pxenv, . - pxenv
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue