Compare commits

...

13 Commits

Author SHA1 Message Date
97ee630e27 [pxe] Discard queued PXE UDP packets when under memory pressure
The PXE UDP receive queue may grow without limit if the PXE NBP does
not call PXENV_UDP_READ sufficiently frequently.

Fix by implementing a cache discarder for received PXE UDP packets
(similar to the TCP cache discarder).

Reported-by: Tal Shorer <shorer@amazon.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 22:23:09 +00:00
e72670ad7b [pxe] Avoid drawing menu items on bottom row of screen
Many consoles will scroll immediately upon drawing a character in the
rightmost column of the bottom row of the display, in order to be able
to advance the cursor to the next character (even if the cursor is
disabled).

This causes PXE menus to display incorrectly.  Specifically, pressing
the down arrow key while already on the last menu item may cause the
whole screen to scroll and the line to be duplicated.

Fix by moving the PXE menu one row up from the bottom of the screen.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 20:30:59 +00:00
68734b9a4d [efi] Bind to only the topmost instance of the SNP or NII protocols
UEFI has the mildly annoying habit of installing copies of the
EFI_SIMPLE_NETWORK_PROTOCOL instance on the IPv4 and IPv6 child device
handles.  This can cause iPXE's SNP driver to attempt to bind to a
copy of the EFI_SIMPLE_NETWORK_PROTOCOL that iPXE itself provided on a
different handle.

Fix by refusing to bind to an SNP (or NII) handle if there exists
another instance of the same protocol further up the device path (on
the basis that we always want to bind to the highest possible device).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:13 +00:00
2fef0c541e [efi] Extend efi_locate_device() to allow searching up the device path
Extend the functionality of efi_locate_device() to allow callers to
find instances of the protocol that may exist further up the device
path.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:13 +00:00
1cd0a248cc [efi] Add efi_path_prev() utility function
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:13 +00:00
204d39222a [efi] Add efi_path_terminate() utility function
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:11 +00:00
fcfb70bfb2 [arm] Inhibit linker warnings about an implied executable stack
Some versions of the 32-bit ARM linker seem to treat the absence of a
.note.GNU-stack section as implying an executable stack, and will
print a warning that this is deprecated behaviour.

Silence the warning by adding a .note.GNU-stack section to each
assembly file and retaining the sections in the Linux linker script.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 12:55:44 +00:00
c5e1f007ac [arm] Use -mfloat-abi=soft only for EFI builds
The EFI ABI requires the use of -mfloat-abi=soft, but other platforms
may require -mfloat-abi=hard.

Allow for this by using -mfloat-abi=soft only for EFI builds.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 01:32:14 +00:00
9de6c45dd3 [arm] Use -fno-short-enums for all 32-bit ARM builds
The EFI ABI requires the use of -fno-short-enums, and the EDK2 headers
will perform a compile-time check that enums are 32 bits.

The EDK2 headers may be included even in builds for non-EFI platforms,
and so the -fno-short-enums flag must be used in all 32-bit ARM
builds.  Fortunately, nothing else currently cares about enum sizes.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 01:26:46 +00:00
8f59911b20 [arm] Support building as a Linux userspace binary for AArch64
Add support for building as a Linux userspace binary for AArch64.
This allows the self-test suite to be more easily run for the 64-bit
ARM code.  For example:

  # On a native AArch64 system:
  #
  make bin-arm64-efi/tests.linux && ./bin-arm64-efi/tests.linux

  # On a non-AArch64 system (e.g. x86_64) via cross-compilation,
  # assuming that kernel and glibc headers are present within
  # /usr/aarch64-linux-gnu/sys-root/:
  #
  make bin-arm64-linux/tests.linux CROSS=aarch64-linux-gnu- && \
  qemu-aarch64 -L /usr/aarch64-linux-gnu/sys-root/ \
               ./bin-arm64-linux/tests.linux

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-22 20:36:57 +00:00
2061d658b3 [dhcp] Simplify platform-specific client architecture definitions
Move the platform-specific DHCP client architecture definitions to
header files of the form <ipxe/$(PLATFORM)/dhcparch.h>.  This
simplifies the directory structure and allows the otherwise unused
arch/$(ARCH)/include/$(PLATFORM) to be removed from the include
directory search path, which avoids the confusing situation in which a
header file may potentially be accessed through more than one path.

