gPXE: update gPXE to get rid of gpxe/src/Config
authorH. Peter Anvin <hpa@zytor.com>
Mon, 30 Jun 2008 19:37:48 +0000 (12:37 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 30 Jun 2008 19:37:48 +0000 (12:37 -0700)
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.

14 files changed:
gpxe/src/Config [deleted file]
gpxe/src/Makefile
gpxe/src/Makefile.housekeeping
gpxe/src/arch/i386/core/gdbidt.S
gpxe/src/arch/i386/image/bzimage.c
gpxe/src/arch/i386/include/gdbmach.h
gpxe/src/arch/i386/prefix/lkrnprefix.S
gpxe/src/arch/i386/prefix/romprefix.S
gpxe/src/config.h
gpxe/src/core/config.c
gpxe/src/core/gdbstub.c
gpxe/src/drivers/net/ns8390.c
gpxe/src/tests/gdbstub_test.S
gpxe/src/tests/gdbstub_test.gdb

diff --git a/gpxe/src/Config b/gpxe/src/Config
deleted file mode 100644 (file)
index 1c0cb1e..0000000
+++ /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=<Client ID length in octets>
-#      -DDHCP_CLIENT_ID_TYPE=<Client ID type>
-#                      Specify a RFC2132 Client Identifier option, length and type.
-#                      Requires DHCP support.
-#      -DDHCP_USER_CLASS=\"UserClass\"
-#      -DDHCP_USER_CLASS_LEN=<User Class length in octets>
-#                      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
index 26d9ee8..c30bf2b 100644 (file)
@@ -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.
 #
index 53e02e3..6cd85f7 100644 (file)
@@ -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'; \
index 45d079f..860f7b0 100644 (file)
@@ -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 */
index 38443f5..9372f55 100644 (file)
@@ -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;
index 9f6dc8f..1a38ccd 100644 (file)
@@ -10,6 +10,8 @@
  *
  */
 
+#include <stdint.h>
+
 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 */
index a3774d1..59e70cd 100644 (file)
@@ -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
        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
index 1eb87c3..727cffc 100644 (file)
@@ -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
index e695b01..f43da04 100644 (file)
 #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 */
 
index 018f084..4202682 100644 (file)
@@ -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
index 213887b..bbed344 100644 (file)
  */
 
 #include <stdlib.h>
-#include <stddef.h>
 #include <stdio.h>
+#include <string.h>
 #include <ctype.h>
-#include <assert.h>
-#include <gpxe/process.h>
-#include <gpxe/serial.h>
+#include <byteswap.h>
+#include <gpxe/gdbstub.h>
 #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();
+}
index c57ed7a..3461c21 100644 (file)
@@ -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"
index ee594ea..bd29383 100644 (file)
@@ -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
index 10db863..52aa693 100644 (file)
@@ -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