From: H. Peter Anvin Date: Mon, 30 Jun 2008 19:37:48 +0000 (-0700) Subject: gPXE: update gPXE to get rid of gpxe/src/Config X-Git-Tag: syslinux-3.70~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5d707e3005f23fb82de8f2c0d23f7e523cf9bb12;p=platform%2Fupstream%2Fsyslinux.git gPXE: update gPXE to get rid of gpxe/src/Config gpxe/src/Config versus gpxe/src/config is a problem on case-deficient filesystems; update to top of tree gPXE so we don't have that problem anymore. --- diff --git a/gpxe/src/Config b/gpxe/src/Config deleted file mode 100644 index 1c0cb1e..0000000 --- a/gpxe/src/Config +++ /dev/null @@ -1,381 +0,0 @@ -############################################################################## -############################################################################## -# -# IMPORTANT! -# -# The use of this file to set options that affect only single object -# files is deprecated, because changing anything in this file results -# in a complete rebuild, which is slow. All options are gradually -# being migrated to config.h, which does not suffer from this problem. -# -# Only options that affect the entire build (e.g. overriding the $(CC) -# Makefile variable) should be placed in here. -# -############################################################################## -############################################################################## - - -# -# Config for Etherboot/32 -# -# -# Do not delete the tag OptionDescription and /OptionDescription -# It is used to automatically generate the documentation. -# -# @OptionDescription@ -# User interaction options: -# -# -DASK_BOOT=n -# Ask "Boot from (N)etwork ... or (Q)uit? " -# at startup, timeout after n seconds (0 = no timeout). -# If unset or negative, don't ask and boot immediately -# using the default. -# -DBOOT_FIRST -# -DBOOT_SECOND -# -DBOOT_THIRD -# On timeout or Return key from previous -# question, selects the order to try to boot from -# various devices. -# (alternatives: BOOT_NIC, BOOT_DISK, -# BOOT_FLOPPY, BOOT_NOTHING) -# See etherboot.h for prompt and answer strings. -# BOOT_DISK and BOOT_FLOPPY work only where a driver -# exists, e.g. in LinuxBIOS. -# They have no effect on PCBIOS. -# -DBOOT_INDEX The device to boot from 0 == any device. -# 1 == The first nic found. -# 2 == The second nic found -# ... -# BOOT_INDEX only applies to the BOOT_FIRST. BOOT_SECOND -# and BOOT_THIRD search through all of the boot devices. -# -DBAR_PROGRESS -# Use rotating bar instead of sequential dots -# to indicate an IP packet transmitted. -# -# Boot order options: -# -# -DBOOT_CLASS_FIRST -# -DBOOT_CLASS_SECOND -# -DBOOT_CLASS_THIRD -# Select the priority of the boot classes -# Valid values are: -# BOOT_NIC -# BOOT_DISK -# BOOT_FLOPPY -# BOOT_DISK and BOOT_FLOPPY work only where a driver exists, -# e.g. in LinuxBIOS. They have no effect on PCBIOS. -# -# Boot autoconfiguration protocol options: -# -# -DALTERNATE_DHCP_PORTS_1067_1068 -# Use ports 1067 and 1068 for DHCP instead of 67 and 68. -# As these ports are non-standard, you need to configure -# your DHCP server to use them. This option gets around -# existing DHCP servers which cannot be touched, for -# one reason or another, at the cost of non-standard -# boot images. -# -DNO_DHCP_SUPPORT -# Use BOOTP instead of DHCP. -# -DRARP_NOT_BOOTP -# Use RARP instead of BOOTP/DHCP. -# -DREQUIRE_VCI_ETHERBOOT -# Require an encapsulated Vendor Class Identifier -# of "Etherboot" in the DHCP reply -# Requires DHCP support. -# -DDHCP_CLIENT_ID=\"Identifier\" -# -DDHCP_CLIENT_ID_LEN= -# -DDHCP_CLIENT_ID_TYPE= -# Specify a RFC2132 Client Identifier option, length and type. -# Requires DHCP support. -# -DDHCP_USER_CLASS=\"UserClass\" -# -DDHCP_USER_CLASS_LEN= -# Specify a RFC3004 User Class option and length. Use this -# option to set a UC (or multiple UCs) rather than munge the -# client Vendor Class ID. -# Requires DHCP support. -# -DALLOW_ONLY_ENCAPSULATED -# Ignore Etherboot-specific options that are not within -# the Etherboot encapsulated options field. This option -# should be enabled unless you have a legacy DHCP server -# configuration from the bad old days before the use of -# encapsulated Etherboot options. -# -DDEFAULT_BOOTFILE=\"default_bootfile_name\" -# Define a default bootfile for the case where your DHCP -# server does not provide the information. Example: -# -DDEFAULT_BOOTFILE="tftp:///tftpboot/kernel" -# If you do not specify this option, then DHCP offers that -# do not specify bootfiles will be ignored. -# -# NIC tuning parameters: -# -# -DALLMULTI -# Turns on multicast reception in the NICs. -# -# Boot tuning parameters: -# -# -DCONGESTED -# Turns on packet retransmission. Use it on a -# congested network, where the normal operation -# can't boot the image. -# -DBACKOFF_LIMIT -# Sets the maximum RFC951 backoff exponent to n. -# Do not set this unreasonably low, because on networks -# with many machines they can saturate the link -# (the delay corresponding to the exponent is a random -# time in the range 0..3.5*2^n seconds). Use 5 for a -# VERY small network (max. 2 minutes delay), 7 for a -# medium sized network (max. 7.5 minutes delay) or 10 -# for a really huge network with many clients, frequent -# congestions (max. 1 hour delay). On average the -# delay time will be half the maximum value. If in -# doubt about the consequences, use a larger value. -# Also keep in mind that the number of retransmissions -# is not changed by this setting, so the default of 20 -# may no longer be appropriate. You might need to set -# MAX_ARP_RETRIES, MAX_BOOTP_RETRIES, MAX_TFTP_RETRIES -# and MAX_RPC_RETRIES to a larger value. -# -DTIMEOUT=n -# Use with care!! See above. -# Sets the base of RFC2131 sleep interval to n. -# This can be used with -DBACKOFF_LIMIT=0 to get a small -# and constant (predictable) retry interval for embedded -# devices. This is to achieve short boot delays if both -# the DHCP Server and the embedded device will be powered -# on the same time. Otherwise if the DHCP server is ready -# the client could sleep the next exponentially timeout, -# e.g. 70 seconds or more. This is not what you want. -# n should be a multiple of TICKS_PER_SEC (18). -# -# Boot device options: -# -# -DTRY_FLOPPY_FIRST -# If > 0, tries that many times to read the boot -# sector from a floppy drive before booting from -# ROM. If successful, does a local boot. -# It assumes the floppy is bootable. -# -DEXIT_IF_NO_OFFER -# If no IP offer is obtained, exit and -# let the BIOS continue. -# The accessibility of the TFTP server has no effect, -# so configure your DHCP/BOOTP server properly. -# You should probably reduce MAX_BOOTP_RETRIES -# to a small number like 3. -# -# Boot image options: -# -# -DFREEBSD_KERNEL_ENV -# Pass in FreeBSD kernel environment -# -DAOUT_LYNX_KDI -# Add Lynx a.out KDI support -# -DMULTICAST_LEVEL1 -# Support for sending multicast packets -# -DMULTICAST_LEVEL2 -# Support for receiving multicast packets -# -# Interface export options: -# -# -DPXE_EXPORT -# Export a PXE API interface. This is work in -# progress. Note that you won't be able to load -# PXE NBPs unless you also use -DPXE_IMAGE. -# -DPXE_STRICT -# Strict(er) compliance with the PXE -# specification as published by Intel. This may -# or may not be a good thing depending on your -# view of the spec... -# -DPXE_DHCP_STRICT -# Strict compliance of the DHCP request packets -# with the PXE specification as published by -# Intel. This may or may not be a good thing -# depending on your view of whether requesting -# vendor options which don't actually exist is -# pointless or not. You probably want this -# option if you intend to use Windows RIS or -# similar. -# -# Obscure options you probably don't need to touch: -# -# -DZPXE_SUFFIX_STRIP -# If the last 5 characters of the filename passed to Etherboot is -# ".zpxe" then strip it off. This is useful in cases where a DHCP server -# is not able to be configured to support conditionals. The way it works -# is that the DHCP server is configured with a filename like -# "foo.nbi.zpxe" so that when PXE asks for a filename it gets that, and -# loads Etherboot from that file. Etherboot then starts up and once -# again asks the DHCP server for a filename and once again gets -# foo.nbi.zpxe, but with this option turned on loads "foo.nbi" instead. -# This allows people to use Etherboot who might not otherwise be able to -# because their DHCP servers won't let them. -# -# -DPOWERSAVE -# Halt the processor when waiting for keyboard input -# which saves power while waiting for user interaction. -# Good for compute clusters and VMware emulation. -# But may not work for all CPUs. -# -# @/OptionDescription@ - -# These default settings compile Etherboot with a small number of options. -# You may wish to enable more of the features if the size of your ROM allows. - - -# For prompting and default on timeout -# CFLAGS+= -DASK_BOOT=3 -DBOOT_FIRST=BOOT_NIC -# If you would like to attempt to boot from other devices as well as the network. -# CFLAGS+= -DBOOT_SECOND=BOOT_FLOPPY -# CFLAGS+= -DBOOT_THIRD=BOOT_DISK -# CFLAGS+= -DBOOT_INDEX=0 - -# If you prefer the old style rotating bar progress display -# CFLAGS+= -DBAR_PROGRESS - -# Show size indicator -# CFLAGS+= -DSIZEINDICATOR - -# Enabling this creates non-standard images which use ports 1067 and 1068 -# for DHCP/BOOTP -# CFLAGS+= -DALTERNATE_DHCP_PORTS_1067_1068 - -# Enabling this makes the boot ROM require a Vendor Class Identifier -# of "Etherboot" in the Vendor Encapsulated Options -# This can be used to reject replies from servers other than the one -# we want to give out addresses to us, but it will prevent Etherboot -# from getting an IP lease until you have configured DHCPD correctly -# CFLAGS+= -DREQUIRE_VCI_ETHERBOOT - -# EXPERIMENTAL! Set DHCP_CLIENT_ID to create a Client Identifier (DHCP -# option 61, see RFC2132 section 9.14) when Etherboot sends the DHCP -# DISCOVER and REQUEST packets. This ID must UNIQUELY identify each -# client on your local network. Set DHCP_CLIENT_ID_TYPE to the -# appropriate hardware type as described in RFC2132 / RFC1700; this -# almost certainly means using '1' if the Client ID is an Ethernet MAC -# address and '0' otherwise. Set DHCP_CLIENT_ID_LEN to the length of -# the Client ID in octets (this is not a null terminated C string, do -# NOT add 1 for a terminator and do NOT add an extra 1 for the -# hardware type octet). Note that to identify your client using the -# normal default MAC address of your NIC, you do NOT need to set this -# option, as the MAC address is automatically used in the -# hwtype/chaddr field; note also that this field only sets the DHCP -# option: it does NOT change the MAC address used by the client. - -# CFLAGS+= -DDHCP_CLIENT_ID="'C','L','I','E','N','T','0','0','1'" \ -# -DDHCP_CLIENT_ID_LEN=9 -DDHCP_CLIENT_ID_TYPE=0 - -# CFLAGS+= -DDHCP_CLIENT_ID="0xDE,0xAD,0xBE,0xEF,0xDE,0xAD" \ -# -DDHCP_CLIENT_ID_LEN=6 -DDHCP_CLIENT_ID_TYPE=1 - -# EXPERIMENTAL! Set DHCP_USER_CLASS to create a User Class option (see -# RFC3004) when Etherboot sends the DHCP DISCOVER and REQUEST packets. -# This can be used for classification of clients, typically so that a -# DHCP server can send an appropriately tailored reply. Normally, a -# string identifies a class of to which this client instance belongs -# which is useful in your network, such as a department ('FINANCE' or -# 'MARKETING') or hardware type ('THINCLIENT' or 'KIOSK'). Set -# DHCP_USER_CLASS_LEN to the length of DHCP_USER_CLASS in octets. -# This is NOT a null terminated C string, do NOT add 1 for a -# terminator. RFC3004 advises how to lay out multiple User Class -# options by using an octet for the length of each string, as in this -# example. It is, of course, up to the server to parse this. - -# CFLAGS+= -DDHCP_USER_CLASS="'T','E','S','T','C','L','A','S','S'" \ -# -DDHCP_USER_CLASS_LEN=9 - -# CFLAGS+= -DDHCP_USER_CLASS="5,'A','L','P','H','A',4,'B','E','T','A'" \ -# -DDHCP_USER_CLASS_LEN=11 - -# Enabling this causes Etherboot to ignore Etherboot-specific options -# that are not within an Etherboot encapsulated options field. -# This option should be enabled unless you have a legacy DHCP server -# configuration from the bad old days before the use of -# encapsulated Etherboot options. -# CFLAGS+= -DALLOW_ONLY_ENCAPSULATED - -# Disable DHCP support -# CFLAGS+= -DNO_DHCP_SUPPORT - -# Specify a default bootfile to be used if the DHCP server does not -# provide the information. If you do not specify this option, then -# DHCP offers that do not contain bootfiles will be ignored. -# CFLAGS+= -DDEFAULT_BOOTFILE=\"tftp:///tftpboot/kernel\" - -# Limit the delay on packet loss/congestion to a more bearable value. See -# description above. If unset, do not limit the delay between resend. -# CFLAGS+= -DBACKOFF_LIMIT=5 -DCONGESTED - -# More optional features -# CFLAGS+= -DTRY_FLOPPY_FIRST=4 -# CFLAGS+= -DEXIT_IF_NO_OFFER - - -# Multicast Support -# CFLAGS+= -DALLMULTI -DMULTICAST_LEVEL1 -DMULTICAST_LEVEL2 - -# Etherboot as a PXE network protocol ROM -# CFLAGS+= -DPXE_IMAGE -DPXE_EXPORT -# Etherboot stricter as a PXE network protocol ROM -# CFLAGS+= -DPXE_DHCP_STRICT - -# Support for PXE emulation. Works only with FreeBSD to load the kernel -# via pxeboot, use only with DOWNLOAD_PROTO_NFS -# CFLAGS+= -DFREEBSD_PXEEMU - - - -# Garbage from Makefile.main temporarily placed here until a home can -# be found for it. - -# NS8390 options: -# -DINCLUDE_NE - Include NE1000/NE2000 support -# -DNE_SCAN=list - Probe for NE base address using list of -# comma separated hex addresses -# -DINCLUDE_3C503 - Include 3c503 support -# -DT503_SHMEM - Use 3c503 shared memory mode (off by default) -# -DINCLUDE_WD - Include Western Digital/SMC support -# -DWD_DEFAULT_MEM- Default memory location for WD/SMC cards -# -DWD_790_PIO - Read/write to WD/SMC 790 cards in PIO mode (default -# is to use shared memory) Try this if you get "Bogus -# packet, ignoring" messages, common on ISA/PCI hybrid -# systems. -# -DCOMPEX_RL2000_FIX -# -# If you have a Compex RL2000 PCI 32-bit (11F6:1401), -# and the bootrom hangs in "Probing...[NE*000/PCI]", -# try enabling this fix... it worked for me :). -# In the first packet write somehow it somehow doesn't -# get back the expected data so it is stuck in a loop. -# I didn't bother to investigate what or why because it works -# when I interrupt the loop if it takes more then COMPEX_RL2000_TRIES. -# The code will notify if it does a abort. -# SomniOne - somnione@gmx.net -# -# 3C90X options: -# Warning Warning Warning -# If you use any of the XCVR options below, please do not complain about -# the behaviour with Linux drivers to the kernel developers. You are -# on your own if you do this. Please read 3c90x.txt to understand -# what they do. If you don't understand them, ask for help on the -# Etherboot mailing list. And please document what you did to the NIC -# on the NIC so that people after you won't get nasty surprises. -# -# -DCFG_3C90X_PRESERVE_XCVR - Reset the transceiver type to the value it -# had initially just before the loaded code is started. -# -DCFG_3C90X_XCVR - Hardcode the tranceiver type Etherboot uses. -# -DCFG_3C90X_BOOTROM_FIX - If you have a 3c905B with buggy ROM -# interface, setting this option might "fix" it. Use -# with caution and read the docs in 3c90x.txt! -# -# See the documentation file 3c90x.txt for more details. -# -# CS89X0 (optional) options: -# -DISA_PROBE_ADDRS=list -# Probe for CS89x0 base address using list of -# comma separated hex addresses; increasing the -# address by one (0x300 -> 0x301) will force a -# more aggressive probing algorithm. This might -# be neccessary after a soft-reset of the NIC. - - -CFLAGS_3c503 = -DINCLUDE_3C503 # -DT503_SHMEM -CFLAGS_ne = -DINCLUDE_NE -DNE_SCAN=0x300,0x280,0x320,0x340,0x380 -CFLAGS_ns8390 = -DINCLUDE_NS8390 # NE2000/PCI! -CFLAGS_wd = -DINCLUDE_WD -DWD_DEFAULT_MEM=0xCC000 diff --git a/gpxe/src/Makefile b/gpxe/src/Makefile index 26d9ee8..c30bf2b 100644 --- a/gpxe/src/Makefile +++ b/gpxe/src/Makefile @@ -68,11 +68,6 @@ noargs : blib $(BIN)/NIC $(BIN)/gpxe.dsk $(BIN)/gpxe.iso $(BIN)/gpxe.usb $(BIN)/ @$(ECHO) @$(ECHO) '===========================================================' -# Grab the central Config file. -# -MAKEDEPS += Config -include Config - # If no architecture is specified in Config or on the command-line, # use that of the build machine. # diff --git a/gpxe/src/Makefile.housekeeping b/gpxe/src/Makefile.housekeeping index 53e02e3..6cd85f7 100644 --- a/gpxe/src/Makefile.housekeeping +++ b/gpxe/src/Makefile.housekeeping @@ -30,7 +30,7 @@ install : # Check for tools that can cause failed builds # -.toolcheck : Makefile Config +.toolcheck : Makefile @if $(CC) -v 2>&1 | grep -is 'gcc version 2\.96' > /dev/null; then \ $(ECHO) 'gcc 2.96 is unsuitable for compiling Etherboot'; \ $(ECHO) 'Use gcc 2.95 or gcc 3.x instead'; \ diff --git a/gpxe/src/arch/i386/core/gdbidt.S b/gpxe/src/arch/i386/core/gdbidt.S index 45d079f..860f7b0 100644 --- a/gpxe/src/arch/i386/core/gdbidt.S +++ b/gpxe/src/arch/i386/core/gdbidt.S @@ -163,12 +163,18 @@ int_page_fault: #define IH_OFFSET_FLUX_END ( IH_OFFSET_END - 20 ) do_interrupt: /* Store CPU state in GDB register snapshot */ - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl %ss - pushl IH_OFFSET_FLUX_OLD_CS(%esp) + pushw $0 + pushw %gs + pushw $0 + pushw %fs + pushw $0 + pushw %es + pushw $0 + pushw %ds + pushw $0 + pushw %ss + pushw $0 + pushw IH_OFFSET_FLUX_OLD_CS + 2(%esp) pushl IH_OFFSET_FLUX_OLD_EFLAGS(%esp) pushl IH_OFFSET_FLUX_OLD_EIP(%esp) pushl %edi @@ -184,7 +190,7 @@ do_interrupt: /* Call GDB stub exception handler */ pushl %esp pushl (IH_OFFSET_SIGNO + 4)(%esp) - call gdbstub_handler + call gdbmach_handler addl $8, %esp /* Restore CPU state from GDB register snapshot */ diff --git a/gpxe/src/arch/i386/image/bzimage.c b/gpxe/src/arch/i386/image/bzimage.c index 38443f5..9372f55 100644 --- a/gpxe/src/arch/i386/image/bzimage.c +++ b/gpxe/src/arch/i386/image/bzimage.c @@ -414,7 +414,9 @@ static int bzimage_load_header ( struct image *image, } /* Calculate load address and size of real-mode portion */ - load_ctx->rm_kernel_seg = 0x1000; /* place RM kernel at 1000:0000 */ + load_ctx->rm_kernel_seg = ( ( bzhdr->loadflags & BZI_LOAD_HIGH ) ? + 0x1000 : /* 1000:0000 (bzImage) */ + 0x9000 ); /* 9000:0000 (zImage) */ load_ctx->rm_kernel = real_to_user ( load_ctx->rm_kernel_seg, 0 ); load_ctx->rm_filesz = ( ( bzhdr->setup_sects ? bzhdr->setup_sects : 4 ) + 1 ) << 9; diff --git a/gpxe/src/arch/i386/include/gdbmach.h b/gpxe/src/arch/i386/include/gdbmach.h index 9f6dc8f..1a38ccd 100644 --- a/gpxe/src/arch/i386/include/gdbmach.h +++ b/gpxe/src/arch/i386/include/gdbmach.h @@ -10,6 +10,8 @@ * */ +#include + typedef uint32_t gdbreg_t; /* The register snapshot, this must be in sync with interrupt handler and the @@ -35,6 +37,15 @@ enum { GDBMACH_SIZEOF_REGS = GDBMACH_NREGS * sizeof ( gdbreg_t ) }; +/* Breakpoint types */ +enum { + GDBMACH_BPMEM, + GDBMACH_BPHW, + GDBMACH_WATCH, + GDBMACH_RWATCH, + GDBMACH_AWATCH, +}; + static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) { regs [ GDBMACH_EIP ] = pc; } @@ -48,4 +59,6 @@ static inline void gdbmach_breakpoint ( void ) { __asm__ __volatile__ ( "int $3\n" ); } +extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len, int enable ); + #endif /* GDBMACH_H */ diff --git a/gpxe/src/arch/i386/prefix/lkrnprefix.S b/gpxe/src/arch/i386/prefix/lkrnprefix.S index a3774d1..59e70cd 100644 --- a/gpxe/src/arch/i386/prefix/lkrnprefix.S +++ b/gpxe/src/arch/i386/prefix/lkrnprefix.S @@ -10,8 +10,8 @@ Description: This is just a little bit of code and data that can get prepended - to an Etherboot ROM image in order to allow LILO to load the - result as if it were a Linux kernel image. + to a ROM image in order to allow bootloaders to load the result + as if it were a Linux kernel image. A real Linux kernel image consists of a one-sector boot loader (to load the image from a floppy disk), followed a few sectors @@ -21,19 +21,16 @@ contains some other parameters that aren't interesting in this case. - When LILO loads the sectors that comprise a kernel image, it doesn't - execute the code in the first sector (since that code would try to - load the image from a floppy disk.) The code in the first sector - below doesn't expect to get executed (and prints an error message - if it ever -is- executed.) LILO's only interested in knowing the - number of setup sectors advertised in the table (at offset 497 in - the first sector.) + When a bootloader loads the sectors that comprise a kernel image, + it doesn't execute the code in the first sector (since that code + would try to load the image from a floppy disk.) The code in the + first sector below doesn't expect to get executed (and prints an + error message if it ever -is- executed.) - Etherboot doesn't require much in the way of setup code. - Historically, the Linux kernel required at least 4 sectors of - setup code. Current versions of LILO look at the byte at - offset 497 in the first sector to indicate how many sectors - of setup code are contained in the image. + We don't require much in the way of setup code. Historically, the + Linux kernel required at least 4 sectors of setup code. + Therefore, at least 4 sectors must be present even though we don't + use them. */ @@ -85,15 +82,25 @@ why: .ascii "This image cannot be loaded from a floppy disk.\r\n" why_end: +/* + The following header is documented in the Linux source code at + Documentation/i386/boot.txt +*/ .org 497 setup_sects: .byte SETUPSECS root_flags: .word 0 syssize: - .word _load_size_pgh - PREFIXPGH -swap_dev: - .word 0 + .long _load_size_pgh - PREFIXPGH + + .section ".zinfo.fixup", "a" /* Compressor fixup information */ + .ascii "SUBL" + .long syssize + .long 16 + .long 0 + .previous + ram_size: .word 0 vid_mode: @@ -102,44 +109,86 @@ root_dev: .word 0 boot_flag: .word 0xAA55 - - - .org 512 - - .section ".zinfo.fixup", "a" /* Compressor fixup information */ - .ascii "SUBW" - .long syssize - .long 16 +jump: + jmp setup_code +header: + .byte 'H', 'd', 'r', 'S' +version: + .word 0x0207 /* 2.07 */ +realmode_swtch: .long 0 - .previous - -/* - We're now at the beginning of the second sector of the image - - where the setup code goes. +start_sys: + .word 0 +kernel_version: + .word 0 +type_of_loader: + .byte 0 +loadflags: + .byte 0 +setup_move_size: + .word 0 +code32_start: + .long 0 +ramdisk_image: + .long 0 +ramdisk_size: + .long 0 +bootsect_kludge: + .long 0 +heap_end_ptr: + .word 0 +pad1: + .word 0 +cmd_line_ptr: + .long 0 +initrd_addr_max: + .long 0 +kernel_alignment: + .long 0 +relocatable_kernel: + .byte 0 +pad2: + .byte 0, 0, 0 +cmdline_size: + .long 0 +hardware_subarch: + .long 0 +hardware_subarch_data: + .byte 0, 0, 0, 0, 0, 0, 0, 0 - We don't need to do too much setup for Etherboot. +/* + We don't need to do too much setup. This code gets loaded at SETUPSEG:0. It wants to start - executing the Etherboot image that's loaded at SYSSEG:0 and + executing the image that's loaded at SYSSEG:0 and whose entry point is SYSSEG:0. */ setup_code: - /* Etherboot expects to be contiguous in memory once loaded. - * LILO doesn't do this, but since we don't need any - * information that's left in the prefix, it doesn't matter: - * we just have to ensure that %cs:0000 is where the start of - * the Etherboot image *would* be. + /* We expect to be contiguous in memory once loaded. The Linux image + * boot process requires that setup code is loaded separately from + * "non-real code". Since we don't need any information that's left + * in the prefix, it doesn't matter: we just have to ensure that + * %cs:0000 is where the start of the image *would* be. */ - ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_etherboot + ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_gpxe .org PREFIXSIZE /* We're now at the beginning of the kernel proper. */ -run_etherboot: +run_gpxe: + /* Set up stack just below 0x7c00 */ + xorw %ax, %ax + movw %ax, %ss + movw $0x7c00, %sp + call install + /* Set up real-mode stack */ + movw %bx, %ss + movw $_estack16, %sp + /* Jump to .text16 segment */ pushw %ax pushw $1f diff --git a/gpxe/src/arch/i386/prefix/romprefix.S b/gpxe/src/arch/i386/prefix/romprefix.S index 1eb87c3..727cffc 100644 --- a/gpxe/src/arch/i386/prefix/romprefix.S +++ b/gpxe/src/arch/i386/prefix/romprefix.S @@ -180,7 +180,7 @@ hook_int19: popl %es:( 0x19 * 4 ) hook_bbs: /* Check for PMM */ - movw $( 0xe00 - 1 ), %bx + movw $( 0xe000 - 1 ), %bx pmm_scan: incw %bx jz no_pmm diff --git a/gpxe/src/config.h b/gpxe/src/config.h index e695b01..f43da04 100644 --- a/gpxe/src/config.h +++ b/gpxe/src/config.h @@ -163,7 +163,9 @@ #undef BUILD_ID /* Include a custom build ID string, * e.g "test-foo" */ #undef NULL_TRAP /* Attempt to catch NULL function calls */ -#undef GDBSTUB /* Remote GDB debugging */ +#undef GDBSERIAL /* Remote GDB debugging over serial */ +#undef GDBUDP /* Remote GDB debugging over UDP + * (both may be set) */ /* @END general.h */ diff --git a/gpxe/src/core/config.c b/gpxe/src/core/config.c index 018f084..4202682 100644 --- a/gpxe/src/core/config.c +++ b/gpxe/src/core/config.c @@ -195,6 +195,13 @@ REQUIRE_OBJECT ( sanboot_cmd ); #ifdef NULL_TRAP REQUIRE_OBJECT ( nulltrap ); #endif -#ifdef GDBSTUB +#ifdef GDBSERIAL REQUIRE_OBJECT ( gdbidt ); +REQUIRE_OBJECT ( gdbserial ); +REQUIRE_OBJECT ( gdbstub_cmd ); +#endif +#ifdef GDBUDP +REQUIRE_OBJECT ( gdbidt ); +REQUIRE_OBJECT ( gdbudp ); +REQUIRE_OBJECT ( gdbstub_cmd ); #endif diff --git a/gpxe/src/core/gdbstub.c b/gpxe/src/core/gdbstub.c index 213887b..bbed344 100644 --- a/gpxe/src/core/gdbstub.c +++ b/gpxe/src/core/gdbstub.c @@ -24,22 +24,24 @@ */ #include -#include #include +#include #include -#include -#include -#include +#include +#include #include "gdbmach.h" enum { - POSIX_EINVAL = 0x1c /* used to report bad arguments to GDB */ + POSIX_EINVAL = 0x1c, /* used to report bad arguments to GDB */ + SIZEOF_PAYLOAD = 256, /* buffer size of GDB payload data */ }; struct gdbstub { + struct gdb_transport *trans; + int exit_handler; /* leave interrupt handler */ + int signo; gdbreg_t *regs; - int exit_handler; /* leave interrupt handler */ void ( * parse ) ( struct gdbstub *stub, char ch ); uint8_t cksum1; @@ -47,10 +49,15 @@ struct gdbstub { /* Buffer for payload data when parsing a packet. Once the * packet has been received, this buffer is used to hold * the reply payload. */ - char payload [ 256 ]; - int len; + char buf [ SIZEOF_PAYLOAD + 4 ]; /* $...PAYLOAD...#XX */ + char *payload; /* start of payload */ + int len; /* length of payload */ }; +/* Transports */ +static struct gdb_transport gdb_transport_start[0] __table_start ( struct gdb_transport, gdb_transports ); +static struct gdb_transport gdb_transport_end[0] __table_end ( struct gdb_transport, gdb_transports ); + /* Packet parser states */ static void gdbstub_state_new ( struct gdbstub *stub, char ch ); static void gdbstub_state_data ( struct gdbstub *stub, char ch ); @@ -67,20 +74,60 @@ static uint8_t gdbstub_to_hex_digit ( uint8_t b ) { return ( b < 0xa ? '0' : 'a' - 0xa ) + b; } -static void gdbstub_from_hex_buf ( char *dst, char *src, int len ) { - while ( len-- > 0 ) { - *dst = gdbstub_from_hex_digit ( *src++ ); - if ( len-- > 0 ) { - *dst = (*dst << 4) | gdbstub_from_hex_digit ( *src++ ); +/* + * To make reading/writing device memory atomic, we check for + * 2- or 4-byte aligned operations and handle them specially. + */ + +static void gdbstub_from_hex_buf ( char *dst, char *src, int lenbytes ) { + if ( lenbytes == 2 && ( ( unsigned long ) dst & 0x1 ) == 0 ) { + uint16_t i = gdbstub_from_hex_digit ( src [ 2 ] ) << 12 | + gdbstub_from_hex_digit ( src [ 3 ] ) << 8 | + gdbstub_from_hex_digit ( src [ 0 ] ) << 4 | + gdbstub_from_hex_digit ( src [ 1 ] ); + * ( uint16_t * ) dst = cpu_to_le16 ( i ); + } else if ( lenbytes == 4 && ( ( unsigned long ) dst & 0x3 ) == 0 ) { + uint32_t i = gdbstub_from_hex_digit ( src [ 6 ] ) << 28 | + gdbstub_from_hex_digit ( src [ 7 ] ) << 24 | + gdbstub_from_hex_digit ( src [ 4 ] ) << 20 | + gdbstub_from_hex_digit ( src [ 5 ] ) << 16 | + gdbstub_from_hex_digit ( src [ 2 ] ) << 12 | + gdbstub_from_hex_digit ( src [ 3 ] ) << 8 | + gdbstub_from_hex_digit ( src [ 0 ] ) << 4 | + gdbstub_from_hex_digit ( src [ 1 ] ); + * ( uint32_t * ) dst = cpu_to_le32 ( i ); + } else { + while ( lenbytes-- > 0 ) { + *dst++ = gdbstub_from_hex_digit ( src [ 0 ] ) << 4 | + gdbstub_from_hex_digit ( src [ 1 ] ); + src += 2; } - dst++; } } -static void gdbstub_to_hex_buf ( char *dst, char *src, int len ) { - while ( len-- > 0 ) { - *dst++ = gdbstub_to_hex_digit ( *src >> 4 ); - *dst++ = gdbstub_to_hex_digit ( *src++ ); +static void gdbstub_to_hex_buf ( char *dst, char *src, int lenbytes ) { + if ( lenbytes == 2 && ( ( unsigned long ) src & 0x1 ) == 0 ) { + uint16_t i = cpu_to_le16 ( * ( uint16_t * ) src ); + dst [ 0 ] = gdbstub_to_hex_digit ( i >> 4 ); + dst [ 1 ] = gdbstub_to_hex_digit ( i ); + dst [ 2 ] = gdbstub_to_hex_digit ( i >> 12 ); + dst [ 3 ] = gdbstub_to_hex_digit ( i >> 8 ); + } else if ( lenbytes == 4 && ( ( unsigned long ) src & 0x3 ) == 0 ) { + uint32_t i = cpu_to_le32 ( * ( uint32_t * ) src ); + dst [ 0 ] = gdbstub_to_hex_digit ( i >> 4 ); + dst [ 1 ] = gdbstub_to_hex_digit ( i ); + dst [ 2 ] = gdbstub_to_hex_digit ( i >> 12 ); + dst [ 3 ] = gdbstub_to_hex_digit ( i >> 8 ); + dst [ 4 ] = gdbstub_to_hex_digit ( i >> 20 ); + dst [ 5 ] = gdbstub_to_hex_digit ( i >> 16); + dst [ 6 ] = gdbstub_to_hex_digit ( i >> 28 ); + dst [ 7 ] = gdbstub_to_hex_digit ( i >> 24 ); + } else { + while ( lenbytes-- > 0 ) { + *dst++ = gdbstub_to_hex_digit ( *src >> 4 ); + *dst++ = gdbstub_to_hex_digit ( *src ); + src++; + } } } @@ -92,29 +139,13 @@ static uint8_t gdbstub_cksum ( char *data, int len ) { return cksum; } -static int gdbstub_getchar ( struct gdbstub *stub ) { - if ( stub->exit_handler ) { - return -1; - } - return serial_getc(); -} - -static void gdbstub_putchar ( struct gdbstub * stub __unused, char ch ) { - serial_putc ( ch ); -} - static void gdbstub_tx_packet ( struct gdbstub *stub ) { uint8_t cksum = gdbstub_cksum ( stub->payload, stub->len ); - int i; - - gdbstub_putchar ( stub, '$' ); - for ( i = 0; i < stub->len; i++ ) { - gdbstub_putchar ( stub, stub->payload [ i ] ); - } - gdbstub_putchar ( stub, '#' ); - gdbstub_putchar ( stub, gdbstub_to_hex_digit ( cksum >> 4 ) ); - gdbstub_putchar ( stub, gdbstub_to_hex_digit ( cksum ) ); - + stub->buf [ 0 ] = '$'; + stub->buf [ stub->len + 1 ] = '#'; + stub->buf [ stub->len + 2 ] = gdbstub_to_hex_digit ( cksum >> 4 ); + stub->buf [ stub->len + 3 ] = gdbstub_to_hex_digit ( cksum ); + stub->trans->send ( stub->buf, stub->len + 4 ); stub->parse = gdbstub_state_wait_ack; } @@ -179,7 +210,7 @@ static void gdbstub_write_regs ( struct gdbstub *stub ) { gdbstub_send_errno ( stub, POSIX_EINVAL ); return; } - gdbstub_from_hex_buf ( ( char * ) stub->regs, &stub->payload [ 1 ], stub->len ); + gdbstub_from_hex_buf ( ( char * ) stub->regs, &stub->payload [ 1 ], GDBMACH_SIZEOF_REGS ); gdbstub_send_ok ( stub ); } @@ -189,7 +220,7 @@ static void gdbstub_read_mem ( struct gdbstub *stub ) { gdbstub_send_errno ( stub, POSIX_EINVAL ); return; } - args [ 1 ] = ( args [ 1 ] < sizeof stub->payload / 2 ) ? args [ 1 ] : sizeof stub->payload / 2; + args [ 1 ] = ( args [ 1 ] < SIZEOF_PAYLOAD / 2 ) ? args [ 1 ] : SIZEOF_PAYLOAD / 2; gdbstub_to_hex_buf ( stub->payload, ( char * ) args [ 0 ], args [ 1 ] ); stub->len = args [ 1 ] * 2; gdbstub_tx_packet ( stub ); @@ -204,7 +235,7 @@ static void gdbstub_write_mem ( struct gdbstub *stub ) { gdbstub_send_errno ( stub, POSIX_EINVAL ); return; } - gdbstub_from_hex_buf ( ( char * ) args [ 0 ], &stub->payload [ colon + 1 ], stub->len - colon - 1 ); + gdbstub_from_hex_buf ( ( char * ) args [ 0 ], &stub->payload [ colon + 1 ], ( stub->len - colon - 1 ) / 2 ); gdbstub_send_ok ( stub ); } @@ -218,6 +249,22 @@ static void gdbstub_continue ( struct gdbstub *stub, int single_step ) { /* Reply will be sent when we hit the next breakpoint or interrupt */ } +static void gdbstub_breakpoint ( struct gdbstub *stub ) { + unsigned long args [ 3 ]; + int enable = stub->payload [ 0 ] == 'Z' ? 1 : 0; + if ( !gdbstub_get_packet_args ( stub, args, sizeof args / sizeof args [ 0 ], NULL ) ) { + gdbstub_send_errno ( stub, POSIX_EINVAL ); + return; + } + if ( gdbmach_set_breakpoint ( args [ 0 ], args [ 1 ], args [ 2 ], enable ) ) { + gdbstub_send_ok ( stub ); + } else { + /* Not supported */ + stub->len = 0; + gdbstub_tx_packet ( stub ); + } +} + static void gdbstub_rx_packet ( struct gdbstub *stub ) { switch ( stub->payload [ 0 ] ) { case '?': @@ -235,11 +282,18 @@ static void gdbstub_rx_packet ( struct gdbstub *stub ) { case 'M': gdbstub_write_mem ( stub ); break; - case 'c': - gdbstub_continue ( stub, 0 ); + case 'c': /* Continue */ + case 'k': /* Kill */ + case 's': /* Step */ + case 'D': /* Detach */ + gdbstub_continue ( stub, stub->payload [ 0 ] == 's' ); + if ( stub->payload [ 0 ] == 'D' ) { + gdbstub_send_ok ( stub ); + } break; - case 's': - gdbstub_continue ( stub, 1 ); + case 'Z': /* Insert breakpoint */ + case 'z': /* Remove breakpoint */ + gdbstub_breakpoint ( stub ); break; default: stub->len = 0; @@ -263,7 +317,7 @@ static void gdbstub_state_data ( struct gdbstub *stub, char ch ) { stub->len = 0; /* retry new packet */ } else { /* If the length exceeds our buffer, let the checksum fail */ - if ( stub->len < ( int ) sizeof stub->payload ) { + if ( stub->len < SIZEOF_PAYLOAD ) { stub->payload [ stub->len++ ] = ch; } } @@ -282,12 +336,12 @@ static void gdbstub_state_cksum2 ( struct gdbstub *stub, char ch ) { their_cksum = stub->cksum1 + gdbstub_from_hex_digit ( ch ); our_cksum = gdbstub_cksum ( stub->payload, stub->len ); if ( their_cksum == our_cksum ) { - gdbstub_putchar ( stub, '+' ); + stub->trans->send ( "+", 1 ); if ( stub->len > 0 ) { gdbstub_rx_packet ( stub ); } } else { - gdbstub_putchar ( stub, '-' ); + stub->trans->send ( "-", 1 ); } } @@ -296,6 +350,10 @@ static void gdbstub_state_wait_ack ( struct gdbstub *stub, char ch ) { stub->parse = gdbstub_state_new; } else if ( ch == '-' ) { gdbstub_tx_packet ( stub ); /* retransmit */ + } else if ( ch == '$' ) { + /* GDB is reconnecting, drop our packet and listen to GDB */ + stub->trans->send ( "-", 1 ); + stub->parse = gdbstub_state_new; } } @@ -307,24 +365,38 @@ static struct gdbstub stub = { .parse = gdbstub_state_new }; -__cdecl void gdbstub_handler ( int signo, gdbreg_t *regs ) { - int ch; +void gdbstub_handler ( int signo, gdbreg_t *regs ) { + char packet [ SIZEOF_PAYLOAD + 4 ]; + size_t len, i; + + /* A transport must be set up */ + if ( !stub.trans ) { + return; + } + stub.signo = signo; stub.regs = regs; stub.exit_handler = 0; gdbstub_report_signal ( &stub ); - while ( ( ch = gdbstub_getchar( &stub ) ) != -1 ) { - gdbstub_parse ( &stub, ch ); + while ( !stub.exit_handler && ( len = stub.trans->recv ( packet, sizeof ( packet ) ) ) > 0 ) { + for ( i = 0; i < len; i++ ) { + gdbstub_parse ( &stub, packet [ i ] ); + } } } -/* Activity monitor to detect packets from GDB when we are not active */ -static void gdbstub_activity_step ( struct process *process __unused ) { - if ( serial_ischar() ) { - gdbmach_breakpoint(); +struct gdb_transport *find_gdb_transport ( const char *name ) { + struct gdb_transport *trans; + for ( trans = gdb_transport_start; trans < gdb_transport_end; trans++ ) { + if ( strcmp ( trans->name, name ) == 0 ) { + return trans; + } } + return NULL; } -struct process gdbstub_activity_process __permanent_process = { - .step = gdbstub_activity_step, -}; +void gdbstub_start ( struct gdb_transport *trans ) { + stub.trans = trans; + stub.payload = &stub.buf [ 1 ]; + gdbmach_breakpoint(); +} diff --git a/gpxe/src/drivers/net/ns8390.c b/gpxe/src/drivers/net/ns8390.c index c57ed7a..3461c21 100644 --- a/gpxe/src/drivers/net/ns8390.c +++ b/gpxe/src/drivers/net/ns8390.c @@ -29,6 +29,12 @@ SMC8416 PIO support added by Andrew Bettison (andrewb@zip.com.au) on 4/3/02 #if 1 +#if !defined(INCLUDE_NS8390) && !defined(INCLUDE_WD) && \ + !defined(INCLUDE_NE) && !defined(INCLUDE_3C503) + /* The driver named ns8390 is the PCI driver, often called + "PCI ne2000 clones". */ +# define INCLUDE_NS8390 1 +#endif #include "etherboot.h" #include "nic.h" diff --git a/gpxe/src/tests/gdbstub_test.S b/gpxe/src/tests/gdbstub_test.S index ee594ea..bd29383 100644 --- a/gpxe/src/tests/gdbstub_test.S +++ b/gpxe/src/tests/gdbstub_test.S @@ -1,4 +1,9 @@ .arch i386 + + .section ".data" +watch_me: + .long 0xfeedbeef + .section ".text" .code32 gdbstub_test: @@ -25,5 +30,25 @@ gdbstub_test: int $3 addl $8, %esp + /* 5. Step test */ + int $3 + nop + + /* 6. Access watch test */ + movl $0x600d0000, %ecx + movl watch_me, %eax + movl $0xbad00000, %ecx + int $3 + movl $0x600d0001, %ecx + movl %eax, watch_me + movl $0xbad00001, %ecx + int $3 + + /* 7. Write watch test */ + movl $0x600d0002, %ecx + movl %eax, watch_me + movl $0xbad00002, %ecx + int $3 + 1: jmp 1b diff --git a/gpxe/src/tests/gdbstub_test.gdb b/gpxe/src/tests/gdbstub_test.gdb index 10db863..52aa693 100644 --- a/gpxe/src/tests/gdbstub_test.gdb +++ b/gpxe/src/tests/gdbstub_test.gdb @@ -3,16 +3,16 @@ # Run: # make bin/gpxe.hd.tmp # make -# tests/gdbstub_test.gdb +# gdb +# (gdb) target remote :TCPPORT +# OR +# (gdb) target remote udp:IP:UDPPORT +# (gdb) source tests/gdbstub_test.gdb define gpxe_load_symbols file bin/gpxe.hd.tmp end -define gpxe_connect - target remote localhost:4444 -end - define gpxe_assert if $arg0 != $arg1 echo FAIL $arg2\n @@ -71,10 +71,46 @@ define gpxe_test_mem_write gpxe_assert ({char}($esp)) (char)0x99 "gpxe_test_mem_write char" end +define gpxe_test_step + c + si + gpxe_assert ({char}($eip-1)) (char)0x90 "gpxe_test_step" # nop = 0x90 +end + +define gpxe_test_awatch + awatch watch_me + + c + gpxe_assert $ecx 0x600d0000 "gpxe_test_awatch read" + if $ecx == 0x600d0000 + c + end + + c + gpxe_assert $ecx 0x600d0001 "gpxe_test_awatch write" + if $ecx == 0x600d0001 + c + end + + delete +end + +define gpxe_test_watch + watch watch_me + c + gpxe_assert $ecx 0x600d0002 "gpxe_test_watch" + if $ecx == 0x600d0002 + c + end + delete +end + gpxe_load_symbols -gpxe_connect gpxe_start_tests gpxe_test_regs_read gpxe_test_regs_write gpxe_test_mem_read gpxe_test_mem_write +gpxe_test_step +gpxe_test_awatch +gpxe_test_watch