For Linux userspace binaries on any architecture, use the EFI values
for that architecture by delegating to the EFI header file.  This
avoids the need to explicitly select values for Linux userspace
binaries for each architecture.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-22 17:45:34 +00:00
2ef5f5e05e [build] Move -Ulinux to common Makefile
The requirement to undo the implicit "-Dlinux" is not specific to the
x86 architecture.  Move this out of the x86-specific Makefile.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-22 16:19:22 +00:00
475c0dfa8e [linux] Centralise the linker script for Linux binaries
Reduce duplication between i386 and x86_64 by providing a single
shared linker script that both architectures can include.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-22 12:38:03 +00:00
43 changed files with 335 additions and 503 deletions

View File

@ -369,7 +369,6 @@ endif
# Include architecture-specific include path
ifdef ARCH
INCDIRS += arch/$(ARCH)/include
INCDIRS += arch/$(ARCH)/include/$(PLATFORM)
endif
###############################################################################
@ -512,6 +511,10 @@ CFLAGS += -include include/compiler.h
#
CFLAGS += -DASM_TCHAR='$(ASM_TCHAR)' -DASM_TCHAR_OPS='$(ASM_TCHAR_OPS)'
# Inhibit the default -Dlinux
#
CFLAGS += -Ulinux
# CFLAGS for specific object types
#
CFLAGS_c +=

View File

@ -8,6 +8,10 @@ SYMBOL_PREFIX = _ipxe__
#
CFLAGS += -UNVALGRIND
# The Linux linker script
#
LDSCRIPT = scripts/linux.lds
# Use a two-stage link
#
LDFLAGS += -r -d

View File

@ -0,0 +1,6 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Include generic Linux Makefile
#
MAKEDEPS += Makefile.linux
include Makefile.linux

View File

@ -5,7 +5,7 @@ SRCDIRS += arch/arm32/libgcc
# ARM32-specific flags
#
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs -mfloat-abi=soft
CFLAGS += -mthumb -mcpu=cortex-a15 -mabi=aapcs
CFLAGS += -mword-relocations
ASFLAGS += -mthumb -mcpu=cortex-a15
@ -13,6 +13,11 @@ ASFLAGS += -mthumb -mcpu=cortex-a15
#
CFLAGS += -fshort-wchar
# EFI requires that enums are always 32 bits, and nothing else
# currently cares
#
CFLAGS += -fno-short-enums
# Include common ARM Makefile
MAKEDEPS += arch/arm/Makefile
include arch/arm/Makefile

View File

@ -1,8 +1,8 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# UEFI requires that enums are always 32 bits
# EFI uses the soft float ABI
#
CFLAGS += -fno-short-enums
CFLAGS += -mfloat-abi=soft
# Specify EFI image builder
#

View File

@ -1,5 +1,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.section ".note.GNU-stack", "", %progbits
.text
.arm

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
*
* 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; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM32
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM32
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,5 +1,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.section ".note.GNU-stack", "", %progbits
.text
.thumb

View File

@ -1,5 +1,6 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.section ".note.GNU-stack", "", %progbits
.text
.arm

View File

@ -0,0 +1,10 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Starting virtual address
#
LDFLAGS += -Ttext=0x400000
# Include generic Linux Makefile
#
MAKEDEPS += arch/arm/Makefile.linux
include arch/arm/Makefile.linux

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
*
* 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; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM64
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM64
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,8 +1,8 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Linker script
# Starting virtual address
#
LDSCRIPT = arch/i386/scripts/linux.lds
LDFLAGS += -Ttext=0x08048000
# Compiler flags for building host API wrapper
#

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. 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; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_IA32
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_IA32
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. 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; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
#endif

View File

