mirror of
https://gitlab.com/qemu-project/ipxe.git
synced 2025-10-30 07:56:50 +08:00
Compare commits
6 Commits
eficompres
...
kexec2
| Author | SHA1 | Date | |
|---|---|---|---|
| 9776f6ece1 | |||
| d175936b78 | |||
| 0956fb52c4 | |||
| f309d7a7b7 | |||
| 040cdd0c65 | |||
| 16d95227a4 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -14,9 +14,11 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update
|
||||
sudo apt install -y -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux libc6-dev-i386 valgrind
|
||||
mtools syslinux isolinux \
|
||||
libc6-dev-i386 libc6-dbg:i386 valgrind
|
||||
- name: Build (BIOS)
|
||||
run: |
|
||||
make -j 4 -C src
|
||||
|
||||
@ -10,6 +10,7 @@ LDFLAGS :=
|
||||
HOST_CFLAGS :=
|
||||
MAKEDEPS := Makefile
|
||||
CROSS_COMPILE ?= $(CROSS)
|
||||
SYMBOL_PREFIX :=
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
@ -1102,9 +1102,10 @@ TGT_LD_ENTRY = _$(TGT_PREFIX)_start
|
||||
#
|
||||
TGT_LD_FLAGS = $(foreach SYM,$(TGT_LD_ENTRY) $(TGT_LD_DRIVERS) \
|
||||
$(TGT_LD_DEVLIST) obj_config obj_config_$(PLATFORM),\
|
||||
-u $(SYM) --defsym check_$(SYM)=$(SYM) ) \
|
||||
-u $(SYMBOL_PREFIX)$(SYM) \
|
||||
--defsym check_$(SYM)=$(SYMBOL_PREFIX)$(SYM) ) \
|
||||
$(patsubst %,--defsym %,$(TGT_LD_IDS)) \
|
||||
-e $(TGT_LD_ENTRY)
|
||||
-e $(SYMBOL_PREFIX)$(TGT_LD_ENTRY)
|
||||
|
||||
# Calculate list of debugging versions of objects to be included in
|
||||
# the target.
|
||||
@ -1166,6 +1167,7 @@ $(BLIB) : $(BLIB_OBJS) $(BLIB_LIST) $(MAKEDEPS)
|
||||
$(Q)$(RM) $(BLIB)
|
||||
$(QM)$(ECHO) " [AR] $@"
|
||||
$(Q)$(AR) rD $@ $(sort $(BLIB_OBJS))
|
||||
$(Q)$(OBJCOPY) --prefix-symbols=$(SYMBOL_PREFIX) $@
|
||||
$(Q)$(RANLIB) -D $@
|
||||
blib : $(BLIB)
|
||||
|
||||
@ -1207,6 +1209,7 @@ $(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(GIT_INDEX)
|
||||
-DVERSION_PATCH=$(VERSION_PATCH) \
|
||||
-DVERSION="\"$(VERSION)\"" \
|
||||
-c $< -o $@
|
||||
$(Q)$(OBJCOPY) --prefix-symbols=$(SYMBOL_PREFIX) $@
|
||||
|
||||
# Build an intermediate object file from the objects required for the
|
||||
# specified target.
|
||||
|
||||
39
src/Makefile.linux
Normal file
39
src/Makefile.linux
Normal file
@ -0,0 +1,39 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Prefix all iPXE symbols to avoid collisions with platform libraries
|
||||
#
|
||||
SYMBOL_PREFIX = _ipxe__
|
||||
|
||||
# Enable valgrind
|
||||
#
|
||||
CFLAGS += -UNVALGRIND
|
||||
|
||||
# Use a two-stage link
|
||||
#
|
||||
LDFLAGS += -r -d
|
||||
|
||||
# Source directories
|
||||
#
|
||||
SRCDIRS += drivers/linux
|
||||
SRCDIRS += interface/linux
|
||||
NON_AUTO_SRCS += interface/linux/linux_api.c
|
||||
|
||||
# Media types
|
||||
#
|
||||
NON_AUTO_MEDIA = linux
|
||||
|
||||
# Compiler flags for building host API wrapper
|
||||
#
|
||||
LINUX_CFLAGS += -Os -idirafter include -DSYMBOL_PREFIX=$(SYMBOL_PREFIX)
|
||||
|
||||
# Host API wrapper
|
||||
#
|
||||
$(BIN)/linux_api.o : interface/linux/linux_api.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [BUILD] $@"
|
||||
$(Q)$(CC) $(LINUX_CFLAGS) $(WORKAROUND_CFLAGS) -o $@ -c $<
|
||||
|
||||
# Rule to generate final binary
|
||||
#
|
||||
$(BIN)/%.linux : $(BIN)/%.linux.tmp $(BIN)/linux_api.o
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)$(CC) $(LINUX_CFLAGS) $(WORKAROUND_CFLAGS) -o $@ $^
|
||||
@ -1,6 +1,14 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Linker script
|
||||
#
|
||||
LDSCRIPT = arch/i386/scripts/linux.lds
|
||||
|
||||
SRCDIRS += arch/i386/core/linux
|
||||
# Compiler flags for building host API wrapper
|
||||
#
|
||||
LINUX_CFLAGS += -m32
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += arch/x86/Makefile.linux
|
||||
include arch/x86/Makefile.linux
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
|
||||
.section ".data"
|
||||
.globl linux_errno
|
||||
|
||||
linux_errno: .int 0
|
||||
|
||||
.section ".text"
|
||||
.code32
|
||||
.globl linux_syscall
|
||||
.type linux_syscall, @function
|
||||
|
||||
linux_syscall:
|
||||
/* Save registers */
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %ebp
|
||||
|
||||
movl 20(%esp), %eax // C arg1 -> syscall number
|
||||
movl 24(%esp), %ebx // C arg2 -> syscall arg1
|
||||
movl 28(%esp), %ecx // C arg3 -> syscall arg2
|
||||
movl 32(%esp), %edx // C arg4 -> syscall arg3
|
||||
movl 36(%esp), %esi // C arg5 -> syscall arg4
|
||||
movl 40(%esp), %edi // C arg6 -> syscall arg5
|
||||
movl 44(%esp), %ebp // C arg7 -> syscall arg6
|
||||
|
||||
int $0x80
|
||||
|
||||
/* Restore registers */
|
||||
popl %ebp
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
|
||||
cmpl $-4095, %eax
|
||||
jae 1f
|
||||
ret
|
||||
|
||||
1:
|
||||
negl %eax
|
||||
movl %eax, linux_errno
|
||||
movl $-1, %eax
|
||||
ret
|
||||
|
||||
.size linux_syscall, . - linux_syscall
|
||||
@ -1,28 +0,0 @@
|
||||
#include <linux/unistd.h>
|
||||
|
||||
.section ".text"
|
||||
.code32
|
||||
.globl _linux_start
|
||||
.type _linux_start, @function
|
||||
|
||||
_linux_start:
|
||||
xorl %ebp, %ebp
|
||||
|
||||
popl %esi // save argc
|
||||
movl %esp, %edi // save argv
|
||||
|
||||
andl $~15, %esp // 16-byte align the stack
|
||||
|
||||
pushl %edi // argv -> C arg2
|
||||
pushl %esi // argc -> C arg1
|
||||
|
||||
call save_args
|
||||
|
||||
/* Our main doesn't use any arguments */
|
||||
call main
|
||||
|
||||
movl %eax, %ebx // rc -> syscall arg1
|
||||
movl $__NR_exit, %eax
|
||||
int $0x80
|
||||
|
||||
.size _linux_start, . - _linux_start
|
||||
@ -1,6 +0,0 @@
|
||||
#ifndef _I386_LINUX_API_H
|
||||
#define _I386_LINUX_API_H
|
||||
|
||||
#define __SYSCALL_mmap __NR_mmap2
|
||||
|
||||
#endif /* _I386_LINUX_API_H */
|
||||
@ -1,13 +1,10 @@
|
||||
MEDIA = linux
|
||||
|
||||
# enable valgrind
|
||||
CFLAGS += -UNVALGRIND
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Include x86 Linux headers
|
||||
#
|
||||
INCDIRS += arch/x86/include/linux
|
||||
SRCDIRS += interface/linux
|
||||
SRCDIRS += drivers/linux
|
||||
SRCDIRS += arch/x86/core/linux
|
||||
|
||||
$(BIN)/%.linux : $(BIN)/%.linux.tmp
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)$(CP) $< $@
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += Makefile.linux
|
||||
include Makefile.linux
|
||||
|
||||
@ -1,149 +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 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Implementation of most of the linux API.
|
||||
*/
|
||||
|
||||
#include <linux_api.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
int linux_open ( const char *pathname, int flags ) {
|
||||
return linux_syscall ( __NR_open, pathname, flags );
|
||||
}
|
||||
|
||||
int linux_close ( int fd ) {
|
||||
return linux_syscall ( __NR_close, fd );
|
||||
}
|
||||
|
||||
off_t linux_lseek ( int fd, off_t offset, int whence ) {
|
||||
return linux_syscall ( __NR_lseek, fd, offset, whence );
|
||||
}
|
||||
|
||||
__kernel_ssize_t linux_read ( int fd, void *buf, __kernel_size_t count ) {
|
||||
return linux_syscall ( __NR_read, fd, buf, count );
|
||||
}
|
||||
|
||||
__kernel_ssize_t linux_write ( int fd, const void *buf,
|
||||
__kernel_size_t count ) {
|
||||
return linux_syscall ( __NR_write, fd, buf, count );
|
||||
}
|
||||
|
||||
int linux_fcntl ( int fd, int cmd, ... ) {
|
||||
long arg;
|
||||
va_list list;
|
||||
|
||||
va_start ( list, cmd );
|
||||
arg = va_arg ( list, long );
|
||||
va_end ( list );
|
||||
|
||||
return linux_syscall ( __NR_fcntl, fd, cmd, arg );
|
||||
}
|
||||
|
||||
int linux_ioctl ( int fd, int request, ... ) {
|
||||
void *arg;
|
||||
va_list list;
|
||||
|
||||
va_start ( list, request );
|
||||
arg = va_arg ( list, void * );
|
||||
va_end ( list );
|
||||
|
||||
return linux_syscall ( __NR_ioctl, fd, request, arg );
|
||||
}
|
||||
|
||||
int linux_poll ( struct pollfd *fds, nfds_t nfds, int timeout ) {
|
||||
return linux_syscall ( __NR_poll, fds, nfds, timeout );
|
||||
}
|
||||
|
||||
int linux_nanosleep ( const struct timespec *req, struct timespec *rem ) {
|
||||
return linux_syscall ( __NR_nanosleep, req, rem );
|
||||
}
|
||||
|
||||
int linux_usleep ( useconds_t usec ) {
|
||||
struct timespec ts = {
|
||||
.tv_sec = ( ( long ) ( usec / 1000000 ) ),
|
||||
.tv_nsec = ( ( long ) ( usec % 1000000 ) * 1000UL ),
|
||||
};
|
||||
|
||||
return linux_nanosleep ( &ts, NULL );
|
||||
}
|
||||
|
||||
int linux_gettimeofday ( struct timeval *tv, struct timezone *tz ) {
|
||||
return linux_syscall ( __NR_gettimeofday, tv, tz );
|
||||
}
|
||||
|
||||
void * linux_mmap ( void *addr, __kernel_size_t length, int prot, int flags,
|
||||
int fd, __kernel_off_t offset ) {
|
||||
return ( void * ) linux_syscall ( __SYSCALL_mmap, addr, length, prot,
|
||||
flags, fd, offset );
|
||||
}
|
||||
|
||||
void * linux_mremap ( void *old_address, __kernel_size_t old_size,
|
||||
__kernel_size_t new_size, int flags ) {
|
||||
return ( void * ) linux_syscall ( __NR_mremap, old_address, old_size,
|
||||
new_size, flags );
|
||||
}
|
||||
|
||||
int linux_munmap ( void *addr, __kernel_size_t length ) {
|
||||
return linux_syscall ( __NR_munmap, addr, length );
|
||||
}
|
||||
|
||||
int linux_socket ( int domain, int type_, int protocol ) {
|
||||
#ifdef __NR_socket
|
||||
return linux_syscall ( __NR_socket, domain, type_, protocol );
|
||||
#else
|
||||
#ifndef SOCKOP_socket
|
||||
# define SOCKOP_socket 1
|
||||
#endif
|
||||
unsigned long sc_args[] = { domain, type_, protocol };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_socket, sc_args );
|
||||
#endif
|
||||
}
|
||||
|
||||
int linux_bind ( int fd, const struct sockaddr *addr, socklen_t addrlen ) {
|
||||
#ifdef __NR_bind
|
||||
return linux_syscall ( __NR_bind, fd, addr, addrlen );
|
||||
#else
|
||||
#ifndef SOCKOP_bind
|
||||
# define SOCKOP_bind 2
|
||||
#endif
|
||||
unsigned long sc_args[] = { fd, (unsigned long)addr, addrlen };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_bind, sc_args );
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t linux_sendto ( int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *daddr, socklen_t addrlen ) {
|
||||
#ifdef __NR_sendto
|
||||
return linux_syscall ( __NR_sendto, fd, buf, len, flags,
|
||||
daddr, addrlen );
|
||||
#else
|
||||
#ifndef SOCKOP_sendto
|
||||
# define SOCKOP_sendto 11
|
||||
#endif
|
||||
unsigned long sc_args[] = { fd, (unsigned long)buf, len,
|
||||
flags, (unsigned long)daddr, addrlen };
|
||||
return linux_syscall ( __NR_socketcall, SOCKOP_sendto, sc_args );
|
||||
#endif
|
||||
}
|
||||
@ -1,169 +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 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
FILE_LICENCE(GPL2_OR_LATER);
|
||||
|
||||
/** @file
|
||||
*
|
||||
* linux_strerror implementation
|
||||
*/
|
||||
|
||||
#include <linux_api.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/** Error names from glibc */
|
||||
static const char *errors[] = {
|
||||
"Success",
|
||||
"Operation not permitted",
|
||||
"No such file or directory",
|
||||
"No such process",
|
||||
"Interrupted system call",
|
||||
"Input/output error",
|
||||
"No such device or address",
|
||||
"Argument list too long",
|
||||
"Exec format error",
|
||||
"Bad file descriptor",
|
||||
"No child processes",
|
||||
"Resource temporarily unavailable",
|
||||
"Cannot allocate memory",
|
||||
"Permission denied",
|
||||
"Bad address",
|
||||
"Block device required",
|
||||
"Device or resource busy",
|
||||
"File exists",
|
||||
"Invalid cross-device link",
|
||||
"No such device",
|
||||
"Not a directory",
|
||||
"Is a directory",
|
||||
"Invalid argument",
|
||||
"Too many open files in system",
|
||||
"Too many open files",
|
||||
"Inappropriate ioctl for device",
|
||||
"Text file busy",
|
||||
"File too large",
|
||||
"No space left on device",
|
||||
"Illegal seek",
|
||||
"Read-only file system",
|
||||
"Too many links",
|
||||
"Broken pipe",
|
||||
"Numerical argument out of domain",
|
||||
"Numerical result out of range",
|
||||
"Resource deadlock avoided",
|
||||
"File name too long",
|
||||
"No locks available",
|
||||
"Function not implemented",
|
||||
"Directory not empty",
|
||||
"Too many levels of symbolic links",
|
||||
"",
|
||||
"No message of desired type",
|
||||
"Identifier removed",
|
||||
"Channel number out of range",
|
||||
"Level 2 not synchronized",
|
||||
"Level 3 halted",
|
||||
"Level 3 reset",
|
||||
"Link number out of range",
|
||||
"Protocol driver not attached",
|
||||
"No CSI structure available",
|
||||
"Level 2 halted",
|
||||
"Invalid exchange",
|
||||
"Invalid request descriptor",
|
||||
"Exchange full",
|
||||
"No anode",
|
||||
"Invalid request code",
|
||||
"Invalid slot",
|
||||
"",
|
||||
"Bad font file format",
|
||||
"Device not a stream",
|
||||
"No data available",
|
||||
"Timer expired",
|
||||
"Out of streams resources",
|
||||
"Machine is not on the network",
|
||||
"Package not installed",
|
||||
"Object is remote",
|
||||
"Link has been severed",
|
||||
"Advertise error",
|
||||
"Srmount error",
|
||||
"Communication error on send",
|
||||
"Protocol error",
|
||||
"Multihop attempted",
|
||||
"RFS specific error",
|
||||
"Bad message",
|
||||
"Value too large for defined data type",
|
||||
"Name not unique on network",
|
||||
"File descriptor in bad state",
|
||||
"Remote address changed",
|
||||
"Can not access a needed shared library",
|
||||
"Accessing a corrupted shared library",
|
||||
".lib section in a.out corrupted",
|
||||
"Attempting to link in too many shared libraries",
|
||||
"Cannot exec a shared library directly",
|
||||
"Invalid or incomplete multibyte or wide character",
|
||||
"Interrupted system call should be restarted",
|
||||
"Streams pipe error",
|
||||
"Too many users",
|
||||
"Socket operation on non-socket",
|
||||
"Destination address required",
|
||||
"Message too long",
|
||||
"Protocol wrong type for socket",
|
||||
"Protocol not available",
|
||||
"Protocol not supported",
|
||||
"Socket type not supported",
|
||||
"Operation not supported",
|
||||
"Protocol family not supported",
|
||||
"Address family not supported by protocol",
|
||||
"Address already in use",
|
||||
"Cannot assign requested address",
|
||||
"Network is down",
|
||||
"Network is unreachable",
|
||||
"Network dropped connection on reset",
|
||||
"Software caused connection abort",
|
||||
"Connection reset by peer",
|
||||
"No buffer space available",
|
||||
"Transport endpoint is already connected",
|
||||
"Transport endpoint is not connected",
|
||||
"Cannot send after transport endpoint shutdown",
|
||||
"Too many references: cannot splice",
|
||||
"Connection timed out",
|
||||
"Connection refused",
|
||||
"Host is down",
|
||||
"No route to host",
|
||||
"Operation already in progress",
|
||||
"Operation now in progress",
|
||||
"Stale NFS file handle",
|
||||
"Structure needs cleaning",
|
||||
"Not a XENIX named type file",
|
||||
"No XENIX semaphores available",
|
||||
"Is a named type file",
|
||||
"Remote I/O error",
|
||||
"Disk quota exceeded",
|
||||
"No medium found",
|
||||
"Wrong medium type",
|
||||
};
|
||||
|
||||
const char *linux_strerror(int errnum)
|
||||
{
|
||||
static char errbuf[64];
|
||||
static int errors_size = sizeof(errors) / sizeof(*errors);
|
||||
|
||||
if (errnum >= errors_size || errnum < 0) {
|
||||
snprintf(errbuf, sizeof(errbuf), "Error %#08x", errnum);
|
||||
return errbuf;
|
||||
} else {
|
||||
return errors[errnum];
|
||||
}
|
||||
}
|
||||
@ -29,7 +29,7 @@ set_bit ( unsigned int bit, volatile void *bits ) {
|
||||
uint8_t byte[ ( bit / 8 ) + 1 ];
|
||||
} *bytes = bits;
|
||||
|
||||
__asm__ __volatile__ ( "lock bts %1, %0"
|
||||
__asm__ __volatile__ ( "lock btsl %k1, %0"
|
||||
: "+m" ( *bytes ) : "Ir" ( bit ) );
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ clear_bit ( unsigned int bit, volatile void *bits ) {
|
||||
uint8_t byte[ ( bit / 8 ) + 1 ];
|
||||
} *bytes = bits;
|
||||
|
||||
__asm__ __volatile__ ( "lock btr %1, %0"
|
||||
__asm__ __volatile__ ( "lock btrl %k1, %0"
|
||||
: "+m" ( *bytes ) : "Ir" ( bit ) );
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ test_and_set_bit ( unsigned int bit, volatile void *bits ) {
|
||||
} *bytes = bits;
|
||||
int old;
|
||||
|
||||
__asm__ __volatile__ ( "lock bts %2, %0\n\t"
|
||||
__asm__ __volatile__ ( "lock btsl %k2, %0\n\t"
|
||||
"sbb %1, %1\n\t"
|
||||
: "+m" ( *bytes ), "=r" ( old )
|
||||
: "Ir" ( bit ) );
|
||||
@ -84,7 +84,7 @@ test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
|
||||
} *bytes = bits;
|
||||
int old;
|
||||
|
||||
__asm__ __volatile__ ( "lock btr %2, %0\n\t"
|
||||
__asm__ __volatile__ ( "lock btrl %k2, %0\n\t"
|
||||
"sbb %1, %1\n\t"
|
||||
: "+m" ( *bytes ), "=r" ( old )
|
||||
: "Ir" ( bit ) );
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
#ifndef _LINUX_API_PLATFORM_H
|
||||
#define _LINUX_API_PLATFORM_H
|
||||
|
||||
extern int linux_errno;
|
||||
|
||||
#endif /* _LINUX_API_PLATFORM_H */
|
||||
@ -15,4 +15,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ACPI_PREFIX_rsdp __rsdp_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Locate ACPI table
|
||||
*
|
||||
* @v signature Requested table signature
|
||||
* @v index Requested index of table with this signature
|
||||
* @ret table Table, or UNULL if not found
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) userptr_t
|
||||
ACPI_INLINE ( rsdp, acpi_find ) ( uint32_t signature, unsigned int index ) {
|
||||
|
||||
return acpi_find_via_rsdt ( signature, index );
|
||||
}
|
||||
|
||||
#endif /* _IPXE_RSDP_H */
|
||||
|
||||
@ -123,3 +123,4 @@ static userptr_t rsdp_find_rsdt ( void ) {
|
||||
}
|
||||
|
||||
PROVIDE_ACPI ( rsdp, acpi_find_rsdt, rsdp_find_rsdt );
|
||||
PROVIDE_ACPI_INLINE ( rsdp, acpi_find );
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Linker script
|
||||
#
|
||||
LDSCRIPT = arch/x86_64/scripts/linux.lds
|
||||
|
||||
SRCDIRS += arch/x86_64/core/linux
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += arch/x86/Makefile.linux
|
||||
include arch/x86/Makefile.linux
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
|
||||
.section ".data"
|
||||
.globl linux_errno
|
||||
|
||||
linux_errno: .int 0
|
||||
|
||||
.section ".text"
|
||||
.code64
|
||||
.globl linux_syscall
|
||||
.type linux_syscall, @function
|
||||
|
||||
linux_syscall:
|
||||
movq %rdi, %rax // C arg1 -> syscall number
|
||||
movq %rsi, %rdi // C arg2 -> syscall arg1
|
||||
movq %rdx, %rsi // C arg3 -> syscall arg2
|
||||
movq %rcx, %rdx // C arg4 -> syscall arg3
|
||||
movq %r8, %r10 // C arg5 -> syscall arg4
|
||||
movq %r9, %r8 // C arg6 -> syscall arg5
|
||||
movq 8(%rsp), %r9 // C arg7 -> syscall arg6
|
||||
|
||||
syscall
|
||||
|
||||
cmpq $-4095, %rax
|
||||
jae 1f
|
||||
ret
|
||||
|
||||
1:
|
||||
negq %rax
|
||||
movl %eax, linux_errno
|
||||
movq $-1, %rax
|
||||
ret
|
||||
|
||||
.size linux_syscall, . - linux_syscall
|
||||
@ -1,25 +0,0 @@
|
||||
#include <linux/unistd.h>
|
||||
|
||||
.section ".text"
|
||||
.code64
|
||||
.globl _linux_start
|
||||
.type _linux_start, @function
|
||||
|
||||
_linux_start:
|
||||
xorq %rbp, %rbp
|
||||
|
||||
popq %rdi // argc -> C arg1
|
||||
movq %rsp, %rsi // argv -> C arg2
|
||||
|
||||
andq $~15, %rsp // 16-byte align the stack
|
||||
|
||||
call save_args
|
||||
|
||||
/* Our main doesn't use any arguments */
|
||||
call main
|
||||
|
||||
movq %rax, %rdi // rc -> syscall arg1
|
||||
movq $__NR_exit, %rax
|
||||
syscall
|
||||
|
||||
.size _linux_start, . - _linux_start
|
||||
@ -1,6 +0,0 @@
|
||||
#ifndef _X86_64_LINUX_API_H
|
||||
#define _X86_64_LINUX_API_H
|
||||
|
||||
#define __SYSCALL_mmap __NR_mmap
|
||||
|
||||
#endif /* _X86_64_LINUX_API_H */
|
||||
@ -35,6 +35,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour FADT_SIGNATURE
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Utility functions
|
||||
@ -80,13 +83,13 @@ void acpi_fix_checksum ( struct acpi_header *acpi ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate ACPI table
|
||||
* Locate ACPI table via RSDT
|
||||
*
|
||||
* @v signature Requested table signature
|
||||
* @v index Requested index of table with this signature
|
||||
* @ret table Table, or UNULL if not found
|
||||
*/
|
||||
userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
|
||||
userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) {
|
||||
struct acpi_header acpi;
|
||||
struct acpi_rsdt *rsdtab;
|
||||
typeof ( rsdtab->entry[0] ) entry;
|
||||
@ -106,17 +109,17 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
|
||||
/* Read RSDT header */
|
||||
copy_from_user ( &acpi, rsdt, 0, sizeof ( acpi ) );
|
||||
if ( acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) {
|
||||
DBGC ( rsdt, "RSDT %#08lx has invalid signature:\n",
|
||||
DBGC ( colour, "RSDT %#08lx has invalid signature:\n",
|
||||
user_to_phys ( rsdt, 0 ) );
|
||||
DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
|
||||
DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi,
|
||||
sizeof ( acpi ) );
|
||||
return UNULL;
|
||||
}
|
||||
len = le32_to_cpu ( acpi.length );
|
||||
if ( len < sizeof ( rsdtab->acpi ) ) {
|
||||
DBGC ( rsdt, "RSDT %#08lx has invalid length:\n",
|
||||
DBGC ( colour, "RSDT %#08lx has invalid length:\n",
|
||||
user_to_phys ( rsdt, 0 ) );
|
||||
DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
|
||||
DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi,
|
||||
sizeof ( acpi ) );
|
||||
return UNULL;
|
||||
}
|
||||
@ -147,20 +150,20 @@ userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
|
||||
|
||||
/* Check table integrity */
|
||||
if ( acpi_checksum ( table ) != 0 ) {
|
||||
DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
|
||||
"at %08lx\n", user_to_phys ( rsdt, 0 ),
|
||||
DBGC ( colour, "RSDT %#08lx found %s with bad "
|
||||
"checksum at %08lx\n", user_to_phys ( rsdt, 0 ),
|
||||
acpi_name ( signature ),
|
||||
user_to_phys ( table, 0 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
|
||||
DBGC ( colour, "RSDT %#08lx found %s at %08lx\n",
|
||||
user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
|
||||
user_to_phys ( table, 0 ) );
|
||||
return table;
|
||||
}
|
||||
|
||||
DBGC ( rsdt, "RSDT %#08lx could not find %s\n",
|
||||
DBGC ( colour, "RSDT %#08lx could not find %s\n",
|
||||
user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
|
||||
return UNULL;
|
||||
}
|
||||
@ -256,20 +259,12 @@ static int acpi_sx_zsdt ( userptr_t zsdt, uint32_t signature ) {
|
||||
*/
|
||||
int acpi_sx ( uint32_t signature ) {
|
||||
struct acpi_fadt fadtab;
|
||||
userptr_t rsdt;
|
||||
userptr_t fadt;
|
||||
userptr_t dsdt;
|
||||
userptr_t ssdt;
|
||||
unsigned int i;
|
||||
int sx;
|
||||
|
||||
/* Locate RSDT */
|
||||
rsdt = acpi_find_rsdt();
|
||||
if ( ! rsdt ) {
|
||||
DBG ( "RSDT not found\n" );
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Try DSDT first */
|
||||
fadt = acpi_find ( FADT_SIGNATURE, 0 );
|
||||
if ( fadt ) {
|
||||
@ -288,8 +283,8 @@ int acpi_sx ( uint32_t signature ) {
|
||||
return sx;
|
||||
}
|
||||
|
||||
DBGC ( rsdt, "RSDT %#08lx could not find \\_Sx \"%s\"\n",
|
||||
user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
|
||||
DBGC ( colour, "ACPI could not find \\_Sx \"%s\"\n",
|
||||
acpi_name ( signature ) );
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
#include <ipxe/acpi.h>
|
||||
|
||||
PROVIDE_ACPI_INLINE ( null, acpi_find_rsdt );
|
||||
PROVIDE_ACPI_INLINE ( null, acpi_find );
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
#include <ipxe/list.h>
|
||||
#include <ipxe/linux.h>
|
||||
#include <ipxe/malloc.h>
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
#include <ipxe/list.h>
|
||||
#include <ipxe/linux.h>
|
||||
#include <ipxe/malloc.h>
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
|
||||
FILE_LICENCE(GPL2_OR_LATER);
|
||||
|
||||
#include <hci/linux_args.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -27,21 +26,8 @@ FILE_LICENCE(GPL2_OR_LATER);
|
||||
#include <ipxe/malloc.h>
|
||||
#include <ipxe/init.h>
|
||||
|
||||
/** Saved argc */
|
||||
static int saved_argc = 0;
|
||||
/** Saved argv */
|
||||
static char ** saved_argv;
|
||||
|
||||
/**
|
||||
* Save argc and argv for later access.
|
||||
*
|
||||
* To be called by linuxprefix
|
||||
*/
|
||||
__asmcall void save_args(int argc, char **argv)
|
||||
{
|
||||
saved_argc = argc;
|
||||
saved_argv = argv;
|
||||
}
|
||||
int linux_argc;
|
||||
char **linux_argv;
|
||||
|
||||
/** Supported command-line options */
|
||||
static struct option options[] = {
|
||||
@ -138,7 +124,7 @@ void linux_args_parse()
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(saved_argc, saved_argv, "", options, &option_index);
|
||||
c = getopt_long(linux_argc, linux_argv, "", options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
|
||||
@ -355,6 +355,8 @@ struct acpi_model {
|
||||
#define PROVIDE_ACPI_INLINE( _subsys, _api_func ) \
|
||||
PROVIDE_SINGLE_API_INLINE ( ACPI_PREFIX_ ## _subsys, _api_func )
|
||||
|
||||
extern userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index );
|
||||
|
||||
/* Include all architecture-independent ACPI API headers */
|
||||
#include <ipxe/null_acpi.h>
|
||||
#include <ipxe/efi/efi_acpi.h>
|
||||
@ -369,13 +371,21 @@ struct acpi_model {
|
||||
*/
|
||||
userptr_t acpi_find_rsdt ( void );
|
||||
|
||||
/**
|
||||
* Locate ACPI table
|
||||
*
|
||||
* @v signature Requested table signature
|
||||
* @v index Requested index of table with this signature
|
||||
* @ret table Table, or UNULL if not found
|
||||
*/
|
||||
userptr_t acpi_find ( uint32_t signature, unsigned int index );
|
||||
|
||||
extern struct acpi_descriptor *
|
||||
acpi_describe ( struct interface *interface );
|
||||
#define acpi_describe_TYPE( object_type ) \
|
||||
typeof ( struct acpi_descriptor * ( object_type ) )
|
||||
|
||||
extern void acpi_fix_checksum ( struct acpi_header *acpi );
|
||||
extern userptr_t acpi_find ( uint32_t signature, unsigned int index );
|
||||
extern int acpi_sx ( uint32_t signature );
|
||||
extern void acpi_add ( struct acpi_descriptor *desc );
|
||||
extern void acpi_del ( struct acpi_descriptor *desc );
|
||||
|
||||
@ -15,4 +15,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ACPI_PREFIX_efi __efi_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Locate ACPI table
|
||||
*
|
||||
* @v signature Requested table signature
|
||||
* @v index Requested index of table with this signature
|
||||
* @ret table Table, or UNULL if not found
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) userptr_t
|
||||
ACPI_INLINE ( efi, acpi_find ) ( uint32_t signature, unsigned int index ) {
|
||||
|
||||
return acpi_find_via_rsdt ( signature, index );
|
||||
}
|
||||
|
||||
#endif /* _IPXE_EFI_ACPI_H */
|
||||
|
||||
86
src/include/ipxe/linux_api.h
Normal file
86
src/include/ipxe/linux_api.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef _IPXE_LINUX_API_H
|
||||
#define _IPXE_LINUX_API_H
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>.
|
||||
* Copyright (C) 2021 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Linux host API
|
||||
*
|
||||
* This file is included from both the iPXE build environment and the
|
||||
* host build environment.
|
||||
*
|
||||
*/
|
||||
|
||||
#if __STDC_HOSTED__
|
||||
#define __asmcall
|
||||
#define FILE_LICENCE(x)
|
||||
#endif
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if ! __STDC_HOSTED__
|
||||
#define __KERNEL_STRICT_NAMES
|
||||
#include <linux/time.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/fs.h>
|
||||
#define MAP_FAILED ( ( void * ) -1 )
|
||||
#endif
|
||||
|
||||
struct sockaddr;
|
||||
|
||||
extern int linux_errno;
|
||||
extern int linux_argc;
|
||||
extern char **linux_argv;
|
||||
|
||||
extern int __asmcall linux_open ( const char *pathname, int flags, ... );
|
||||
extern int __asmcall linux_close ( int fd );
|
||||
extern off_t __asmcall linux_lseek ( int fd, off_t offset, int whence );
|
||||
extern ssize_t __asmcall linux_read ( int fd, void *buf, size_t count );
|
||||
extern ssize_t __asmcall linux_write ( int fd, const void *buf, size_t count );
|
||||
extern int __asmcall linux_fcntl ( int fd, int cmd, ... );
|
||||
extern int __asmcall linux_ioctl ( int fd, unsigned long request, ... );
|
||||
extern int __asmcall linux_poll ( struct pollfd *fds, unsigned int nfds,
|
||||
int timeout );
|
||||
extern int __asmcall linux_nanosleep ( const struct timespec *req,
|
||||
struct timespec *rem );
|
||||
extern int __asmcall linux_usleep ( unsigned int usec );
|
||||
extern int __asmcall linux_gettimeofday ( struct timeval *tv,
|
||||
struct timezone *tz );
|
||||
extern void * __asmcall linux_mmap ( void *addr, size_t length, int prot,
|
||||
int flags, int fd, off_t offset );
|
||||
extern void * __asmcall linux_mremap ( void *old_address, size_t old_size,
|
||||
size_t new_size, int flags, ... );
|
||||
extern int __asmcall linux_munmap ( void *addr, size_t length );
|
||||
extern int __asmcall linux_socket ( int domain, int type, int protocol );
|
||||
extern int __asmcall linux_bind ( int sockfd, const struct sockaddr *addr,
|
||||
size_t addrlen );
|
||||
extern ssize_t __asmcall linux_sendto ( int sockfd, const void *buf,
|
||||
size_t len, int flags,
|
||||
const struct sockaddr *dest_addr,
|
||||
size_t addrlen );
|
||||
extern const char * __asmcall linux_strerror ( int linux_errno );
|
||||
|
||||
#endif /* _IPXE_LINUX_API_H */
|
||||
@ -15,8 +15,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ACPI_PREFIX_null __null_
|
||||
#endif
|
||||
|
||||
static inline __always_inline userptr_t
|
||||
ACPI_INLINE ( null, acpi_find_rsdt ) ( void ) {
|
||||
static inline __attribute__ (( always_inline )) userptr_t
|
||||
ACPI_INLINE ( null, acpi_find ) ( uint32_t signature __unused,
|
||||
unsigned int index __unused ) {
|
||||
|
||||
return UNULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1,81 +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 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_API_H
|
||||
#define _LINUX_API_H
|
||||
|
||||
/** * @file
|
||||
*
|
||||
* Linux API prototypes.
|
||||
* Most of the functions map directly to linux syscalls and are the equivalent
|
||||
* of POSIX functions with the linux_ prefix removed.
|
||||
*/
|
||||
|
||||
FILE_LICENCE(GPL2_OR_LATER);
|
||||
|
||||
#include <bits/linux_api.h>
|
||||
#include <bits/linux_api_platform.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define __KERNEL_STRICT_NAMES
|
||||
#include <linux/types.h>
|
||||
#include <linux/posix_types.h>
|
||||
typedef __kernel_pid_t pid_t;
|
||||
typedef __kernel_suseconds_t suseconds_t;
|
||||
typedef __kernel_loff_t loff_t;
|
||||
#include <linux/time.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/poll.h>
|
||||
typedef unsigned long nfds_t;
|
||||
typedef uint32_t useconds_t;
|
||||
typedef uint32_t socklen_t;
|
||||
struct sockaddr;
|
||||
#define MAP_FAILED ( ( void * ) -1 )
|
||||
#define SEEK_SET 0
|
||||
|
||||
extern long linux_syscall ( int number, ... );
|
||||
|
||||
extern int linux_open ( const char *pathname, int flags );
|
||||
extern int linux_close ( int fd );
|
||||
extern off_t linux_lseek ( int fd, off_t offset, int whence );
|
||||
extern __kernel_ssize_t linux_read ( int fd, void *buf, __kernel_size_t count );
|
||||
extern __kernel_ssize_t linux_write ( int fd, const void *buf,
|
||||
__kernel_size_t count );
|
||||
extern int linux_fcntl ( int fd, int cmd, ... );
|
||||
extern int linux_ioctl ( int fd, int request, ... );
|
||||
extern int linux_poll ( struct pollfd *fds, nfds_t nfds, int timeout );
|
||||
extern int linux_nanosleep ( const struct timespec *req, struct timespec *rem );
|
||||
extern int linux_usleep ( useconds_t usec );
|
||||
extern int linux_gettimeofday ( struct timeval *tv, struct timezone *tz );
|
||||
extern void * linux_mmap ( void *addr, __kernel_size_t length, int prot,
|
||||
int flags, int fd, off_t offset );
|
||||
extern void * linux_mremap ( void *old_address, __kernel_size_t old_size,
|
||||
__kernel_size_t new_size, int flags );
|
||||
extern int linux_munmap ( void *addr, __kernel_size_t length );
|
||||
extern int linux_socket ( int domain, int type_, int protocol );
|
||||
extern int linux_bind ( int fd, const struct sockaddr *addr,
|
||||
socklen_t addrlen );
|
||||
extern ssize_t linux_sendto ( int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *daddr, socklen_t addrlen );
|
||||
|
||||
extern const char * linux_strerror ( int errnum );
|
||||
|
||||
#endif /* _LINUX_API_H */
|
||||
@ -54,3 +54,4 @@ static userptr_t efi_find_rsdt ( void ) {
|
||||
}
|
||||
|
||||
PROVIDE_ACPI ( efi, acpi_find_rsdt, efi_find_rsdt );
|
||||
PROVIDE_ACPI_INLINE ( efi, acpi_find );
|
||||
|
||||
373
src/interface/linux/linux_api.c
Normal file
373
src/interface/linux/linux_api.c
Normal file
@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>.
|
||||
* Copyright (C) 2021 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 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.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <poll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Linux host API
|
||||
*
|
||||
*/
|
||||
|
||||
/** Construct prefixed symbol name */
|
||||
#define _C1( x, y ) x ## y
|
||||
#define _C2( x, y ) _C1 ( x, y )
|
||||
|
||||
/** Construct prefixed symbol name for iPXE symbols */
|
||||
#define IPXE_SYM( symbol ) _C2 ( SYMBOL_PREFIX, symbol )
|
||||
|
||||
/** Provide a prefixed symbol alias visible to iPXE code */
|
||||
#define PROVIDE_IPXE_SYM( symbol ) \
|
||||
extern typeof ( symbol ) IPXE_SYM ( symbol ) \
|
||||
__attribute__ (( alias ( #symbol) ))
|
||||
|
||||
/** Most recent system call error */
|
||||
int linux_errno __attribute__ (( nocommon ));
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Host entry point
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
extern int IPXE_SYM ( _linux_start ) ( int argc, char **argv );
|
||||
|
||||
/**
|
||||
* Main entry point
|
||||
*
|
||||
* @v argc Argument count
|
||||
* @v argv Argument list
|
||||
* @ret rc Exit status
|
||||
*/
|
||||
int main ( int argc, char **argv ) {
|
||||
|
||||
return IPXE_SYM ( _linux_start ) ( argc, argv );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* System call wrappers
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrap open()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_open ( const char *pathname, int flags, ... ) {
|
||||
va_list args;
|
||||
mode_t mode;
|
||||
int ret;
|
||||
|
||||
va_start ( args, flags );
|
||||
mode = va_arg ( args, mode_t );
|
||||
va_end ( args );
|
||||
ret = open ( pathname, flags, mode );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap close()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_close ( int fd ) {
|
||||
int ret;
|
||||
|
||||
ret = close ( fd );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap lseek()
|
||||
*
|
||||
*/
|
||||
off_t __asmcall linux_lseek ( int fd, off_t offset, int whence ) {
|
||||
off_t ret;
|
||||
|
||||
ret = lseek ( fd, offset, whence );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap read()
|
||||
*
|
||||
*/
|
||||
ssize_t __asmcall linux_read ( int fd, void *buf, size_t count ) {
|
||||
ssize_t ret;
|
||||
|
||||
ret = read ( fd, buf, count );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap write()
|
||||
*
|
||||
*/
|
||||
ssize_t __asmcall linux_write ( int fd, const void *buf, size_t count ) {
|
||||
ssize_t ret;
|
||||
|
||||
ret = write ( fd, buf, count );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap fcntl()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_fcntl ( int fd, int cmd, ... ) {
|
||||
va_list args;
|
||||
long arg;
|
||||
int ret;
|
||||
|
||||
va_start ( args, cmd );
|
||||
arg = va_arg ( args, long );
|
||||
va_end ( args );
|
||||
ret = fcntl ( fd, cmd, arg );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap ioctl()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_ioctl ( int fd, unsigned long request, ... ) {
|
||||
va_list args;
|
||||
void *arg;
|
||||
int ret;
|
||||
|
||||
va_start ( args, request );
|
||||
arg = va_arg ( args, void * );
|
||||
va_end ( args );
|
||||
ret = ioctl ( fd, request, arg );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap poll()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_poll ( struct pollfd *fds, unsigned int nfds,
|
||||
int timeout ) {
|
||||
int ret;
|
||||
|
||||
ret = poll ( fds, nfds, timeout );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap nanosleep()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_nanosleep ( const struct timespec *req,
|
||||
struct timespec *rem ) {
|
||||
int ret;
|
||||
|
||||
ret = nanosleep ( req, rem );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap usleep()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_usleep ( unsigned int usec ) {
|
||||
int ret;
|
||||
|
||||
ret = usleep ( usec );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap gettimeofday()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_gettimeofday ( struct timeval *tv, struct timezone *tz ) {
|
||||
int ret;
|
||||
|
||||
ret = gettimeofday ( tv, tz );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap mmap()
|
||||
*
|
||||
*/
|
||||
void * __asmcall linux_mmap ( void *addr, size_t length, int prot, int flags,
|
||||
int fd, off_t offset ) {
|
||||
void *ret;
|
||||
|
||||
ret = mmap ( addr, length, prot, flags, fd, offset );
|
||||
if ( ret == MAP_FAILED )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap mremap()
|
||||
*
|
||||
*/
|
||||
void * __asmcall linux_mremap ( void *old_address, size_t old_size,
|
||||
size_t new_size, int flags, ... ) {
|
||||
va_list args;
|
||||
void *new_address;
|
||||
void *ret;
|
||||
|
||||
va_start ( args, flags );
|
||||
new_address = va_arg ( args, void * );
|
||||
va_end ( args );
|
||||
ret = mremap ( old_address, old_size, new_size, flags, new_address );
|
||||
if ( ret == MAP_FAILED )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap munmap()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_munmap ( void *addr, size_t length ) {
|
||||
int ret;
|
||||
|
||||
ret = munmap ( addr, length );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap socket()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_socket ( int domain, int type, int protocol ) {
|
||||
int ret;
|
||||
|
||||
ret = socket ( domain, type, protocol );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap bind()
|
||||
*
|
||||
*/
|
||||
int __asmcall linux_bind ( int sockfd, const struct sockaddr *addr,
|
||||
size_t addrlen ) {
|
||||
int ret;
|
||||
|
||||
ret = bind ( sockfd, addr, addrlen );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap sendto()
|
||||
*
|
||||
*/
|
||||
ssize_t __asmcall linux_sendto ( int sockfd, const void *buf, size_t len,
|
||||
int flags, const struct sockaddr *dest_addr,
|
||||
size_t addrlen ) {
|
||||
ssize_t ret;
|
||||
|
||||
ret = sendto ( sockfd, buf, len, flags, dest_addr, addrlen );
|
||||
if ( ret == -1 )
|
||||
linux_errno = errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* C library wrappers
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrap strerror()
|
||||
*
|
||||
*/
|
||||
const char * __asmcall linux_strerror ( int linux_errno ) {
|
||||
|
||||
return strerror ( linux_errno );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Symbol aliases
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
PROVIDE_IPXE_SYM ( linux_errno );
|
||||
PROVIDE_IPXE_SYM ( linux_open );
|
||||
PROVIDE_IPXE_SYM ( linux_close );
|
||||
PROVIDE_IPXE_SYM ( linux_lseek );
|
||||
PROVIDE_IPXE_SYM ( linux_read );
|
||||
PROVIDE_IPXE_SYM ( linux_write );
|
||||
PROVIDE_IPXE_SYM ( linux_fcntl );
|
||||
PROVIDE_IPXE_SYM ( linux_ioctl );
|
||||
PROVIDE_IPXE_SYM ( linux_poll );
|
||||
PROVIDE_IPXE_SYM ( linux_nanosleep );
|
||||
PROVIDE_IPXE_SYM ( linux_usleep );
|
||||
PROVIDE_IPXE_SYM ( linux_gettimeofday );
|
||||
PROVIDE_IPXE_SYM ( linux_mmap );
|
||||
PROVIDE_IPXE_SYM ( linux_mremap );
|
||||
PROVIDE_IPXE_SYM ( linux_munmap );
|
||||
PROVIDE_IPXE_SYM ( linux_socket );
|
||||
PROVIDE_IPXE_SYM ( linux_bind );
|
||||
PROVIDE_IPXE_SYM ( linux_sendto );
|
||||
PROVIDE_IPXE_SYM ( linux_strerror );
|
||||
@ -28,7 +28,7 @@ FILE_LICENCE(GPL2_OR_LATER);
|
||||
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/keys.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
|
||||
#include <linux/termios.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
@ -31,7 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
#include <ipxe/entropy.h>
|
||||
|
||||
/** Entropy source filename */
|
||||
|
||||
@ -21,7 +21,7 @@ FILE_LICENCE(GPL2_OR_LATER);
|
||||
|
||||
#include <ipxe/nap.h>
|
||||
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
|
||||
@ -26,7 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <byteswap.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
#include <ipxe/linux.h>
|
||||
#include <ipxe/pci.h>
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
#include <ipxe/linux.h>
|
||||
#include <ipxe/smbios.h>
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
#include <ipxe/time.h>
|
||||
|
||||
/**
|
||||
|
||||
@ -21,7 +21,7 @@ FILE_LICENCE(GPL2_OR_LATER);
|
||||
#include <stddef.h>
|
||||
#include <ipxe/timer.h>
|
||||
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
|
||||
@ -29,7 +29,7 @@ FILE_LICENCE(GPL2_OR_LATER);
|
||||
#include <assert.h>
|
||||
#include <ipxe/umalloc.h>
|
||||
|
||||
#include <linux_api.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
|
||||
/** Special address returned for empty allocations */
|
||||
#define NOWHERE ((void *)-1)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
|
||||
* Copyright (C) 2021 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
|
||||
@ -13,19 +13,26 @@
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _HCI_LINUX_ARGS_H
|
||||
#define _HCI_LINUX_ARGS_H
|
||||
|
||||
FILE_LICENCE(GPL2_OR_LATER);
|
||||
#include <stdlib.h>
|
||||
#include <ipxe/linux_api.h>
|
||||
|
||||
/**
|
||||
* Save argc and argv for later access.
|
||||
* Linux entry point
|
||||
*
|
||||
* To be called by linuxprefix
|
||||
* @v argc Argument count
|
||||
* @v argv Argument list
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
extern __asmcall void save_args(int argc, char **argv);
|
||||
int __asmcall _linux_start ( int argc, char **argv ) {
|
||||
|
||||
#endif /* _HCI_LINUX_ARGS_H */
|
||||
/* Store command-line arguments */
|
||||
linux_argc = argc;
|
||||
linux_argv = argv;
|
||||
|
||||
/* Run iPXE */
|
||||
return main();
|
||||
}
|
||||
Reference in New Issue
Block a user