diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-08-11 11:49:04 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-08-11 11:49:04 -0700 |
commit | e32f5182161fd5210e67ae57136e929dc20e0776 (patch) | |
tree | b71aab9e889a2d607d792763d011c8e72e3d74a2 | |
parent | 5d7d50a01de8282a0e910beb0a9f151e526dcb62 (diff) | |
download | syslinux-e32f5182161fd5210e67ae57136e929dc20e0776.tar.gz |
pxe: clean up C code; reimplement "Plan C"; share PXE API definitions
Minor cleanups to the C code.
Reimplement "Plan C" for finding the entry point.
Share the PXE API definitions between com32 and the core.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | com32/include/syslinux/pxe.h | 487 | ||||
-rw-r--r-- | com32/include/syslinux/pxe_api.h | 531 | ||||
-rw-r--r-- | core/include/pxe.h | 234 | ||||
-rw-r--r-- | core/pxe.c | 159 | ||||
-rw-r--r-- | core/pxelinux.asm | 39 |
5 files changed, 695 insertions, 755 deletions
diff --git a/com32/include/syslinux/pxe.h b/com32/include/syslinux/pxe.h index 037642bc..041e0ae1 100644 --- a/com32/include/syslinux/pxe.h +++ b/com32/include/syslinux/pxe.h @@ -34,493 +34,10 @@ #ifndef _SYSLINUX_PXE_H #define _SYSLINUX_PXE_H -#include <stdint.h> -#include <netinet/in.h> -#include <klibc/compiler.h> - -/* PXE spec structures and definitions. These mostly follow the PXE - spec, except when the PXE spec is unnecessarily stupid. Of course, - that is most of the time. */ - -/* Basic types; use Unix-like _t convention instead of SCREAMING; also - re-use types we already have, like in_addr_t. */ - -typedef uint16_t pxenv_status_t; - -#define MAC_ADDR_LEN 16 -typedef uint8_t mac_addr_t[MAC_ADDR_LEN]; - -/* "Protected mode segment descriptor" according to PXE... */ -typedef struct { - uint16_t segaddr; - uint32_t physaddr; - uint16_t segsize; -} __packed pxe_segdesc_t; - -typedef struct { - uint16_t offs; - uint16_t seg; -} segoff16_t; - -typedef struct { - uint8_t opcode; -#define BOOTP_REQ 1 -#define BOOTP_REP 2 - uint8_t Hardware; - uint8_t Hardlen; - uint8_t Gatehops; - uint32_t ident; - uint16_t seconds; - uint16_t Flags; -#define BOOTP_BCAST 0x8000 - in_addr_t cip; /* Client IP address */ - in_addr_t yip; /* You IP address */ - in_addr_t sip; /* next server IP address */ - in_addr_t gip; /*relay agent IP address */ - mac_addr_t CAddr; - uint8_t Sname[64]; - uint8_t bootfile[128]; - union { -#define BOOTP_DHCPVEND 1024 - uint8_t d[BOOTP_DHCPVEND]; - struct { - uint8_t magic[4]; -#define VM_RFC1048 0x63825363L - uint32_t flags; - uint8_t pad[56]; - } v; - } vendor; -} __packed pxe_bootp_t; - -/* Function calling structures and constants */ - -typedef struct s_PXENV_GET_CACHED_INFO { - pxenv_status_t Status; - uint16_t PacketType; -#define PXENV_PACKET_TYPE_DHCP_DISCOVER 1 -#define PXENV_PACKET_TYPE_DHCP_ACK 2 -#define PXENV_PACKET_TYPE_CACHED_REPLY 3 - uint16_t BufferSize; - segoff16_t Buffer; - uint16_t BufferLimit; -} __packed t_PXENV_GET_CACHED_INFO; - -typedef struct s_PXENV_START_UNDI { - pxenv_status_t Status; - uint16_t AX; - uint16_t BX; - uint16_t DX; - uint16_t DI; - uint16_t ES; -} __packed t_PXENV_START_UNDI; - -typedef struct s_PXENV_STOP_UNDI { - pxenv_status_t Status; -} __packed t_PXENV_STOP_UNDI; - -typedef struct s_PXENV_START_BASE { - pxenv_status_t Status; -} __packed t_PXENV_START_BASE; - -typedef struct s_PXENV_STOP_BASE { - pxenv_status_t Status; -} __packed t_PXENV_STOP_BASE; - -typedef struct s_PXENV_TFTP_OPEN { - pxenv_status_t Status; - in_addr_t ServerIPAddress; - in_addr_t GatewayIPAddress; - uint8_t FileName[128]; - in_port_t TFTPPort; - uint16_t PacketSize; -} __packed t_PXENV_TFTP_OPEN; - -typedef struct s_PXENV_TFTP_CLOSE { - pxenv_status_t Status; -} __packed t_PXENV_TFTP_CLOSE; - -typedef struct s_PXENV_TFTP_READ { - pxenv_status_t Status; - uint16_t PacketNumber; - uint16_t BufferSize; - segoff16_t Buffer; -} __packed t_PXENV_TFTP_READ; - -typedef struct s_PXENV_TFTP_READ_FILE { - pxenv_status_t Status; - uint8_t FileName[128]; - uint32_t BufferSize; - void *Buffer; - in_addr_t ServerIPAddress; - in_addr_t GatewayIPAddress; - in_addr_t McastIPAddress; - in_port_t TFTPClntPort; - in_port_t TFTPSrvPort; - uint16_t TFTPOpenTimeOut; - uint16_t TFTPReopenDelay; -} __packed t_PXENV_TFTP_READ_FILE; - -typedef struct s_PXENV_TFTP_GET_FSIZE { - pxenv_status_t Status; - in_addr_t ServerIPAddress; - in_addr_t GatewayIPAddress; - uint8_t FileName[128]; - uint32_t FileSize; -} __packed t_PXENV_TFTP_GET_FSIZE; - -typedef struct s_PXENV_UDP_OPEN { - pxenv_status_t status; - in_addr_t src_ip; -} __packed t_PXENV_UDP_OPEN; - -typedef struct s_PXENV_UDP_CLOSE { - pxenv_status_t status; -} __packed t_PXENV_UDP_CLOSE; - -typedef struct s_PXENV_UDP_WRITE { - pxenv_status_t status; - in_addr_t ip; - in_addr_t gw; - in_port_t src_port; - in_port_t dst_port; - uint16_t buffer_size; - segoff16_t buffer; -} __packed t_PXENV_UDP_WRITE; - -typedef struct s_PXENV_UDP_READ { - pxenv_status_t status; - in_addr_t src_ip; - in_addr_t dest_ip; - in_port_t s_port; - in_port_t d_port; - uint16_t buffer_size; - segoff16_t buffer; -} __packed t_PXENV_UDP_READ; - -typedef struct s_PXENV_UNDI_STARTUP { - pxenv_status_t Status; -} __packed t_PXENV_UNDI_STARTUP; - -typedef struct s_PXENV_UNDI_CLEANUP { - pxenv_status_t Status; -} __packed t_PXENV_UNDI_CLEANUP; - -typedef struct s_PXENV_UNDI_INITIALIZE { - pxenv_status_t Status; - void *ProtocolIni; - uint8_t reserved[8]; -} __packed t_PXENV_UNDI_INITIALIZE; - -#define MAXNUM_MCADDR 8 -typedef struct s_PXENV_UNDI_MCAST_ADDRESS { - uint16_t MCastAddrCount; - mac_addr_t McastAddr[MAXNUM_MCADDR]; -} __packed t_PXENV_UNDI_MCAST_ADDRESS; - -typedef struct s_PXENV_UNDI_RESET { - pxenv_status_t Status; - t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; -} __packed t_PXENV_UNDI_RESET; - -typedef struct s_PXENV_UNDI_SHUTDOWN { - pxenv_status_t Status; -} __packed t_PXENV_UNDI_SHUTDOWN; - -typedef struct s_PXENV_UNDI_OPEN { - pxenv_status_t Status; - uint16_t OpenFlag; - uint16_t PktFilter; -#define FLTR_DIRECTED 0x0001 -#define FLTR_BRDCST 0x0002 -#define FLTR_PRMSCS 0x0004 -#define FLTR_SRC_RTG 0x0008 - t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; -} __packed t_PXENV_UNDI_OPEN; - -typedef struct s_PXENV_UNDI_CLOSE { - pxenv_status_t Status; -} __packed t_PXENV_UNDI_CLOSE; - -typedef struct s_PXENV_UNDI_TRANSMIT { - pxenv_status_t Status; - uint8_t Protocol; -#define P_UNKNOWN 0 -#define P_IP 1 -#define P_ARP 2 -#define P_RARP 3 - uint8_t XmitFlag; -#define XMT_DESTADDR 0x0000 -#define XMT_BROADCAST 0x0001 - segoff16_t DestAddr; - segoff16_t TBD; - uint32_t Reserved[2]; -} __packed t_PXENV_UNDI_TRANSMIT; -#define MAX_DATA_BLKS 8 -typedef struct s_PXENV_UNDI_TBD { - uint16_t ImmedLength; - segoff16_t Xmit; - uint16_t DataBlkCount; - struct DataBlk { - uint8_t TDPtrType; - uint8_t TDRsvdByte; - uint16_t TDDataLen; - segoff16_t TDDataPtr; - } DataBlock[MAX_DATA_BLKS]; -} __packed t_PXENV_UNDI_TBD; - -typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS { - pxenv_status_t Status; - t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; -} __packed t_PXENV_UNDI_SET_MCAST_ADDR; - -typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS { - pxenv_status_t Status; - mac_addr_t StationAddress; -} __packed t_PXENV_UNDI_SET_STATION_ADDR; - -typedef struct s_PXENV_UNDI_SET_PACKET_FILTER { - pxenv_status_t Status; - uint8_t filter; -} __packed t_PXENV_UNDI_SET_PACKET_FILTER; - -typedef struct s_PXENV_UNDI_GET_INFORMATION { - pxenv_status_t Status; - uint16_t BaseIo; - uint16_t IntNumber; - uint16_t MaxTranUnit; - uint16_t HwType; -#define ETHER_TYPE 1 -#define EXP_ETHER_TYPE 2 -#define IEEE_TYPE 6 -#define ARCNET_TYPE 7 - uint16_t HwAddrLen; - mac_addr_t CurrentNodeAddress; - mac_addr_t PermNodeAddress; - uint16_t ROMAddress; - uint16_t RxBufCt; - uint16_t TxBufCt; -} __packed t_PXENV_UNDI_GET_INFORMATION; - -typedef struct s_PXENV_UNDI_GET_STATISTICS { - pxenv_status_t Status; - uint32_t XmtGoodFrames; - uint32_t RcvGoodFrames; - uint32_t RcvCRCErrors; - uint32_t RcvResourceErrors; -} __packed t_PXENV_UNDI_GET_STATISTICS; - -typedef struct s_PXENV_UNDI_CLEAR_STATISTICS { - pxenv_status_t Status; -} __packed t_PXENV_UNDI_CLEAR_STATISTICS; - -typedef struct s_PXENV_UNDI_INITIATE_DIAGS { - pxenv_status_t Status; -} __packed t_PXENV_UNDI_INITIATE_DIAGS; - -typedef struct s_PXENV_UNDI_FORCE_INTERRUPT { - pxenv_status_t Status; -} __packed t_PXENV_UNDI_FORCE_INTERRUPT; - -typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS { - pxenv_status_t Status; - in_addr_t InetAddr; - mac_addr_t MediaAddr; -} __packed t_PXENV_UNDI_GET_MCAST_ADDR; - -typedef struct s_PXENV_UNDI_GET_NIC_TYPE { - pxenv_status_t Status; - uint8_t NicType; -#define PCI_NIC 2 -#define PnP_NIC 3 -#define CardBus_NIC 4 - union { - struct { - uint16_t Vendor_ID; - uint16_t Dev_ID; - uint8_t Base_Class; - uint8_t Sub_Class; - uint8_t Prog_Intf; - uint8_t Rev; - uint16_t BusDevFunc; - uint16_t SubVendor_ID; - uint16_t SubDevice_ID; - } pci, cardbus; - struct { - uint32_t EISA_Dev_ID; - uint8_t Base_Class; - uint8_t Sub_Class; - uint8_t Prog_Intf; - uint16_t CardSelNum; - } __packed pnp; - } __packed info; -} __packed t_PXENV_UNDI_GET_NIC_TYPE; - -typedef struct s_PXENV_UNDI_GET_IFACE_INFO { - pxenv_status_t Status; - uint8_t IfaceType[16]; - uint32_t LinkSpeed; - uint32_t ServiceFlags; - uint32_t Reserved[4]; -} __packed t_PXENV_UNDI_GET_NDIS_INFO; - -typedef struct s_PXENV_UNDI_GET_STATE { -#define PXE_UNDI_GET_STATE_STARTED 1 -#define PXE_UNDI_GET_STATE_INITIALIZED 2 -#define PXE_UNDI_GET_STATE_OPENED 3 - pxenv_status_t Status; - uint8_t UNDIstate; -} __packed t_PXENV_UNDI_GET_STATE; - -typedef struct s_PXENV_UNDI_ISR { - pxenv_status_t Status; - uint16_t FuncFlag; - uint16_t BufferLength; - uint16_t FrameLength; - uint16_t FrameHeaderLength; - segoff16_t Frame; - uint8_t ProtType; - uint8_t PktType; -} __packed t_PXENV_UNDI_ISR; -#define PXENV_UNDI_ISR_IN_START 1 -#define PXENV_UNDI_ISR_IN_PROCESS 2 -#define PXENV_UNDI_ISR_IN_GET_NEXT 3 -/* One of these will be returned for - PXENV_UNDI_ISR_IN_START */ -#define PXENV_UNDI_ISR_OUT_OURS 0 -#define PXENV_UNDI_USR_OUT_NOT_OURS 1 -/* One of these will be returned for - PXENV_UNDI_ISR_IN_PROCESS and - PXENV_UNDI_ISR_IN_GET_NEXT */ -#define PXENV_UNDI_ISR_OUT_DONE 0 -#define PXENV_UNDI_ISR_OUT_TRANSMIT 2 -#define PXENV_UNDI_ISR_OUT_RECEIVE 3 -#define PXENV_UNDI_ISR_OUT_BUSY 4 - -/* Function numbers and error codes */ - -#define PXENV_TFTP_OPEN 0x0020 -#define PXENV_TFTP_CLOSE 0x0021 -#define PXENV_TFTP_READ 0x0022 -#define PXENV_TFTP_READ_FILE 0x0023 -#define PXENV_TFTP_READ_FILE_PMODE 0x0024 -#define PXENV_TFTP_GET_FSIZE 0x0025 - -#define PXENV_UDP_OPEN 0x0030 -#define PXENV_UDP_CLOSE 0x0031 -#define PXENV_UDP_READ 0x0032 -#define PXENV_UDP_WRITE 0x0033 - -#define PXENV_START_UNDI 0x0000 -#define PXENV_UNDI_STARTUP 0x0001 -#define PXENV_UNDI_CLEANUP 0x0002 -#define PXENV_UNDI_INITIALIZE 0x0003 -#define PXENV_UNDI_RESET_NIC 0x0004 -#define PXENV_UNDI_SHUTDOWN 0x0005 -#define PXENV_UNDI_OPEN 0x0006 -#define PXENV_UNDI_CLOSE 0x0007 -#define PXENV_UNDI_TRANSMIT 0x0008 -#define PXENV_UNDI_SET_MCAST_ADDR 0x0009 -#define PXENV_UNDI_SET_STATION_ADDR 0x000A -#define PXENV_UNDI_SET_PACKET_FILTER 0x000B -#define PXENV_UNDI_GET_INFORMATION 0x000C -#define PXENV_UNDI_GET_STATISTICS 0x000D -#define PXENV_UNDI_CLEAR_STATISTICS 0x000E -#define PXENV_UNDI_INITIATE_DIAGS 0x000F -#define PXENV_UNDI_FORCE_INTERRUPT 0x0010 -#define PXENV_UNDI_GET_MCAST_ADDR 0x0011 -#define PXENV_UNDI_GET_NIC_TYPE 0x0012 -#define PXENV_UNDI_GET_IFACE_INFO 0x0013 -#define PXENV_UNDI_ISR 0x0014 -#define PXENV_STOP_UNDI 0x0015 /* Overlap...? */ -#define PXENV_UNDI_GET_STATE 0x0015 /* Overlap...? */ - -#define PXENV_UNLOAD_STACK 0x0070 -#define PXENV_GET_CACHED_INFO 0x0071 -#define PXENV_RESTART_DHCP 0x0072 -#define PXENV_RESTART_TFTP 0x0073 -#define PXENV_MODE_SWITCH 0x0074 -#define PXENV_START_BASE 0x0075 -#define PXENV_STOP_BASE 0x0076 - -#define PXENV_EXIT_SUCCESS 0x0000 -#define PXENV_EXIT_FAILURE 0x0001 - -#define PXENV_STATUS_SUCCESS 0x00 -#define PXENV_STATUS_FAILURE 0x01 -#define PXENV_STATUS_BAD_FUNC 0x02 -#define PXENV_STATUS_UNSUPPORTED 0x03 -#define PXENV_STATUS_KEEP_UNDI 0x04 -#define PXENV_STATUS_KEEP_ALL 0x05 -#define PXENV_STATUS_OUT_OF_RESOURCES 0x06 -#define PXENV_STATUS_ARP_TIMEOUT 0x11 -#define PXENV_STATUS_UDP_CLOSED 0x18 -#define PXENV_STATUS_UDP_OPEN 0x19 -#define PXENV_STATUS_TFTP_CLOSED 0x1A -#define PXENV_STATUS_TFTP_OPEN 0x1B -#define PXENV_STATUS_MCOPY_PROBLEM 0x20 -#define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21 -#define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22 -#define PXENV_STATUS_BIS_INIT_FAILURE 0x23 -#define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24 -#define PXENV_STATUS_BIS_GBOA_FAILURE 0x25 -#define PXENV_STATUS_BIS_FREE_FAILURE 0x26 -#define PXENV_STATUS_BIS_GSI_FAILURE 0x27 -#define PXENV_STATUS_BIS_BAD_CKSUM 0x28 -#define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30 -#define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32 - -#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 -#define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 -#define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 -#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38 -#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39 -#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3A -#define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B -#define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C -#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D -#define PXENV_STATUS_TFTP_NO_FILESIZE 0x3E -#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3F -#define PXENV_STATUS_DHCP_TIMEOUT 0x51 -#define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 -#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 -#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54 -#define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 -#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 -#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62 -#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63 -#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64 -#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65 -#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66 -#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 -#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68 -#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69 -#define PXENV_STATUS_UNDI_INVALID_STATE 0x6A -#define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6B -#define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6C -#define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 -#define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 -#define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 -#define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 -#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79 -#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xA0 -#define PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1 -#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xA2 -#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xA3 -#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xB0 -#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xC0 -#define PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1 -#define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2 -#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xC3 -#define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4 -#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5 -#define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xC6 -#define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8 -#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xC9 -#define PXENV_STATUS_LOADER_UNDI_START 0xCA -#define PXENV_STATUS_LOADER_BC_START 0xCB +#include <syslinux/pxe_api.h> /* SYSLINUX-defined PXE utility functions */ -int pxe_get_cached_info(int level, void **buf, size_t * len); +int pxe_get_cached_info(int level, void **buf, size_t *len); int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE * gnt); #endif /* _SYSLINUX_PXE_H */ diff --git a/com32/include/syslinux/pxe_api.h b/com32/include/syslinux/pxe_api.h new file mode 100644 index 00000000..5fd102ef --- /dev/null +++ b/com32/include/syslinux/pxe_api.h @@ -0,0 +1,531 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * syslinux/pxe_api.h + * + * PXE type and constant definitions for SYSLINUX + */ + +#ifndef _SYSLINUX_PXE_API_H +#define _SYSLINUX_PXE_API_H + +#include <stdint.h> +#include <netinet/in.h> +#include <klibc/compiler.h> +#include <com32.h> + +/* PXE spec structures and definitions. These mostly follow the PXE + spec, except when the PXE spec is unnecessarily stupid. Of course, + that is most of the time. */ + +/* Basic types; use Unix-like _t convention instead of SCREAMING; also + re-use types we already have, like in_addr_t. */ + +typedef uint16_t pxenv_status_t; + +#define MAC_ADDR_LEN 16 +typedef uint8_t mac_addr_t[MAC_ADDR_LEN]; + +/* "Protected mode segment descriptor" according to PXE... */ +typedef struct { + uint16_t sel; + uint32_t base; + uint16_t size; +} __packed pxe_segdesc_t; + +typedef far_ptr_t segoff16_t; + +typedef struct { + uint8_t opcode; +#define BOOTP_REQ 1 +#define BOOTP_REP 2 + uint8_t Hardware; + uint8_t Hardlen; + uint8_t Gatehops; + uint32_t ident; + uint16_t seconds; + uint16_t Flags; +#define BOOTP_BCAST 0x8000 + in_addr_t cip; /* Client IP address */ + in_addr_t yip; /* You IP address */ + in_addr_t sip; /* next server IP address */ + in_addr_t gip; /*relay agent IP address */ + mac_addr_t CAddr; + uint8_t Sname[64]; + uint8_t bootfile[128]; + union { +#define BOOTP_DHCPVEND 1024 + uint8_t d[BOOTP_DHCPVEND]; + struct { + uint8_t magic[4]; +#define VM_RFC1048 0x63825363L + uint32_t flags; + uint8_t pad[56]; + } v; + } vendor; +} __packed pxe_bootp_t; + +/* Function calling structures and constants */ + +typedef struct s_PXENV_GET_CACHED_INFO { + pxenv_status_t Status; + uint16_t PacketType; +#define PXENV_PACKET_TYPE_DHCP_DISCOVER 1 +#define PXENV_PACKET_TYPE_DHCP_ACK 2 +#define PXENV_PACKET_TYPE_CACHED_REPLY 3 + uint16_t BufferSize; + segoff16_t Buffer; + uint16_t BufferLimit; +} __packed t_PXENV_GET_CACHED_INFO; + +typedef struct s_PXENV_START_UNDI { + pxenv_status_t Status; + uint16_t AX; + uint16_t BX; + uint16_t DX; + uint16_t DI; + uint16_t ES; +} __packed t_PXENV_START_UNDI; + +typedef struct s_PXENV_STOP_UNDI { + pxenv_status_t Status; +} __packed t_PXENV_STOP_UNDI; + +typedef struct s_PXENV_START_BASE { + pxenv_status_t Status; +} __packed t_PXENV_START_BASE; + +typedef struct s_PXENV_STOP_BASE { + pxenv_status_t Status; +} __packed t_PXENV_STOP_BASE; + +typedef struct s_PXENV_TFTP_OPEN { + pxenv_status_t Status; + in_addr_t ServerIPAddress; + in_addr_t GatewayIPAddress; + uint8_t FileName[128]; + in_port_t TFTPPort; + uint16_t PacketSize; +} __packed t_PXENV_TFTP_OPEN; + +typedef struct s_PXENV_TFTP_CLOSE { + pxenv_status_t Status; +} __packed t_PXENV_TFTP_CLOSE; + +typedef struct s_PXENV_TFTP_READ { + pxenv_status_t Status; + uint16_t PacketNumber; + uint16_t BufferSize; + segoff16_t Buffer; +} __packed t_PXENV_TFTP_READ; + +typedef struct s_PXENV_TFTP_READ_FILE { + pxenv_status_t Status; + uint8_t FileName[128]; + uint32_t BufferSize; + void *Buffer; + in_addr_t ServerIPAddress; + in_addr_t GatewayIPAddress; + in_addr_t McastIPAddress; + in_port_t TFTPClntPort; + in_port_t TFTPSrvPort; + uint16_t TFTPOpenTimeOut; + uint16_t TFTPReopenDelay; +} __packed t_PXENV_TFTP_READ_FILE; + +typedef struct s_PXENV_TFTP_GET_FSIZE { + pxenv_status_t Status; + in_addr_t ServerIPAddress; + in_addr_t GatewayIPAddress; + uint8_t FileName[128]; + uint32_t FileSize; +} __packed t_PXENV_TFTP_GET_FSIZE; + +typedef struct s_PXENV_UDP_OPEN { + pxenv_status_t status; + in_addr_t src_ip; +} __packed t_PXENV_UDP_OPEN; + +typedef struct s_PXENV_UDP_CLOSE { + pxenv_status_t status; +} __packed t_PXENV_UDP_CLOSE; + +typedef struct s_PXENV_UDP_WRITE { + pxenv_status_t status; + in_addr_t ip; + in_addr_t gw; + in_port_t src_port; + in_port_t dst_port; + uint16_t buffer_size; + segoff16_t buffer; +} __packed t_PXENV_UDP_WRITE; + +typedef struct s_PXENV_UDP_READ { + pxenv_status_t status; + in_addr_t src_ip; + in_addr_t dest_ip; + in_port_t s_port; + in_port_t d_port; + uint16_t buffer_size; + segoff16_t buffer; +} __packed t_PXENV_UDP_READ; + +typedef struct s_PXENV_UNDI_STARTUP { + pxenv_status_t Status; +} __packed t_PXENV_UNDI_STARTUP; + +typedef struct s_PXENV_UNDI_CLEANUP { + pxenv_status_t Status; +} __packed t_PXENV_UNDI_CLEANUP; + +typedef struct s_PXENV_UNDI_INITIALIZE { + pxenv_status_t Status; + void *ProtocolIni; + uint8_t reserved[8]; +} __packed t_PXENV_UNDI_INITIALIZE; + +#define MAXNUM_MCADDR 8 +typedef struct s_PXENV_UNDI_MCAST_ADDRESS { + uint16_t MCastAddrCount; + mac_addr_t McastAddr[MAXNUM_MCADDR]; +} __packed t_PXENV_UNDI_MCAST_ADDRESS; + +typedef struct s_PXENV_UNDI_RESET { + pxenv_status_t Status; + t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; +} __packed t_PXENV_UNDI_RESET; + +typedef struct s_PXENV_UNDI_SHUTDOWN { + pxenv_status_t Status; +} __packed t_PXENV_UNDI_SHUTDOWN; + +typedef struct s_PXENV_UNDI_OPEN { + pxenv_status_t Status; + uint16_t OpenFlag; + uint16_t PktFilter; +#define FLTR_DIRECTED 0x0001 +#define FLTR_BRDCST 0x0002 +#define FLTR_PRMSCS 0x0004 +#define FLTR_SRC_RTG 0x0008 + t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; +} __packed t_PXENV_UNDI_OPEN; + +typedef struct s_PXENV_UNDI_CLOSE { + pxenv_status_t Status; +} __packed t_PXENV_UNDI_CLOSE; + +typedef struct s_PXENV_UNDI_TRANSMIT { + pxenv_status_t Status; + uint8_t Protocol; +#define P_UNKNOWN 0 +#define P_IP 1 +#define P_ARP 2 +#define P_RARP 3 + uint8_t XmitFlag; +#define XMT_DESTADDR 0x0000 +#define XMT_BROADCAST 0x0001 + segoff16_t DestAddr; + segoff16_t TBD; + uint32_t Reserved[2]; +} __packed t_PXENV_UNDI_TRANSMIT; +#define MAX_DATA_BLKS 8 +typedef struct s_PXENV_UNDI_TBD { + uint16_t ImmedLength; + segoff16_t Xmit; + uint16_t DataBlkCount; + struct DataBlk { + uint8_t TDPtrType; + uint8_t TDRsvdByte; + uint16_t TDDataLen; + segoff16_t TDDataPtr; + } DataBlock[MAX_DATA_BLKS]; +} __packed t_PXENV_UNDI_TBD; + +typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS { + pxenv_status_t Status; + t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; +} __packed t_PXENV_UNDI_SET_MCAST_ADDR; + +typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS { + pxenv_status_t Status; + mac_addr_t StationAddress; +} __packed t_PXENV_UNDI_SET_STATION_ADDR; + +typedef struct s_PXENV_UNDI_SET_PACKET_FILTER { + pxenv_status_t Status; + uint8_t filter; +} __packed t_PXENV_UNDI_SET_PACKET_FILTER; + +typedef struct s_PXENV_UNDI_GET_INFORMATION { + pxenv_status_t Status; + uint16_t BaseIo; + uint16_t IntNumber; + uint16_t MaxTranUnit; + uint16_t HwType; +#define ETHER_TYPE 1 +#define EXP_ETHER_TYPE 2 +#define IEEE_TYPE 6 +#define ARCNET_TYPE 7 + uint16_t HwAddrLen; + mac_addr_t CurrentNodeAddress; + mac_addr_t PermNodeAddress; + uint16_t ROMAddress; + uint16_t RxBufCt; + uint16_t TxBufCt; +} __packed t_PXENV_UNDI_GET_INFORMATION; + +typedef struct s_PXENV_UNDI_GET_STATISTICS { + pxenv_status_t Status; + uint32_t XmtGoodFrames; + uint32_t RcvGoodFrames; + uint32_t RcvCRCErrors; + uint32_t RcvResourceErrors; +} __packed t_PXENV_UNDI_GET_STATISTICS; + +typedef struct s_PXENV_UNDI_CLEAR_STATISTICS { + pxenv_status_t Status; +} __packed t_PXENV_UNDI_CLEAR_STATISTICS; + +typedef struct s_PXENV_UNDI_INITIATE_DIAGS { + pxenv_status_t Status; +} __packed t_PXENV_UNDI_INITIATE_DIAGS; + +typedef struct s_PXENV_UNDI_FORCE_INTERRUPT { + pxenv_status_t Status; +} __packed t_PXENV_UNDI_FORCE_INTERRUPT; + +typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS { + pxenv_status_t Status; + in_addr_t InetAddr; + mac_addr_t MediaAddr; +} __packed t_PXENV_UNDI_GET_MCAST_ADDR; + +typedef struct s_PXENV_UNDI_GET_NIC_TYPE { + pxenv_status_t Status; + uint8_t NicType; +#define PCI_NIC 2 +#define PnP_NIC 3 +#define CardBus_NIC 4 + union { + struct { + uint16_t Vendor_ID; + uint16_t Dev_ID; + uint8_t Base_Class; + uint8_t Sub_Class; + uint8_t Prog_Intf; + uint8_t Rev; + uint16_t BusDevFunc; + uint16_t SubVendor_ID; + uint16_t SubDevice_ID; + } pci, cardbus; + struct { + uint32_t EISA_Dev_ID; + uint8_t Base_Class; + uint8_t Sub_Class; + uint8_t Prog_Intf; + uint16_t CardSelNum; + } __packed pnp; + } __packed info; +} __packed t_PXENV_UNDI_GET_NIC_TYPE; + +typedef struct s_PXENV_UNDI_GET_IFACE_INFO { + pxenv_status_t Status; + uint8_t IfaceType[16]; + uint32_t LinkSpeed; + uint32_t ServiceFlags; + uint32_t Reserved[4]; +} __packed t_PXENV_UNDI_GET_NDIS_INFO; + +typedef struct s_PXENV_UNDI_GET_STATE { +#define PXE_UNDI_GET_STATE_STARTED 1 +#define PXE_UNDI_GET_STATE_INITIALIZED 2 +#define PXE_UNDI_GET_STATE_OPENED 3 + pxenv_status_t Status; + uint8_t UNDIstate; +} __packed t_PXENV_UNDI_GET_STATE; + +typedef struct s_PXENV_UNDI_ISR { + pxenv_status_t Status; + uint16_t FuncFlag; + uint16_t BufferLength; + uint16_t FrameLength; + uint16_t FrameHeaderLength; + segoff16_t Frame; + uint8_t ProtType; + uint8_t PktType; +} __packed t_PXENV_UNDI_ISR; +#define PXENV_UNDI_ISR_IN_START 1 +#define PXENV_UNDI_ISR_IN_PROCESS 2 +#define PXENV_UNDI_ISR_IN_GET_NEXT 3 +/* One of these will be returned for + PXENV_UNDI_ISR_IN_START */ +#define PXENV_UNDI_ISR_OUT_OURS 0 +#define PXENV_UNDI_USR_OUT_NOT_OURS 1 +/* One of these will be returned for + PXENV_UNDI_ISR_IN_PROCESS and + PXENV_UNDI_ISR_IN_GET_NEXT */ +#define PXENV_UNDI_ISR_OUT_DONE 0 +#define PXENV_UNDI_ISR_OUT_TRANSMIT 2 +#define PXENV_UNDI_ISR_OUT_RECEIVE 3 +#define PXENV_UNDI_ISR_OUT_BUSY 4 + +/* Function numbers and error codes */ + +#define PXENV_TFTP_OPEN 0x0020 +#define PXENV_TFTP_CLOSE 0x0021 +#define PXENV_TFTP_READ 0x0022 +#define PXENV_TFTP_READ_FILE 0x0023 +#define PXENV_TFTP_READ_FILE_PMODE 0x0024 +#define PXENV_TFTP_GET_FSIZE 0x0025 + +#define PXENV_UDP_OPEN 0x0030 +#define PXENV_UDP_CLOSE 0x0031 +#define PXENV_UDP_READ 0x0032 +#define PXENV_UDP_WRITE 0x0033 + +#define PXENV_START_UNDI 0x0000 +#define PXENV_UNDI_STARTUP 0x0001 +#define PXENV_UNDI_CLEANUP 0x0002 +#define PXENV_UNDI_INITIALIZE 0x0003 +#define PXENV_UNDI_RESET_NIC 0x0004 +#define PXENV_UNDI_SHUTDOWN 0x0005 +#define PXENV_UNDI_OPEN 0x0006 +#define PXENV_UNDI_CLOSE 0x0007 +#define PXENV_UNDI_TRANSMIT 0x0008 +#define PXENV_UNDI_SET_MCAST_ADDR 0x0009 +#define PXENV_UNDI_SET_STATION_ADDR 0x000A +#define PXENV_UNDI_SET_PACKET_FILTER 0x000B +#define PXENV_UNDI_GET_INFORMATION 0x000C +#define PXENV_UNDI_GET_STATISTICS 0x000D +#define PXENV_UNDI_CLEAR_STATISTICS 0x000E +#define PXENV_UNDI_INITIATE_DIAGS 0x000F +#define PXENV_UNDI_FORCE_INTERRUPT 0x0010 +#define PXENV_UNDI_GET_MCAST_ADDR 0x0011 +#define PXENV_UNDI_GET_NIC_TYPE 0x0012 +#define PXENV_UNDI_GET_IFACE_INFO 0x0013 +#define PXENV_UNDI_ISR 0x0014 +#define PXENV_STOP_UNDI 0x0015 /* Overlap...? */ +#define PXENV_UNDI_GET_STATE 0x0015 /* Overlap...? */ + +#define PXENV_UNLOAD_STACK 0x0070 +#define PXENV_GET_CACHED_INFO 0x0071 +#define PXENV_RESTART_DHCP 0x0072 +#define PXENV_RESTART_TFTP 0x0073 +#define PXENV_MODE_SWITCH 0x0074 +#define PXENV_START_BASE 0x0075 +#define PXENV_STOP_BASE 0x0076 + +/* gPXE extensions... */ +#define PXENV_FILE_OPEN 0x00e0 +#define PXENV_FILE_CLOSE 0x00e1 +#define PXENV_FILE_SELECT 0x00e2 +#define PXENV_FILE_READ 0x00e3 +#define PXENV_GET_FILE_SIZE 0x00e4 +#define PXENV_FILE_EXEC 0x00e5 +#define PXENV_FILE_API_CHECK 0x00e6 + +/* Exit codes */ +#define PXENV_EXIT_SUCCESS 0x0000 +#define PXENV_EXIT_FAILURE 0x0001 + +/* Status codes */ +#define PXENV_STATUS_SUCCESS 0x00 +#define PXENV_STATUS_FAILURE 0x01 +#define PXENV_STATUS_BAD_FUNC 0x02 +#define PXENV_STATUS_UNSUPPORTED 0x03 +#define PXENV_STATUS_KEEP_UNDI 0x04 +#define PXENV_STATUS_KEEP_ALL 0x05 +#define PXENV_STATUS_OUT_OF_RESOURCES 0x06 +#define PXENV_STATUS_ARP_TIMEOUT 0x11 +#define PXENV_STATUS_UDP_CLOSED 0x18 +#define PXENV_STATUS_UDP_OPEN 0x19 +#define PXENV_STATUS_TFTP_CLOSED 0x1a +#define PXENV_STATUS_TFTP_OPEN 0x1b +#define PXENV_STATUS_MCOPY_PROBLEM 0x20 +#define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21 +#define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22 +#define PXENV_STATUS_BIS_INIT_FAILURE 0x23 +#define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24 +#define PXENV_STATUS_BIS_GBOA_FAILURE 0x25 +#define PXENV_STATUS_BIS_FREE_FAILURE 0x26 +#define PXENV_STATUS_BIS_GSI_FAILURE 0x27 +#define PXENV_STATUS_BIS_BAD_CKSUM 0x28 +#define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30 +#define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32 + +#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 +#define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 +#define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 +#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38 +#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39 +#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3a +#define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3b +#define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3c +#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3d +#define PXENV_STATUS_TFTP_NO_FILESIZE 0x3e +#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3f +#define PXENV_STATUS_DHCP_TIMEOUT 0x51 +#define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 +#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 +#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54 +#define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 +#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 +#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62 +#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63 +#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64 +#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65 +#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66 +#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 +#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68 +#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69 +#define PXENV_STATUS_UNDI_INVALID_STATE 0x6a +#define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6b +#define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6c +#define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 +#define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 +#define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 +#define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 +#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79 +#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xa0 +#define PXENV_STATUS_BINL_NO_PXE_SERVER 0xa1 +#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xa2 +#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xa3 +#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xb0 +#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xc0 +#define PXENV_STATUS_LOADER_NO_BC_ROMID 0xc1 +#define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xc2 +#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xc3 +#define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xc4 +#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xc5 +#define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xc6 +#define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xc8 +#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xc9 +#define PXENV_STATUS_LOADER_UNDI_START 0xca +#define PXENV_STATUS_LOADER_BC_START 0xcb + +#endif /* _SYSLINUX_PXE_API_H */ diff --git a/core/include/pxe.h b/core/include/pxe.h index 06cea0a3..1f66032e 100644 --- a/core/include/pxe.h +++ b/core/include/pxe.h @@ -1,164 +1,28 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ -/** -* ----------------------------------------------------------------------- -* -* Copyright 1999-2008 H. Peter Anvin - All Rights Reserved -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, Inc., 53 Temple Place Ste 330, -* Boston MA 02111-1307, USA; either version 2 of the License, or -* (at your option) any later version; incorporated herein by reference. -* -* ----------------------------------------------------------------------- - -* -* pxe.inc -* -* PXE opcodes -* -*/ +/* + * pxe.h + * + * PXE opcodes + * + */ #ifndef PXE_H #define PXE_H - -#define PXENV_TFTP_OPEN 0x0020 -#define PXENV_TFTP_CLOSE 0x0021 -#define PXENV_TFTP_READ 0x0022 -#define PXENV_TFTP_READ_FILE 0x0023 -#define PXENV_TFTP_READ_FILE_PMODE 0x0024 -#define PXENV_TFTP_GET_FSIZE 0x0025 - -#define PXENV_UDP_OPEN 0x0030 -#define PXENV_UDP_CLOSE 0x0031 -#define PXENV_UDP_READ 0x0032 -#define PXENV_UDP_WRITE 0x0033 - -#define PXENV_START_UNDI 0x0000 -#define PXENV_UNDI_STARTUP 0x0001 -#define PXENV_UNDI_CLEANUP 0x0002 -#define PXENV_UNDI_INITIALIZE 0x0003 -#define PXENV_UNDI_RESET_NIC 0x0004 -#define PXENV_UNDI_SHUTDOWN 0x0005 -#define PXENV_UNDI_OPEN 0x0006 -#define PXENV_UNDI_CLOSE 0x0007 -#define PXENV_UNDI_TRANSMIT 0x0008 -#define PXENV_UNDI_SET_MCAST_ADDR 0x0009 -#define PXENV_UNDI_SET_STATION_ADDR 0x000A -#define PXENV_UNDI_SET_PACKET_FILTER 0x000B -#define PXENV_UNDI_GET_INFORMATION 0x000C -#define PXENV_UNDI_GET_STATISTICS 0x000D -#define PXENV_UNDI_CLEAR_STATISTICS 0x000E -#define PXENV_UNDI_INITIATE_DIAGS 0x000F -#define PXENV_UNDI_FORCE_INTERRUPT 0x0010 -#define PXENV_UNDI_GET_MCAST_ADDR 0x0011 -#define PXENV_UNDI_GET_NIC_TYPE 0x0012 -#define PXENV_UNDI_GET_IFACE_INFO 0x0013 -#define PXENV_UNDI_ISR 0x0014 -#define PXENV_STOP_UNDI 0x0015 -#define PXENV_UNDI_GET_STATE 0x0015 - -#define PXENV_UNLOAD_STACK 0x0070 -#define PXENV_GET_CACHED_INFO 0x0071 -#define PXENV_RESTART_DHCP 0x0072 -#define PXENV_RESTART_TFTP 0x0073 -#define PXENV_MODE_SWITCH 0x0074 -#define PXENV_START_BASE 0x0075 -#define PXENV_STOP_BASE 0x0076 - -/* gPXE extensions... */ -#define PXENV_FILE_OPEN 0x00e0 -#define PXENV_FILE_CLOSE 0x00e1 -#define PXENV_FILE_SELECT 0x00e2 -#define PXENV_FILE_READ 0x00e3 -#define PXENV_GET_FILE_SIZE 0x00e4 -#define PXENV_FILE_EXEC 0x00e5 -#define PXENV_FILE_API_CHECK 0x00e6 - -/* Exit codes */ -#define PXENV_EXIT_SUCCESS 0x0000 -#define PXENV_EXIT_FAILURE 0x0001 - -/* Status codes */ -#define PXENV_STATUS_SUCCESS 0x00 -#define PXENV_STATUS_FAILURE 0x01 -#define PXENV_STATUS_BAD_FUNC 0x02 -#define PXENV_STATUS_UNSUPPORTED 0x03 -#define PXENV_STATUS_KEEP_UNDI 0x04 -#define PXENV_STATUS_KEEP_ALL 0x05 -#define PXENV_STATUS_OUT_OF_RESOURCES 0x06 -#define PXENV_STATUS_ARP_TIMEOUT 0x11 -#define PXENV_STATUS_UDP_CLOSED 0x18 -#define PXENV_STATUS_UDP_OPEN 0x19 -#define PXENV_STATUS_TFTP_CLOSED 0x1a -#define PXENV_STATUS_TFTP_OPEN 0x1b -#define PXENV_STATUS_MCOPY_PROBLEM 0x20 -#define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21 -#define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22 -#define PXENV_STATUS_BIS_INIT_FAILURE 0x23 -#define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24 -#define PXENV_STATUS_BIS_GBOA_FAILURE 0x25 -#define PXENV_STATUS_BIS_FREE_FAILURE 0x26 -#define PXENV_STATUS_BIS_GSI_FAILURE 0x27 -#define PXENV_STATUS_BIS_BAD_CKSUM 0x28 -#define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30 -#define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32 - -#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 -#define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 -#define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 -#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38 -#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39 -#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3a -#define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3b -#define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3c -#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3d -#define PXENV_STATUS_TFTP_NO_FILESIZE 0x3e -#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3f -#define PXENV_STATUS_DHCP_TIMEOUT 0x51 -#define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 -#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 -#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54 -#define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 -#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 -#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62 -#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63 -#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64 -#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65 -#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66 -#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 -#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68 -#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69 -#define PXENV_STATUS_UNDI_INVALID_STATE 0x6a -#define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6b -#define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6c -#define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 -#define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 -#define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 -#define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 -#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79 -#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xa0 -#define PXENV_STATUS_BINL_NO_PXE_SERVER 0xa1 -#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xa2 -#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xa3 -#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xb0 -#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xc0 -#define PXENV_STATUS_LOADER_NO_BC_ROMID 0xc1 -#define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xc2 -#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xc3 -#define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xc4 -#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xc5 -#define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xc6 -#define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xc8 -#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xc9 -#define PXENV_STATUS_LOADER_UNDI_START 0xca -#define PXENV_STATUS_LOADER_BC_START 0xcb - - - +#include <syslinux/pxe_api.h> /* - * some other defines + * Some basic defines... */ #define PKTBUF_SIZE (65536 / MAX_OPEN) @@ -168,11 +32,6 @@ #define DNS_MAX_SERVERS 4 #define is_digit(c) (((c) >= '0') && ((c) <= '9')) -#define htons(x) ( ( ((x) & 0xff) << 8) + ( ((x) &0xff00) >> 8) ) -#define ntohs(x) htons(x) -#define htonl(x) ( ( ((x) & 0xff) << 24) + ( ((x) & 0xff00) << 8 ) + \ - ( ((x) & 0xff0000) >> 8 ) + ( ((x) & 0xff000000) >> 24) ) -#define ntohl(x) htonl(x) /* * TFTP operation codes @@ -200,10 +59,58 @@ #define BOOTP_OPTION_MAGIC htonl(0x63825363) #define MAC_MAX 32 - /* * structures */ + +struct pxenv_t { + uint8_t signature[6]; /* PXENV+ */ + uint16_t version; + uint8_t length; + uint8_t checksum; + segoff16_t rmentry; + uint32_t pmoffset; + uint16_t pmselector; + uint16_t stackseg; + uint16_t stacksize; + uint16_t bc_codeseg; + uint16_t bc_codesize; + uint16_t bc_dataseg; + uint16_t bc_datasize; + uint16_t undidataseg; + uint16_t undidatasize; + uint16_t undicodeseg; + uint16_t undicodesize; + segoff16_t pxeptr; +} __packed; + +struct pxe_t { + uint8_t signature[4]; /* !PXE */ + uint8_t structlength; + uint8_t structcksum; + uint8_t structrev; + uint8_t _pad1; + segoff16_t undiromid; + segoff16_t baseromid; + segoff16_t entrypointsp; + segoff16_t entrypointesp; + segoff16_t statuscallout; + uint8_t _pad2; + uint8_t segdesccnt; + uint16_t firstselector; + pxe_segdesc_t seg[7]; +} __packed; + +enum pxe_segments { + PXE_Seg_Stack = 0, + PXE_Seg_UNDIData = 1, + PXE_Seg_UNDICode = 2, + PXE_Seg_UNDICodeWrite = 3, + PXE_Seg_BC_Data = 4, + PXE_Seg_BC_Code = 5, + PXE_Seg_BC_CodeWrite = 6 +}; + struct bootp_t { uint8_t opcode; /* BOOTP/DHCP "opcode" */ uint8_t hardware; /* ARP hreadware type */ @@ -302,8 +209,6 @@ struct gpxe_file_read { uint16_t buffer[2]; } __attribute__ ((packed)); - - /* * functions */ @@ -311,7 +216,4 @@ int ip_ok(uint32_t); void parse_dhcp(int); void parse_dhcp_options(void *, int, int); - - - #endif /* pxe.h */ @@ -336,7 +336,6 @@ static int pxe_get_cached_info(int type) */ static int is_url(char *url) { - while (*url) { if(! strncmp(url, "://", 3)) return 1; @@ -1251,42 +1250,43 @@ static void ip_init(void) * return 1 for success, 0 for failure. * */ -static int is_pxe(char *buf) +static int is_pxe(const void *buf) { - int i = buf[4]; + const struct pxe_t *pxe = buf; + const uint8_t *p = buf; + int i = pxe->structlength; uint8_t sum = 0; - if (memcmp(buf, "!PXE", 4) || i < 0x58) + if (i < sizeof(struct pxe_t) || + memcmp(pxe->signature, "!PXE", 4)) return 0; while (i--) - sum += *buf++; + sum += *p++; - if (sum == 0) - return 1; - else - return 0; + return sum == 0; } /** * Just like is_pxe, it checks PXENV+ structure * */ -static int is_pxenv(char *buf) +static int is_pxenv(const void *buf) { - int i = buf[8]; + const struct pxenv_t *pxenv = buf; + const uint8_t *p = buf; + int i = pxenv->length; uint8_t sum = 0; - if (memcmp(buf, "PXENV+", 6) || i < 0x28) + /* The pxeptr field isn't present in old versions */ + if (i < offsetof(struct pxenv_t, pxeptr) || + memcmp(pxenv->signature, "PXENV+", 6)) return 0; while (i--) - sum += *buf++; + sum += *p++; - if (sum == 0) - return 1; - else - return 0; + return sum == 0; } @@ -1309,29 +1309,29 @@ static int is_pxenv(char *buf) ; ********************************************************************/ -static inline int memory_scan(uint16_t seg, int (*func)(char *)) +static const void *memory_scan(uintptr_t start, int (*func)(const void *)) { - while (seg < 0xA000) { - if (func(MK_PTR(seg, 0))) - return 1; /* found it */ - seg++; + const char *ptr; + + /* Scan each 16 bytes of conventional memory before the VGA region */ + for (ptr = (const char *)start; ptr < (const char *)0xA0000; ptr += 16) { + if (func(ptr)) + return ptr; /* found it! */ + ptr += 16; } - return 0; + return NULL; } -static int memory_scan_for_pxe_struct(void) +static const struct pxe_t *memory_scan_for_pxe_struct(void) { extern uint16_t BIOS_fbm; /* Starting segment */ - uint16_t seg = BIOS_fbm << (10 - 4); - return memory_scan(seg, is_pxe); + return memory_scan(BIOS_fbm << 10, is_pxe); } -static int memory_scan_for_pxenv_struct(void) +static const struct pxenv_t *memory_scan_for_pxenv_struct(void) { - uint16_t seg = 0x1000; - - return memory_scan(seg, is_pxenv); + return memory_scan(0x10000, is_pxenv); } /* @@ -1349,11 +1349,16 @@ static int memory_scan_for_pxenv_struct(void) */ static void pxe_init(void) { + extern void pxe_int1a(void); char plan = 'A'; uint16_t seg, off; uint16_t code_seg, code_len; uint16_t data_seg, data_len; char *base = GET_PTR(InitStack); + com32sys_t regs; + const char *type; + const struct pxenv_t *pxenv; + const struct pxe_t *pxe; /* Assume API version 2.1 */ APIVer = 0x201; @@ -1361,43 +1366,39 @@ static void pxe_init(void) /* Plan A: !PXE structure as SS:[SP + 4] */ off = *(uint16_t *)(base + 48); seg = *(uint16_t *)(base + 50); - if (is_pxe(MK_PTR(seg, off))) + pxe = MK_PTR(seg, off); + if (is_pxe(pxe)) goto have_pxe; /* Plan B: PXENV+ structure at [ES:BX] */ plan++; off = *(uint16_t *)(base + 24); /* Original BX */ seg = *(uint16_t *)(base + 4); /* Original ES */ - if (is_pxenv(MK_PTR(seg, off))) + pxenv = MK_PTR(seg, off); + if (is_pxenv(pxenv)) goto have_pxenv; /* * Plan C: PXENV+ structure via INT 1Ah AX=5650h - * - * for now, we just skip it since it must be run in Real mode */ - extern void plan_c(void); plan++; -#if 0 - goto plan_D; - call16(plan_c, regs, regs); - if (((regs->eflags.l & EFLAGS_CF) == 0) && (regs->eax.w[0] == 0x564e)) { - seg = regs->es; - off = regs->ebx.w[0]; - if (is_pxenv(MK_PTR(seg, off))) + memset(®s, 0, sizeof regs); + regs.eax.w[0] = 0x5650; + call16(pxe_int1a, ®s, ®s); + if (!(regs.eflags.l & EFLAGS_CF) && (regs.eax.w[0] == 0x564e)) { + pxenv = MK_PTR(regs.es, regs.ebx.w[0]); + if (is_pxenv(pxenv)) goto have_pxenv; } - plan_D: -#endif /* Plan D: !PXE memory scan */ plan++; - if (memory_scan_for_pxe_struct()) + if ((pxe = memory_scan_for_pxe_struct())) goto have_pxe; /* Plan E: PXENV+ memory scan */ plan++; - if (memory_scan_for_pxenv_struct()) + if ((pxenv = memory_scan_for_pxenv_struct())) goto have_pxenv; /* Found nothing at all !! */ @@ -1405,59 +1406,51 @@ static void pxe_init(void) call16(kaboom, NULL, NULL); have_pxenv: - base = MK_PTR(seg, off); - APIVer = *(uint16_t *)(base + 6); + APIVer = pxenv->version; printf("Found PXENV+ structure\nPXE API version is %04x\n", APIVer); /* if the API version number is 0x0201 or higher, use the !PXE structure */ if (APIVer >= 0x201) { - if (*(char *)(base + 8) < 0x2c) { /* Length of PXENV+ structure in bytes */ - if (memory_scan_for_pxe_struct()) - goto have_pxe; - } - - off = *(uint16_t *)(base + 0x28); - seg = *(uint16_t *)(base + 0x2a); - if (is_pxe(MK_PTR(seg, off))) - goto have_pxe; - /* - * Nope, !PXE structuremissing despite API 2.1+, or at least - * the pointer is missing. Do a last-ditch attempt to find it - */ - if (memory_scan_for_pxe_struct()) - goto have_pxe; + if (pxenv->length >= sizeof(struct pxenv_t)) { + pxe = GET_PTR(pxenv->pxeptr); + if (is_pxe(pxe)) + goto have_pxe; + /* + * Nope, !PXE structure missing despite API 2.1+, or at least + * the pointer is missing. Do a last-ditch attempt to find it + */ + if ((pxe = memory_scan_for_pxe_struct())) + goto have_pxe; + } } /* Otherwise, no dice, use PXENV+ structure */ - data_len = *(uint16_t *)(base + 0x22); /* UNDI data len */ - data_seg = *(uint16_t *)(base + 0x20); /* UNDI data seg */ - code_len = *(uint16_t *)(base + 0x26); /* UNDI code len */ - code_seg = *(uint16_t *)(base + 0x24); /* UNDI code seg */ - PXEEntry = *(far_ptr_t *)(base + 0x0a); /* PXENV+ entry point */ - printf("PXENV+ entry point found (we hope) at "); + data_len = pxenv->undidatasize; + data_seg = pxenv->undidataseg; + code_len = pxenv->undicodesize; + code_seg = pxenv->undicodeseg; + PXEEntry = pxenv->rmentry; + type = "PXENV+"; goto have_entrypoint; have_pxe: - base = MK_PTR(seg, off); - - data_len = *(uint16_t *)(base + 0x2e); /* UNDI data len */ - data_seg = *(uint16_t *)(base + 0x28); /* UNDI data seg */ - code_len = *(uint16_t *)(base + 0x36); /* UNDI code len */ - code_seg = *(uint16_t *)(base + 0x30); /* UNDI code seg */ - PXEEntry = *(far_ptr_t *)(base + 0x10); /* !PXE entry point */ - printf("!PXE entry point found (we hope) at "); + data_len = pxe->seg[PXE_Seg_UNDIData].size; + data_seg = pxe->seg[PXE_Seg_UNDIData].sel; + code_len = pxe->seg[PXE_Seg_UNDICode].size; + code_seg = pxe->seg[PXE_Seg_UNDICode].sel; + PXEEntry = pxe->entrypointsp; + type = "!PXE"; have_entrypoint: - printf("%04X:%04X via plan %c\n", PXEEntry.seg, PXEEntry.offs, plan); + printf("%s entry point found (we hope) at %04X:%04X via plan %c\n", + type, PXEEntry.seg, PXEEntry.offs, plan); printf("UNDI code segment at %04X len %04X\n", code_seg, code_len); - code_seg = code_seg + ((code_len + 15) >> 4); - printf("UNDI data segment at %04X len %04X\n", data_seg, data_len); + + code_seg = code_seg + ((code_len + 15) >> 4); data_seg = data_seg + ((data_len + 15) >> 4); - - + RealBaseMem = MAX(code_seg,data_seg) >> 6; /* Convert to kilobytes */ - //regs->es = regs->ds; /* Restore the es segment */ } /* diff --git a/core/pxelinux.asm b/core/pxelinux.asm index b8077fd9..06e52061 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -290,29 +290,8 @@ _start1: extern pxe_fs_ops mov eax,pxe_fs_ops pm_call fs_init - jmp next ; -; Plan C, because it must be in real mode, we set it here -; - global plan_c -plan_c: - - ; Plan C: PXENV+ structure via INT 1Ah AX=5650h - mov ax, 5650h -%if USE_PXE_PROVIDED_STACK == 0 - lss sp,[InitStack] -%endif - int 1Ah ; May trash regs -%if USE_PXE_PROVIDED_STACK == 0 - lss esp,[BaseStack] -%endif - sti ; Work around Etherboot bug - ret - - -next: -; ; Common initialization code ; %include "cpuinit.inc" @@ -483,6 +462,24 @@ PXEEntry equ pxenv.jump+1 PXEStatus resb 2 + section .text16 +; +; Invoke INT 1Ah on the PXE stack. This is used by the "Plan C" method +; for finding the PXE entry point. +; + global pxe_int1a +pxe_int1a: +%if USE_PXE_PROVIDED_STACK == 0 + mov [cs:PXEStack],sp + mov [cs:PXEStack+2],ss + lss sp,[cs:InitStack] +%endif + int 1Ah ; May trash registers +%if USE_PXE_PROVIDED_STACK == 0 + lss sp,[cs:PXEStack] +%endif + ret + ; ; TimeoutTable: list of timeouts (in 18.2 Hz timer ticks) ; |