@ -22,9 +22,6 @@ SRCDIRS += arch/x86/drivers/xen
SRCDIRS += arch/x86/drivers/hyperv
SRCDIRS += arch/x86/transitions
# breaks building some of the linux-related objects
CFLAGS += -Ulinux
# disable valgrind
CFLAGS += -DNVALGRIND

View File

@ -1,9 +1,5 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Include x86 Linux headers
#
INCDIRS += arch/x86/include/linux
# Include generic Linux Makefile
#
MAKEDEPS += Makefile.linux

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_PCBIOS_DHCPARCH_H
#define _IPXE_PCBIOS_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
#endif /* _IPXE_PCBIOS_DHCPARCH_H */

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
*
* 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; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _LINUX_DHCP_ARCH_H
#define _LINUX_DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL);
#include <ipxe/dhcp.h>
// Emulate one of the supported arch-platforms
#include <arch/i386/include/pcbios/ipxe/dhcp_arch.h>
//#include <arch/i386/include/efi/ipxe/dhcp_arch.h>
//#include <arch/x86_64/include/efi/ipxe/dhcp_arch.h>
#endif

View File

@ -12,6 +12,7 @@
#include <ipxe/uaccess.h>
#include <ipxe/process.h>
#include <ipxe/netdevice.h>
#include <ipxe/malloc.h>
#include <realmode.h>
#include <pxe.h>
@ -482,3 +483,28 @@ struct pxe_api_call pxe_udp_api[] __pxe_api_call = {
PXE_API_CALL ( PXENV_UDP_READ, pxenv_udp_read,
struct s_PXENV_UDP_READ ),
};
/**
* Discard some cached PXE UDP data
*
* @ret discarded Number of cached items discarded
*/
static unsigned int pxe_udp_discard ( void ) {
struct io_buffer *iobuf;
unsigned int discarded = 0;
/* Try to discard the oldest received UDP packet */
iobuf = list_first_entry ( &pxe_udp.list, struct io_buffer, list );
if ( iobuf ) {
list_del ( &iobuf->list );
free_iob ( iobuf );
discarded++;
}
return discarded;
}
/** PXE UDP cache discarder */
struct cache_discarder pxe_udp_discarder __cache_discarder ( CACHE_NORMAL ) = {
.discard = pxe_udp_discard,
};

View File

@ -1,8 +1,8 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Linker script
# Starting virtual address
#
LDSCRIPT = arch/x86_64/scripts/linux.lds
LDFLAGS += -Ttext=0x400000
# Include generic Linux Makefile
#

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. 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; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86_64
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_DHCPARCH_H
#define _IPXE_EFI_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
/** DHCP client architecture */
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86_64
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2010 VMware, Inc. 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; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
#ifndef _DHCP_ARCH_H
#define _DHCP_ARCH_H
/** @file
*
* Architecture-specific DHCP options
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
#endif

View File

@ -1,106 +0,0 @@
/* -*- sh -*- */
/*
* Linker script for x86_64 Linux images
*
*/
OUTPUT_FORMAT ( "elf64-x86-64", "elf64-x86-64", "elf64-x86-64" )
OUTPUT_ARCH ( i386:x86-64 )
SECTIONS {
_max_align = 32;
. = 0x400000;
/*
* The text section
*
*/
. = ALIGN ( _max_align );
.text : {
_text = .;
*(.text)
*(.text.*)
_etext = .;
}
/*
* The rodata section
*
*/
. = ALIGN ( _max_align );
.rodata : {
_rodata = .;
*(.rodata)
*(.rodata.*)
_erodata = .;
}
/*
* The data section
*
* Adjust the address for the data segment. We want to adjust up to
* the same address within the page on the next page up.
*/
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1));
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
.data : {
_data = .;
*(.data)
*(.data.*)
KEEP(*(SORT(.tbl.*)))
KEEP(*(.provided))
KEEP(*(.provided.*))
_edata = .;
}
/*
* The bss section
*
*/
. = ALIGN ( _max_align );
.bss : {
_bss = .;
*(.bss)
*(.bss.*)
*(COMMON)
_ebss = .;
}
/*
* Weak symbols that need zero values if not otherwise defined
*
*/
.weak 0x0 : {
_weak = .;
*(.weak)
*(.weak.*)
_eweak = .;
}
_assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" );
/*
* Dispose of the comment and note sections to make the link map
* easier to read
*
*/
/DISCARD/ : {
*(.comment)
*(.comment.*)
*(.note)
*(.note.*)
*(.rel)
*(.rel.*)
*(.discard)
*(.discard.*)
*(.sbat)
*(.sbat.*)
}
}

View File

@ -222,7 +222,7 @@ static int nii_pci_open ( struct nii_nic *nii ) {
/* Locate PCI I/O protocol */
if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
&pci_device ) ) != 0 ) {
&pci_device, 0 ) ) != 0 ) {
DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
nii->dev.name, strerror ( rc ) );
goto err_locate;

View File

@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_utils.h>
#include "snpnet.h"
#include "nii.h"
@ -40,34 +41,60 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* Check to see if driver supports a device
*
* @v device EFI device handle
* @v protocol Protocol GUID
* @ret rc Return status code
*/
static int snp_supported ( EFI_HANDLE device ) {
static int snp_nii_supported ( EFI_HANDLE device, EFI_GUID *protocol ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_HANDLE parent;
EFI_STATUS efirc;
int rc;
/* Check that this is not a device we are providing ourselves */
if ( find_snpdev ( device ) != NULL ) {
DBGCP ( device, "SNP %s is provided by this binary\n",
DBGCP ( device, "HANDLE %s is provided by this binary\n",
efi_handle_name ( device ) );
return -ENOTTY;
}
/* Test for presence of simple network protocol */
if ( ( efirc = bs->OpenProtocol ( device,
&efi_simple_network_protocol_guid,
/* Test for presence of protocol */
if ( ( efirc = bs->OpenProtocol ( device, protocol,
NULL, efi_image_handle, device,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
DBGCP ( device, "SNP %s is not an SNP device\n",
efi_handle_name ( device ) );
DBGCP ( device, "HANDLE %s is not a %s device\n",
efi_handle_name ( device ),
efi_guid_ntoa ( protocol ) );
return -EEFI ( efirc );
}
DBGC ( device, "SNP %s is an SNP device\n",
efi_handle_name ( device ) );
/* Check that there are no instances of this protocol further
* up this device path.
*/
if ( ( rc = efi_locate_device ( device, protocol,
&parent, 1 ) ) == 0 ) {
DBGC2 ( device, "HANDLE %s has %s-supporting parent ",
efi_handle_name ( device ),
efi_guid_ntoa ( protocol ) );
DBGC2 ( device, "%s\n", efi_handle_name ( parent ) );
return -ENOTTY;
}
DBGC ( device, "HANDLE %s is a %s device\n",
efi_handle_name ( device ), efi_guid_ntoa ( protocol ) );
return 0;
}
/**
* Check to see if driver supports a device
*
* @v device EFI device handle
* @ret rc Return status code
*/
static int snp_supported ( EFI_HANDLE device ) {
return snp_nii_supported ( device, &efi_simple_network_protocol_guid );
}
/**
* Check to see if driver supports a device
*
@ -75,29 +102,8 @@ static int snp_supported ( EFI_HANDLE device ) {
* @ret rc Return status code
*/
static int nii_supported ( EFI_HANDLE device ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_STATUS efirc;
/* Check that this is not a device we are providing ourselves */
if ( find_snpdev ( device ) != NULL ) {
DBGCP ( device, "NII %s is provided by this binary\n",
efi_handle_name ( device ) );
return -ENOTTY;
}
/* Test for presence of NII protocol */
if ( ( efirc = bs->OpenProtocol ( device,
&efi_nii31_protocol_guid,
NULL, efi_image_handle, device,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
DBGCP ( device, "NII %s is not an NII device\n",
efi_handle_name ( device ) );
return -EEFI ( efirc );
}
DBGC ( device, "NII %s is an NII device\n",
efi_handle_name ( device ) );
return 0;
return snp_nii_supported ( device, &efi_nii31_protocol_guid );
}
/** EFI SNP driver */

View File

@ -80,7 +80,7 @@ static int chained_locate ( struct chained_protocol *chained ) {
/* Locate handle supporting this protocol */
if ( ( rc = efi_locate_device ( device, chained->protocol,
&parent ) ) != 0 ) {
&parent, 0 ) ) != 0 ) {
DBGC ( device, "CHAINED %s does not support %s: %s\n",
efi_handle_name ( device ),
efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );

View File

@ -96,9 +96,7 @@ efi_image_path ( struct image *image, EFI_DEVICE_PATH_PROTOCOL *parent ) {
efi_snprintf ( filepath->PathName, ( name_len + 1 /* NUL */ ),
"%s", image->name );
end = ( ( ( void * ) filepath ) + filepath_len );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
return path;
}

View File

@ -0,0 +1,16 @@
#ifndef _IPXE_DHCPARCH_H
#define _IPXE_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Include platform-specific client architecture definitions */
#define PLATFORM_DHCPARCH(_platform) <ipxe/_platform/dhcparch.h>
#include PLATFORM_DHCPARCH(PLATFORM)
#endif /* _IPXE_DHCPARCH_H */

View File

@ -21,9 +21,25 @@ struct fcp_description;
struct ib_srp_device;
struct usb_function;
/**
* Terminate device path
*
* @v end End of device path to fill in
*/
static inline void efi_path_terminate ( EFI_DEVICE_PATH_PROTOCOL *end ) {
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
end->Length[1] = 0;
}
extern EFI_DEVICE_PATH_PROTOCOL *
efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path );
extern EFI_DEVICE_PATH_PROTOCOL *
efi_path_prev ( EFI_DEVICE_PATH_PROTOCOL *path,
EFI_DEVICE_PATH_PROTOCOL *curr );
extern EFI_DEVICE_PATH_PROTOCOL *
efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
extern unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path );

View File

@ -13,7 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct device;
extern int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
EFI_HANDLE *parent );
EFI_HANDLE *parent, unsigned int skip );
extern int efi_child_add ( EFI_HANDLE parent, EFI_HANDLE child );
extern void efi_child_del ( EFI_HANDLE parent, EFI_HANDLE child );
extern void efi_device_info ( EFI_HANDLE device, const char *prefix,

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_LINUX_DHCPARCH_H
#define _IPXE_LINUX_DHCPARCH_H
/** @file
*
* DHCP client architecture definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/*
* There are no specification-defined values for DHCP architecture for
* PXE clients running as Linux userspace applications. Pretend to be
* the equivalent EFI client.
*
*/
#include <ipxe/efi/dhcparch.h>
#endif /* _IPXE_LINUX_DHCPARCH_H */

View File

@ -582,9 +582,7 @@ static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
sizeof ( efi_block_boot_filename ) );
}
end = ( ( ( void * ) filepath ) + filepath_len );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
DBGC ( sandev, "EFIBLK %#02x trying to load %s\n",
sandev->drive, efi_devpath_text ( boot_path ) );

View File

@ -65,6 +65,25 @@ EFI_DEVICE_PATH_PROTOCOL * efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path ) {
return path;
}
/**
* Find previous element of device path
*
* @v path Device path, or NULL for no path
* @v curr Current element in device path, or NULL for end of path
* @ret prev Previous element in device path, or NULL
*/
EFI_DEVICE_PATH_PROTOCOL * efi_path_prev ( EFI_DEVICE_PATH_PROTOCOL *path,
EFI_DEVICE_PATH_PROTOCOL *curr ) {
EFI_DEVICE_PATH_PROTOCOL *tmp;
/* Find immediately preceding element */
while ( ( tmp = efi_path_next ( path ) ) != curr ) {
path = tmp;
}
return path;
}
/**
* Find end of device path
*
@ -72,14 +91,8 @@ EFI_DEVICE_PATH_PROTOCOL * efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path ) {
* @ret path_end End of device path, or NULL
*/
EFI_DEVICE_PATH_PROTOCOL * efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
EFI_DEVICE_PATH_PROTOCOL *next;
/* Find end of device path */
while ( ( next = efi_path_next ( path ) ) != NULL ) {
path = next;
}
return path;
return efi_path_prev ( path, NULL );
}
/**
@ -161,9 +174,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first, ... ) {
}
va_end ( args );
end = dst;
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
return path;
}
@ -223,9 +234,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev ) {
} else {
end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
}
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
return path;
}
@ -265,9 +274,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri ) {
uripath->Header.Length[1] = ( uripath_len >> 8 );
format_uri ( uri, uripath->Uri, uri_len );
end = ( ( ( void * ) path ) + uripath_len );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
return path;
}
@ -324,9 +331,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path ( struct iscsi_session *iscsi ) {
name = ( ( ( void * ) iscsipath ) + sizeof ( *iscsipath ) );
memcpy ( name, iscsi->target_iqn, name_len );
end = ( ( ( void * ) name ) + name_len );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
/* Free temporary paths */
free ( netpath );
@ -366,9 +371,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev ) {
satapath.sata.Header.Length[0] = sizeof ( satapath.sata );
satapath.sata.HBAPortNumber = aoedev->major;
satapath.sata.PortMultiplierPortNumber = aoedev->minor;
satapath.end.Type = END_DEVICE_PATH_TYPE;
satapath.end.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
satapath.end.Length[0] = sizeof ( satapath.end );
efi_path_terminate ( &satapath.end );
/* Construct overall device path */
path = efi_paths ( netpath, &satapath, NULL );
@ -409,9 +412,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path ( struct fcp_description *desc ) {
path->fc.Header.Length[0] = sizeof ( path->fc );
memcpy ( path->fc.WWN, &desc->wwn, sizeof ( path->fc.WWN ) );
memcpy ( path->fc.Lun, &desc->lun, sizeof ( path->fc.Lun ) );
path->end.Type = END_DEVICE_PATH_TYPE;
path->end.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
path->end.Length[0] = sizeof ( path->end );
efi_path_terminate ( &path->end );
return &path->fc.Header;
}
@ -463,9 +464,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_ib_srp_path ( struct ib_srp_device *ib_srp ) {
memcpy ( &ibpath->DeviceId, &id->ib.id_ext,
sizeof ( ibpath->DeviceId ) );
end = ( ( ( void * ) ibpath ) + sizeof ( *ibpath ) );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
return path;
}
@ -511,9 +510,7 @@ EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func ) {
/* Construct device path */
memcpy ( path, efidev->path, prefix_len );
end = ( ( ( void * ) path ) + len - sizeof ( *end ) );
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
efi_path_terminate ( end );
usbpath = ( ( ( void * ) end ) - sizeof ( *usbpath ) );
usbpath->InterfaceNumber = func->interface[0];
for ( ; usb ; usbpath--, usb = usb->port->hub->usb ) {

View File

@ -704,9 +704,7 @@ int efi_snp_hii_install ( struct efi_snp_device *snpdev ) {
vendor_path->Header.Length[0] = sizeof ( *vendor_path );
efi_snp_hii_random_guid ( &vendor_path->Guid );
path_end = ( ( void * ) ( vendor_path + 1 ) );
path_end->Type = END_DEVICE_PATH_TYPE;
path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
path_end->Length[0] = sizeof ( *path_end );
efi_path_terminate ( path_end );
/* Create device path and child handle for HII association */
if ( ( efirc = bs->InstallMultipleProtocolInterfaces (

View File

@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <string.h>
#include <errno.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_pci.h>
#include <ipxe/efi/efi_utils.h>
@ -38,23 +39,26 @@ FILE_LICENCE ( GPL2_OR_LATER );
* @v device EFI device handle
* @v protocol Protocol GUID
* @v parent Parent EFI device handle to fill in
* @v skip Number of protocol-supporting parent devices to skip
* @ret rc Return status code
*/
int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
EFI_HANDLE *parent ) {
EFI_HANDLE *parent, unsigned int skip ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
union {
EFI_DEVICE_PATH_PROTOCOL *path;
void *interface;
} path;
EFI_DEVICE_PATH_PROTOCOL *devpath;
} u;
EFI_DEVICE_PATH_PROTOCOL *path;
EFI_DEVICE_PATH_PROTOCOL *end;
size_t len;
EFI_STATUS efirc;
int rc;
/* Get device path */
if ( ( efirc = bs->OpenProtocol ( device,
&efi_device_path_protocol_guid,
&path.interface,
&u.interface,
efi_image_handle, device,
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
rc = -EEFI ( efirc );
@ -62,22 +66,46 @@ int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
efi_handle_name ( device ), strerror ( rc ) );
goto err_open_device_path;
}
devpath = path.path;
/* Check for presence of specified protocol */
if ( ( efirc = bs->LocateDevicePath ( protocol, &devpath,
parent ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( device, "EFIDEV %s has no parent supporting %s: %s\n",
efi_handle_name ( device ),
efi_guid_ntoa ( protocol ), strerror ( rc ) );
goto err_locate_protocol;
/* Create modifiable copy of device path */
len = ( efi_path_len ( u.path ) + sizeof ( EFI_DEVICE_PATH_PROTOCOL ));
path = malloc ( len );
if ( ! path ) {
rc = -ENOMEM;
goto err_alloc_path;
}
memcpy ( path, u.path, len );
/* Locate parent device(s) */
while ( 1 ) {
/* Check for presence of specified protocol */
end = path;
if ( ( efirc = bs->LocateDevicePath ( protocol, &end,
parent ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( device, "EFIDEV %s has no parent supporting "
"%s: %s\n", efi_devpath_text ( path ),
efi_guid_ntoa ( protocol ), strerror ( rc ) );
goto err_locate_protocol;
}
/* Stop if we have skipped the requested number of devices */
if ( ! skip-- )
break;
/* Trim device path */
efi_path_terminate ( end );
end = efi_path_prev ( path, end );
efi_path_terminate ( end );
}
/* Success */
rc = 0;
err_locate_protocol:
free ( path );
err_alloc_path:
bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
efi_image_handle, device );
err_open_device_path:
@ -150,7 +178,7 @@ static int efi_pci_info ( EFI_HANDLE device, const char *prefix,
/* Find parent PCI device */
if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
&pci_device ) ) != 0 ) {
&pci_device, 0 ) ) != 0 ) {
DBGC ( device, "EFIDEV %s is not a PCI device: %s\n",
efi_handle_name ( device ), strerror ( rc ) );
return rc;

View File

@ -46,7 +46,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/dhcp.h>
#include <ipxe/dhcpopts.h>
#include <ipxe/dhcppkt.h>
#include <ipxe/dhcp_arch.h>
#include <ipxe/dhcparch.h>
#include <ipxe/features.h>
#include <config/dhcp.h>

View File

@ -40,7 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/crc32.h>
#include <ipxe/errortab.h>
#include <ipxe/ipv6.h>
#include <ipxe/dhcp_arch.h>
#include <ipxe/dhcparch.h>
#include <ipxe/dhcpv6.h>
/** @file

View File

@ -1,18 +1,13 @@
/* -*- sh -*- */
/*
* Linker script for i386 Linux images
* Linker script for Linux images
*
*/
OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
OUTPUT_ARCH ( i386 )
SECTIONS {
_max_align = 32;
. = 0x08048000;
/*
* The text section
*
@ -86,16 +81,13 @@ SECTIONS {
_assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" );
/*
* Dispose of the comment and note sections to make the link map
* easier to read
* Dispose of unwanted sections to make the link map easier to read
*
*/
/DISCARD/ : {
*(.comment)
*(.comment.*)
*(.note)
*(.note.*)
*(.rel)
*(.rel.*)
*(.discard)

View File

@ -204,7 +204,7 @@ static void pxe_menu_draw_item ( struct pxe_menu *menu,
buf[ sizeof ( buf ) - 1 ] = '\0';
/* Draw row */
row = ( LINES - menu->num_items + index );
row = ( LINES - menu->num_items + index - 1 );
color_set ( ( selected ? CPAIR_PXE : CPAIR_DEFAULT ), NULL );
mvprintw ( row, 0, "%s", buf );
move ( row, 1 );