mirror of https://github.com/ipxe/ipxe.git
Merge branch 'ipxe:master' into QRcode
commit
3b77a70782
|
@ -0,0 +1,71 @@
|
|||
name: Build
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
|
||||
x86:
|
||||
name: x86
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
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 libc6-dbg:i386 valgrind
|
||||
- name: Build (BIOS)
|
||||
run: |
|
||||
make -j 4 -C src
|
||||
- name: Build (Everything)
|
||||
run: |
|
||||
make -j 4 -C src everything
|
||||
- name: Test
|
||||
run: |
|
||||
valgrind ./src/bin-i386-linux/tests.linux
|
||||
valgrind ./src/bin-x86_64-linux/tests.linux
|
||||
|
||||
arm32:
|
||||
name: ARM32
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux gcc-arm-none-eabi
|
||||
- name: Build
|
||||
run: |
|
||||
make -j 4 -C src CROSS=arm-none-eabi- \
|
||||
bin-arm32-efi/intel.efi \
|
||||
bin-arm32-efi/intel.usb \
|
||||
bin-arm32-efi/intel.iso
|
||||
|
||||
arm64:
|
||||
name: ARM64
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux gcc-aarch64-linux-gnu
|
||||
- name: Build
|
||||
run: |
|
||||
make -j 4 -C src CROSS=aarch64-linux-gnu- \
|
||||
bin-arm64-efi/ipxe.efi \
|
||||
bin-arm64-efi/ipxe.usb \
|
||||
bin-arm64-efi/ipxe.iso
|
|
@ -0,0 +1,37 @@
|
|||
name: Coverity Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- coverity_scan
|
||||
|
||||
jobs:
|
||||
submit:
|
||||
name: Submit
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
- name: Download Coverity Scan
|
||||
run: |
|
||||
curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
|
||||
--form project=${{ github.repository }} \
|
||||
--output coverity.tar.gz \
|
||||
https://scan.coverity.com/download/cxx/linux64
|
||||
mkdir -p /opt/coverity
|
||||
sudo tar xvzf coverity.tar.gz --strip 1 --directory /opt/coverity
|
||||
- name: Build via Coverity Scan
|
||||
run: |
|
||||
make -C src bin/deps
|
||||
/opt/coverity/bin/cov-build --dir cov-int make -C src bin/blib.a
|
||||
- name: Create submission
|
||||
run : |
|
||||
tar cvzf cov-int.tar.gz cov-int
|
||||
- name: Submit to Coverity Scan
|
||||
run: |
|
||||
curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
|
||||
--form email=${{ secrets.COVERITY_SCAN_EMAIL }} \
|
||||
--form file=@cov-int.tar.gz \
|
||||
--form version=${{ github.sha }} \
|
||||
--form description=${{ github.ref }} \
|
||||
https://scan.coverity.com/builds?project=${{ github.repository }}
|
57
.travis.yml
57
.travis.yml
|
@ -1,57 +0,0 @@
|
|||
dist: trusty
|
||||
|
||||
sudo: false
|
||||
|
||||
git:
|
||||
depth: false
|
||||
|
||||
language: c
|
||||
|
||||
cache: ccache
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- binutils-dev
|
||||
- liblzma-dev
|
||||
- syslinux
|
||||
- genisoimage
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "ipxe/ipxe"
|
||||
version: $TRAVIS_COMMIT
|
||||
build_command_prepend: "make -C src bin/deps"
|
||||
build_command: "make -C src bin/blib.a"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
env:
|
||||
global:
|
||||
- MAKEFLAGS="-j 4"
|
||||
|
||||
script:
|
||||
- make -C src bin/blib.a
|
||||
- make -C src bin/ipxe.pxe
|
||||
- make -C src bin/ipxe.usb
|
||||
- make -C src bin/ipxe.iso
|
||||
- make -C src bin/8086100e.mrom
|
||||
- make -C src bin-x86_64-pcbios/blib.a
|
||||
- make -C src bin-x86_64-pcbios/ipxe.pxe
|
||||
- make -C src bin-x86_64-pcbios/ipxe.usb
|
||||
- make -C src bin-x86_64-pcbios/ipxe.iso
|
||||
- make -C src bin-x86_64-pcbios/8086100e.mrom
|
||||
- make -C src bin-x86_64-efi/blib.a
|
||||
- make -C src bin-x86_64-efi/ipxe.efi
|
||||
- make -C src bin-x86_64-efi/intel.efidrv
|
||||
- make -C src bin-x86_64-efi/intel.efirom
|
||||
- make -C src bin-i386-efi/blib.a
|
||||
- make -C src bin-i386-efi/ipxe.efi
|
||||
- make -C src bin-i386-efi/intel.efidrv
|
||||
- make -C src bin-i386-efi/intel.efirom
|
||||
- make -C src bin-x86_64-linux/blib.a
|
||||
- make -C src bin-x86_64-linux/tap.linux
|
||||
- make -C src bin-x86_64-linux/af_packet.linux
|
||||
- make -C src bin-x86_64-linux/tests.linux
|
||||
- ./src/bin-x86_64-linux/tests.linux
|
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from base64 import b64encode
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import date
|
||||
from hashlib import sha256
|
||||
from itertools import count
|
||||
import subprocess
|
||||
|
||||
import boto3
|
||||
|
||||
BLOCKSIZE = 512 * 1024
|
||||
|
||||
|
||||
def detect_architecture(image):
|
||||
"""Detect CPU architecture"""
|
||||
mdir = subprocess.run(['mdir', '-b', '-i', image, '::/EFI/BOOT'],
|
||||
capture_output=True)
|
||||
if any(b'BOOTAA64.EFI' in x for x in mdir.stdout.splitlines()):
|
||||
return 'arm64'
|
||||
return 'x86_64'
|
||||
|
||||
|
||||
def create_snapshot(region, description, image):
|
||||
"""Create an EBS snapshot"""
|
||||
client = boto3.client('ebs', region_name=region)
|
||||
snapshot = client.start_snapshot(VolumeSize=1,
|
||||
Description=description)
|
||||
snapshot_id = snapshot['SnapshotId']
|
||||
with open(image, 'rb') as fh:
|
||||
for block in count():
|
||||
data = fh.read(BLOCKSIZE)
|
||||
if not data:
|
||||
break
|
||||
data = data.ljust(BLOCKSIZE, b'\0')
|
||||
checksum = b64encode(sha256(data).digest()).decode()
|
||||
client.put_snapshot_block(SnapshotId=snapshot_id,
|
||||
BlockIndex=block,
|
||||
BlockData=data,
|
||||
DataLength=BLOCKSIZE,
|
||||
Checksum=checksum,
|
||||
ChecksumAlgorithm='SHA256')
|
||||
client.complete_snapshot(SnapshotId=snapshot_id,
|
||||
ChangedBlocksCount=block)
|
||||
return snapshot_id
|
||||
|
||||
|
||||
def import_image(region, name, architecture, image, public):
|
||||
"""Import an AMI image"""
|
||||
client = boto3.client('ec2', region_name=region)
|
||||
resource = boto3.resource('ec2', region_name=region)
|
||||
description = '%s (%s)' % (name, architecture)
|
||||
snapshot_id = create_snapshot(region=region, description=description,
|
||||
image=image)
|
||||
client.get_waiter('snapshot_completed').wait(SnapshotIds=[snapshot_id])
|
||||
image = client.register_image(Architecture=architecture,
|
||||
BlockDeviceMappings=[{
|
||||
'DeviceName': '/dev/sda1',
|
||||
'Ebs': {
|
||||
'SnapshotId': snapshot_id,
|
||||
'VolumeType': 'standard',
|
||||
},
|
||||
}],
|
||||
EnaSupport=True,
|
||||
Name=description,
|
||||
RootDeviceName='/dev/sda1',
|
||||
SriovNetSupport='simple',
|
||||
VirtualizationType='hvm')
|
||||
image_id = image['ImageId']
|
||||
client.get_waiter('image_available').wait(ImageIds=[image_id])
|
||||
if public:
|
||||
resource.Image(image_id).modify_attribute(Attribute='launchPermission',
|
||||
OperationType='add',
|
||||
UserGroups=['all'])
|
||||
return image_id
|
||||
|
||||
|
||||
def launch_link(region, image_id):
|
||||
"""Construct a web console launch link"""
|
||||
return ("https://console.aws.amazon.com/ec2/v2/home?"
|
||||
"region=%s#LaunchInstanceWizard:ami=%s" % (region, image_id))
|
||||
|
||||
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="Import AWS EC2 image (AMI)")
|
||||
parser.add_argument('--name', '-n',
|
||||
help="Image name")
|
||||
parser.add_argument('--public', '-p', action='store_true',
|
||||
help="Make image public")
|
||||
parser.add_argument('--region', '-r', action='append',
|
||||
help="AWS region(s)")
|
||||
parser.add_argument('--wiki', '-w', metavar='FILE',
|
||||
help="Generate Dokuwiki table")
|
||||
parser.add_argument('image', nargs='+', help="iPXE disk image")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Detect CPU architectures
|
||||
architectures = {image: detect_architecture(image) for image in args.image}
|
||||
|
||||
# Use default name if none specified
|
||||
if not args.name:
|
||||
args.name = 'iPXE (%s)' % date.today().strftime('%Y-%m-%d')
|
||||
|
||||
# Use all regions if none specified
|
||||
if not args.region:
|
||||
args.region = sorted(x['RegionName'] for x in
|
||||
boto3.client('ec2').describe_regions()['Regions'])
|
||||
|
||||
# Use one thread per import to maximise parallelism
|
||||
imports = [(region, image) for region in args.region for image in args.image]
|
||||
with ThreadPoolExecutor(max_workers=len(imports)) as executor:
|
||||
futures = {executor.submit(import_image,
|
||||
region=region,
|
||||
name=args.name,
|
||||
architecture=architectures[image],
|
||||
image=image,
|
||||
public=args.public): (region, image)
|
||||
for region, image in imports}
|
||||
results = {futures[future]: future.result()
|
||||
for future in as_completed(futures)}
|
||||
|
||||
# Construct Dokuwiki table
|
||||
wikitab = ["^ AWS region ^ CPU architecture ^ AMI ID ^\n"] + list(
|
||||
"| ''%s'' | ''%s'' | ''[[%s|%s]]'' |\n" % (
|
||||
region,
|
||||
architectures[image],
|
||||
launch_link(region, results[(region, image)]),
|
||||
results[(region, image)],
|
||||
) for region, image in imports)
|
||||
if args.wiki:
|
||||
with open(args.wiki, 'wt') as fh:
|
||||
fh.writelines(wikitab)
|
||||
|
||||
# Show created images
|
||||
for region, image in imports:
|
||||
print("%s %s %s %s" % (
|
||||
region, image, architectures[image], results[(region, image)]
|
||||
))
|
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,7 @@ LDFLAGS :=
|
|||
HOST_CFLAGS :=
|
||||
MAKEDEPS := Makefile
|
||||
CROSS_COMPILE ?= $(CROSS)
|
||||
SYMBOL_PREFIX :=
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
|
@ -48,7 +49,6 @@ ELF2EFI32 := ./util/elf2efi32
|
|||
ELF2EFI64 := ./util/elf2efi64
|
||||
EFIROM := ./util/efirom
|
||||
EFIFATBIN := ./util/efifatbin
|
||||
ICCFIX := ./util/iccfix
|
||||
EINFO := ./util/einfo
|
||||
GENKEYMAP := ./util/genkeymap.pl
|
||||
DOXYGEN := doxygen
|
||||
|
@ -74,6 +74,7 @@ SRCDIRS += drivers/net/phantom
|
|||
SRCDIRS += drivers/net/vxge
|
||||
SRCDIRS += drivers/net/efi
|
||||
SRCDIRS += drivers/net/tg3
|
||||
SRCDIRS += drivers/net/bnxt
|
||||
SRCDIRS += drivers/net/sfc
|
||||
SRCDIRS += drivers/block
|
||||
SRCDIRS += drivers/nvs
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Enable stack protection if available
|
||||
#
|
||||
SPG_TEST = $(CC) -fstack-protector-strong -mstack-protector-guard=global \
|
||||
-x c -c /dev/null -o /dev/null >/dev/null 2>&1
|
||||
SPG_FLAGS := $(shell $(SPG_TEST) && $(ECHO) '-fstack-protector-strong ' \
|
||||
'-mstack-protector-guard=global')
|
||||
CFLAGS += $(SPG_FLAGS)
|
||||
|
||||
# The EFI linker script
|
||||
#
|
||||
LDSCRIPT = scripts/efi.lds
|
||||
|
@ -35,12 +43,13 @@ $(BIN)/%.drv.efi : $(BIN)/%.efidrv
|
|||
|
||||
$(BIN)/%.efirom : $(BIN)/%.efidrv $(EFIROM)
|
||||
$(QM)$(ECHO) " [FINISH] $@"
|
||||
$(Q)$(EFIROM) -v $(TGT_PCI_VENDOR) -d $(TGT_PCI_DEVICE) $< $@
|
||||
$(Q)$(EFIROM) -v $(firstword $(TGT_PCI_VENDOR) 0) \
|
||||
-d $(firstword $(TGT_PCI_DEVICE) 0) -c $< $@
|
||||
|
||||
$(BIN)/efidrv.cab : $(BIN)/alldrv.efis # $(ALL_drv.efi) is not yet defined
|
||||
$(QM)$(ECHO) " [CAB] $@"
|
||||
$(Q)$(LCAB) -n -q $(ALL_drv.efi) $@
|
||||
|
||||
$(BIN)/%.usb : $(BIN)/%.efi
|
||||
$(QM)$(ECHO) " [GENEFIDSK] $@"
|
||||
$(Q)bash util/genefidsk -o $@ -b $(EFI_BOOT_FILE) $<
|
||||
$(BIN)/%.iso $(BIN)/%.usb : $(BIN)/%.efi util/genfsimg
|
||||
$(QM)$(ECHO) " [GENFSIMG] $@"
|
||||
$(Q)util/genfsimg -o $@ $<
|
||||
|
|
|
@ -76,9 +76,7 @@ CCDEFS := $(shell $(CC) -E -x c -c /dev/null -dM | cut -d" " -f2)
|
|||
ccdefs:
|
||||
@$(ECHO) $(CCDEFS)
|
||||
|
||||
ifeq ($(filter __ICC,$(CCDEFS)),__ICC)
|
||||
CCTYPE := icc
|
||||
else
|
||||
ifeq ($(filter __GNUC__,$(CCDEFS)),__GNUC__)
|
||||
CCTYPE := gcc
|
||||
endif
|
||||
cctype:
|
||||
|
@ -113,6 +111,13 @@ $(warning Use GNU ld instead)
|
|||
$(error Unsuitable build environment found)
|
||||
endif
|
||||
|
||||
OBJCOPY_ETC_BANNER := $(shell $(OBJCOPY) --version | grep 'elftoolchain')
|
||||
ifneq ($(OBJCOPY_ETC_BANNER),)
|
||||
$(warning The elftoolchain objcopy is unsuitable for building iPXE)
|
||||
$(warning Use binutils objcopy instead)
|
||||
$(error Unsuitable build environment found)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Check if $(eval ...) is available to use
|
||||
|
@ -146,17 +151,6 @@ define NEWLINE
|
|||
|
||||
endef
|
||||
|
||||
# Some widespread patched versions of gcc include -fstack-protector by
|
||||
# default, even when -ffreestanding is specified. We therefore need
|
||||
# to disable -fstack-protector if the compiler supports it.
|
||||
#
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
SP_TEST = $(CC) -fno-stack-protector -x c -c /dev/null \
|
||||
-o /dev/null >/dev/null 2>&1
|
||||
SP_FLAGS := $(shell $(SP_TEST) && $(ECHO) '-fno-stack-protector')
|
||||
WORKAROUND_CFLAGS += $(SP_FLAGS)
|
||||
endif
|
||||
|
||||
# gcc 4.4 generates .eh_frame sections by default, which distort the
|
||||
# output of "size". Inhibit this.
|
||||
#
|
||||
|
@ -353,7 +347,7 @@ arch :
|
|||
# Determine build platform
|
||||
DEFAULT_PLATFORM := pcbios
|
||||
PLATFORM := $(firstword $(BIN_PLATFORM) $(DEFAULT_PLATFORM))
|
||||
CFLAGS += -DPLATFORM=$(PLATFORM)
|
||||
CFLAGS += -DPLATFORM=$(PLATFORM) -DPLATFORM_$(PLATFORM)
|
||||
platform :
|
||||
@$(ECHO) $(PLATFORM)
|
||||
|
||||
|
@ -378,6 +372,43 @@ INCDIRS += arch/$(ARCH)/include
|
|||
INCDIRS += arch/$(ARCH)/include/$(PLATFORM)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Especially ugly workarounds
|
||||
|
||||
# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
|
||||
# default. Note that gcc will exit *successfully* if it fails to
|
||||
# recognise an option that starts with "no", so we have to test for
|
||||
# output on stderr instead of checking the exit status.
|
||||
#
|
||||
# Current versions of gcc require -no-pie; older versions require
|
||||
# -nopie. We therefore test for both.
|
||||
#
|
||||
# This workaround must be determined only after the
|
||||
# architecture-specific Makefile has been included, since some
|
||||
# platforms (e.g. bin-x86_64-efi) will explicitly require the use of
|
||||
# -fpie.
|
||||
#
|
||||
ifeq ($(filter -fpie,$(CFLAGS)),)
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
|
||||
PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
|
||||
WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Some widespread patched versions of gcc include -fcf-protection=full
|
||||
# by default.
|
||||
#
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
CFP_TEST = $(CC) -fcf-protection=none -x c -c /dev/null -o /dev/null \
|
||||
>/dev/null 2>&1
|
||||
CFP_FLAGS := $(shell $(CFP_TEST) && $(ECHO) '-fcf-protection=none')
|
||||
WORKAROUND_CFLAGS += $(CFP_FLAGS)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Source file handling
|
||||
|
@ -415,6 +446,13 @@ ifdef BIN
|
|||
incdirs :
|
||||
@$(ECHO) $(INCDIRS)
|
||||
|
||||
# Inhibit -fstack-protector (which is implicitly enabled in some
|
||||
# patched gcc versions) unless explicitly mentioned in CFLAGS.
|
||||
#
|
||||
ifeq ($(findstring -fstack-protector,$(CFLAGS)),)
|
||||
CFLAGS += -fno-stack-protector
|
||||
endif
|
||||
|
||||
# Common flags
|
||||
#
|
||||
CFLAGS += $(foreach INC,$(INCDIRS),-I$(INC))
|
||||
|
@ -422,35 +460,10 @@ CFLAGS += -Os
|
|||
CFLAGS += -g
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
CFLAGS += -ffreestanding
|
||||
CFLAGS += -fcommon
|
||||
CFLAGS += -Wall -W -Wformat-nonliteral
|
||||
HOST_CFLAGS += -Wall -W -Wformat-nonliteral
|
||||
endif
|
||||
ifeq ($(CCTYPE),icc)
|
||||
CFLAGS += -fno-builtin
|
||||
CFLAGS += -no-ip
|
||||
CFLAGS += -no-gcc
|
||||
CFLAGS += -diag-disable 111 # Unreachable code
|
||||
CFLAGS += -diag-disable 128 # Unreachable loop
|
||||
CFLAGS += -diag-disable 170 # Array boundary checks
|
||||
CFLAGS += -diag-disable 177 # Unused functions
|
||||
CFLAGS += -diag-disable 181 # printf() format checks
|
||||
CFLAGS += -diag-disable 188 # enum strictness
|
||||
CFLAGS += -diag-disable 193 # Undefined preprocessor identifiers
|
||||
CFLAGS += -diag-disable 280 # switch ( constant )
|
||||
CFLAGS += -diag-disable 310 # K&R parameter lists
|
||||
CFLAGS += -diag-disable 424 # Extra semicolon
|
||||
CFLAGS += -diag-disable 589 # Declarations mid-code
|
||||
CFLAGS += -diag-disable 593 # Unused variables
|
||||
CFLAGS += -diag-disable 810 # Casting ints to smaller ints
|
||||
CFLAGS += -diag-disable 981 # Sequence point violations
|
||||
CFLAGS += -diag-disable 1292 # Ignored attributes
|
||||
CFLAGS += -diag-disable 1338 # void pointer arithmetic
|
||||
CFLAGS += -diag-disable 1361 # Variable-length arrays
|
||||
CFLAGS += -diag-disable 1418 # Missing prototypes
|
||||
CFLAGS += -diag-disable 1419 # Missing prototypes
|
||||
CFLAGS += -diag-disable 1599 # Hidden variables
|
||||
CFLAGS += -Wall -Wmissing-declarations
|
||||
endif
|
||||
CFLAGS += $(WORKAROUND_CFLAGS) $(EXTRA_CFLAGS)
|
||||
ASFLAGS += $(WORKAROUND_ASFLAGS) $(EXTRA_ASFLAGS)
|
||||
LDFLAGS += $(WORKAROUND_LDFLAGS) $(EXTRA_LDFLAGS)
|
||||
|
@ -464,35 +477,6 @@ ASFLAGS += --fatal-warnings
|
|||
HOST_CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
# Function trace recorder state in the last build. This is needed
|
||||
# in order to correctly rebuild whenever the function recorder is
|
||||
# enabled/disabled.
|
||||
#
|
||||
FNREC_STATE := $(BIN)/.fnrec.state
|
||||
ifeq ($(wildcard $(FNREC_STATE)),)
|
||||
FNREC_OLD := <invalid>
|
||||
else
|
||||
FNREC_OLD := $(shell cat $(FNREC_STATE))
|
||||
endif
|
||||
ifeq ($(FNREC_OLD),$(FNREC))
|
||||
$(FNREC_STATE) :
|
||||
else
|
||||
$(FNREC_STATE) : clean
|
||||
$(shell $(ECHO) "$(FNREC)" > $(FNREC_STATE))
|
||||
endif
|
||||
|
||||
VERYCLEANUP += $(FNREC_STATE)
|
||||
MAKEDEPS += $(FNREC_STATE)
|
||||
|
||||
ifeq ($(FNREC),1)
|
||||
# Enabling -finstrument-functions affects gcc's analysis and leads to spurious
|
||||
# warnings about use of uninitialised variables.
|
||||
#
|
||||
CFLAGS += -Wno-uninitialized
|
||||
CFLAGS += -finstrument-functions
|
||||
CFLAGS += -finstrument-functions-exclude-file-list=core/fnrec.c
|
||||
endif
|
||||
|
||||
# Enable per-item sections and section garbage collection. Note that
|
||||
# some older versions of gcc support -fdata-sections but treat it as
|
||||
# implying -fno-common, which would break our build. Some other older
|
||||
|
@ -543,16 +527,6 @@ OBJ_CFLAGS = $(CFLAGS_$(OBJECT)) -DOBJECT=$(subst -,_,$(OBJECT))
|
|||
$(BIN)/%.flags :
|
||||
@$(ECHO) $(OBJ_CFLAGS)
|
||||
|
||||
# ICC requires postprocessing objects to fix up table alignments
|
||||
#
|
||||
ifeq ($(CCTYPE),icc)
|
||||
POST_O = && $(ICCFIX) $@
|
||||
POST_O_DEPS := $(ICCFIX)
|
||||
else
|
||||
POST_O :=
|
||||
POST_O_DEPS :=
|
||||
endif
|
||||
|
||||
# Debug level calculations
|
||||
#
|
||||
DBGLVL_MAX = -DDBGLVL_MAX=$(firstword $(subst ., ,$(1)))
|
||||
|
@ -562,9 +536,9 @@ DBGLVL = $(call DBGLVL_MAX,$(1)) $(call DBGLVL_DFLT,$(1))
|
|||
# Rules for specific object types.
|
||||
#
|
||||
COMPILE_c = $(CC) $(CFLAGS) $(CFLAGS_c) $(OBJ_CFLAGS)
|
||||
RULE_c = $(Q)$(COMPILE_c) -c $< -o $@ $(POST_O)
|
||||
RULE_c = $(Q)$(COMPILE_c) -c $< -o $@
|
||||
RULE_c_to_ids.o = $(Q)$(ECHO_E) '$(OBJ_IDS_ASM_NL)' | $(ASSEMBLE_S) -o $@
|
||||
RULE_c_to_dbg%.o= $(Q)$(COMPILE_c) $(call DBGLVL,$*) -c $< -o $@ $(POST_O)
|
||||
RULE_c_to_dbg%.o= $(Q)$(COMPILE_c) $(call DBGLVL,$*) -c $< -o $@
|
||||
RULE_c_to_c = $(Q)$(COMPILE_c) -E -c $< > $@
|
||||
RULE_c_to_s = $(Q)$(COMPILE_c) -S -g0 -c $< -o $@
|
||||
|
||||
|
@ -804,6 +778,38 @@ include/ipxe/profile.h : $(PROFILE_LIST)
|
|||
|
||||
.PRECIOUS : include/ipxe/profile.h
|
||||
|
||||
# (Single-element) list of function recorder configuration
|
||||
#
|
||||
FNREC_LIST := $(BIN)/.fnrec.list
|
||||
ifeq ($(wildcard $(FNREC_LIST)),)
|
||||
FNREC_OLD := <invalid>
|
||||
else
|
||||
FNREC_OLD := $(shell cat $(FNREC_LIST))
|
||||
endif
|
||||
ifneq ($(FNREC_OLD),$(FNREC))
|
||||
$(shell $(ECHO) "$(FNREC)" > $(FNREC_LIST))
|
||||
endif
|
||||
|
||||
$(FNREC_LIST) : $(MAKEDEPS)
|
||||
|
||||
VERYCLEANUP += $(FNREC_LIST)
|
||||
|
||||
# Function recorder configuration
|
||||
#
|
||||
ifeq ($(FNREC),1)
|
||||
# Enabling -finstrument-functions affects gcc's analysis and leads to spurious
|
||||
# warnings about use of uninitialised variables.
|
||||
#
|
||||
CFLAGS += -Wno-uninitialized
|
||||
CFLAGS += -finstrument-functions
|
||||
CFLAGS += -finstrument-functions-exclude-file-list=core/fnrec.c
|
||||
endif
|
||||
|
||||
include/compiler.h : $(FNREC_LIST)
|
||||
$(Q)$(TOUCH) $@
|
||||
|
||||
.PRECIOUS : include/compiler.h
|
||||
|
||||
# These files use .incbin inline assembly to include a binary file.
|
||||
# Unfortunately ccache does not detect this dependency and caches
|
||||
# builds even when the binary file has changed.
|
||||
|
@ -859,7 +865,7 @@ define deps_template_parts
|
|||
@$(MKDIR) -p $(BIN)/deps/$(dir $(1))
|
||||
$(Q)$(CPP) $(CFLAGS) $(CFLAGS_$(2)) $(CFLAGS_$(3)) -DOBJECT=$(3) \
|
||||
-Wno-error -M $(1) -MG -MP | \
|
||||
sed 's/\.o\s*:/_DEPS +=/' > $(BIN)/deps/$(1).d
|
||||
sed 's/\.o[[:blank:]]*:/_DEPS +=/' > $(BIN)/deps/$(1).d
|
||||
endef
|
||||
|
||||
# rules_template : generate rules for a given source file
|
||||
|
@ -875,7 +881,7 @@ endef
|
|||
# $(3) is the source base name (e.g. "rtl8139")
|
||||
#
|
||||
define rules_template_parts
|
||||
$$(BIN)/$(3).o : $(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(3)_DEPS)
|
||||
$$(BIN)/$(3).o : $(1) $$(MAKEDEPS) $$($(3)_DEPS)
|
||||
$$(QM)$(ECHO) " [BUILD] $$@"
|
||||
$$(RULE_$(2))
|
||||
BOBJS += $$(BIN)/$(3).o
|
||||
|
@ -890,7 +896,7 @@ endef
|
|||
# $(4) is the destination type (e.g. "dbg%.o")
|
||||
#
|
||||
define rules_template_target
|
||||
$$(BIN)/$(3).$(4) : $(1) $$(MAKEDEPS) $$(POST_O_DEPS) $$($(3)_DEPS)
|
||||
$$(BIN)/$(3).$(4) : $(1) $$(MAKEDEPS) $$($(3)_DEPS)
|
||||
$$(QM)$(ECHO) " [BUILD] $$@"
|
||||
$$(RULE_$(2)_to_$(4))
|
||||
$(TGT)_OBJS += $$(BIN)/$(3).$(4)
|
||||
|
@ -1096,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.
|
||||
|
@ -1159,18 +1166,38 @@ BLIB = $(BIN)/blib.a
|
|||
$(BLIB) : $(BLIB_OBJS) $(BLIB_LIST) $(MAKEDEPS)
|
||||
$(Q)$(RM) $(BLIB)
|
||||
$(QM)$(ECHO) " [AR] $@"
|
||||
$(Q)$(AR) r $@ $(sort $(BLIB_OBJS))
|
||||
$(Q)$(RANLIB) $@
|
||||
$(Q)$(AR) rD $@ $(sort $(BLIB_OBJS))
|
||||
$(Q)$(OBJCOPY) --enable-deterministic-archives \
|
||||
--prefix-symbols=$(SYMBOL_PREFIX) $@
|
||||
$(Q)$(RANLIB) -D $@
|
||||
blib : $(BLIB)
|
||||
|
||||
# Command to generate build ID. Must be unique for each $(BIN)/%.tmp,
|
||||
# even within the same build run.
|
||||
#
|
||||
BUILD_ID_CMD := perl -e 'printf "0x%08x", int ( rand ( 0xffffffff ) );'
|
||||
# The build ID is supposed to be collision-free across all ROMs that
|
||||
# might ever end up installed in the same system. It doesn't just
|
||||
# disambiguate targets within a single build; it also disambiguates
|
||||
# different builds (such as builds for multiple ROMs all built from
|
||||
# the same blib.a).
|
||||
#
|
||||
BUILD_ID_CMD = cat $^ | cksum | awk '{print $$1}'
|
||||
|
||||
# Build timestamp
|
||||
#
|
||||
# Used as a means to automatically select the newest version of iPXE
|
||||
# if multiple iPXE drivers are loaded concurrently in a UEFI system.
|
||||
#
|
||||
# It gets rounded down to the nearest minute when used for this
|
||||
# purpose.
|
||||
#
|
||||
ifdef SOURCE_DATE_EPOCH
|
||||
BUILD_TIMESTAMP := $(SOURCE_DATE_EPOCH)
|
||||
else ifdef GITVERSION
|
||||
BUILD_TIMESTAMP := $(shell git log -1 --pretty=%ct)
|
||||
else
|
||||
BUILD_TIMESTAMP := $(shell date +%s)
|
||||
endif
|
||||
|
||||
# Build version
|
||||
#
|
||||
|
@ -1183,6 +1210,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.
|
||||
|
@ -1190,7 +1218,7 @@ $(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(GIT_INDEX)
|
|||
$(BIN)/%.tmp : $(BIN)/version.%.o $(BLIB) $(MAKEDEPS) $(LDSCRIPT)
|
||||
$(QM)$(ECHO) " [LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT) $(TGT_LD_FLAGS) $< $(BLIB) -o $@ \
|
||||
--defsym _build_id=`$(BUILD_ID_CMD)` \
|
||||
--defsym _build_id=$(shell $(BUILD_ID_CMD)) \
|
||||
--defsym _build_timestamp=$(BUILD_TIMESTAMP) \
|
||||
-Map $(BIN)/$*.tmp.map
|
||||
$(Q)$(OBJDUMP) -ht $@ | $(PERL) $(SORTOBJDUMP) >> $(BIN)/$*.tmp.map
|
||||
|
@ -1401,7 +1429,7 @@ $(ELF2EFI64) : util/elf2efi.c $(MAKEDEPS)
|
|||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -DEFI_TARGET64 $< -o $@
|
||||
CLEANUP += $(ELF2EFI64)
|
||||
|
||||
$(EFIROM) : util/efirom.c $(MAKEDEPS)
|
||||
$(EFIROM) : util/efirom.c util/eficompress.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(EFIROM)
|
||||
|
@ -1411,15 +1439,6 @@ $(EFIFATBIN) : util/efifatbin.c $(MAKEDEPS)
|
|||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(EFIFATBIN)
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# The ICC fixup utility
|
||||
#
|
||||
$(ICCFIX) : util/iccfix.c $(MAKEDEPS)
|
||||
$(QM)$(ECHO) " [HOSTCC] $@"
|
||||
$(Q)$(HOST_CC) $(HOST_CFLAGS) -idirafter include -o $@ $<
|
||||
CLEANUP += $(ICCFIX)
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# The error usage information utility
|
||||
|
@ -1559,13 +1578,14 @@ hci/keymap/keymap_%.c :
|
|||
#
|
||||
|
||||
ifeq ($(NUM_BINS),0)
|
||||
ALLBINS := bin{,-*}
|
||||
CLEANUP := $(patsubst $(BIN)/%,$(ALLBINS)/%,$(CLEANUP))
|
||||
VERYCLEANUP := $(patsubst $(BIN)/%,$(ALLBINS)/%,$(VERYCLEANUP))
|
||||
ALLBINS := bin bin-*
|
||||
ALLBIN = $(foreach B,$(ALLBINS),$(patsubst $(BIN)/%,$(B)/%,$(1)))
|
||||
CLEANUP := $(foreach C,$(CLEANUP),$(call ALLBIN,$(C)))
|
||||
VERYCLEANUP := $(foreach V,$(VERYCLEANUP),$(call ALLBIN,$(V)))
|
||||
endif
|
||||
|
||||
clean :
|
||||
$(RM) $(CLEANUP)
|
||||
$(RM) -r $(CLEANUP)
|
||||
|
||||
veryclean : clean
|
||||
$(RM) -r $(VERYCLEANUP)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# -*- 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)
|
||||
|
||||
# Check for libslirp
|
||||
#
|
||||
LIBSLIRP_TEST = $(CC) $(LINUX_CFLAGS) -x c /dev/null -nostartfiles \
|
||||
-include slirp/libslirp.h -lslirp \
|
||||
-o /dev/null >/dev/null 2>&1
|
||||
WITH_LIBSLIRP := $(shell $(LIBSLIRP_TEST) && $(ECHO) yes)
|
||||
ifneq ($(WITH_LIBSLIRP),)
|
||||
LINUX_CFLAGS += -DHAVE_LIBSLIRP
|
||||
LINUX_LIBS += -lslirp
|
||||
endif
|
||||
|
||||
# Host API wrapper
|
||||
#
|
||||
$(BIN)/linux_api.o : interface/linux/linux_api.c include/ipxe/linux_api.h \
|
||||
include/ipxe/slirp.h $(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 $@ $^ $(LINUX_LIBS)
|
|
@ -69,22 +69,6 @@ CFLAGS += -fshort-wchar
|
|||
#
|
||||
CFLAGS += -Ui386
|
||||
|
||||
# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
|
||||
# default. Note that gcc will exit *successfully* if it fails to
|
||||
# recognise an option that starts with "no", so we have to test for
|
||||
# output on stderr instead of checking the exit status.
|
||||
#
|
||||
# Current versions of gcc require -no-pie; older versions require
|
||||
# -nopie. We therefore test for both.
|
||||
#
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
|
||||
PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
|
||||
PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
|
||||
WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
|
||||
endif
|
||||
|
||||
# i386-specific directories containing source files
|
||||
#
|
||||
SRCDIRS += arch/i386/core
|
||||
|
|
|
@ -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
|
|
@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#ifndef ASSEMBLY
|
||||
|
||||
/** Declare a function with standard calling conventions */
|
||||
#define __asmcall __attribute__ (( used, cdecl, regparm(0) ))
|
||||
#define __asmcall __attribute__ (( cdecl, regparm(0) ))
|
||||
|
||||
/**
|
||||
* Declare a function with libgcc implicit linkage
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4,18 +4,15 @@
|
|||
#
|
||||
SRCDIRS += arch/x86/drivers/net
|
||||
|
||||
# The i386 linker script
|
||||
# The linker scripts
|
||||
#
|
||||
LDSCRIPT = arch/x86/scripts/pcbios.lds
|
||||
LDSCRIPT_PREFIX = arch/x86/scripts/prefixonly.lds
|
||||
|
||||
# Stop ld from complaining about our customised linker script
|
||||
#
|
||||
LDFLAGS += -N --no-check-sections
|
||||
|
||||
# Prefix always starts at address zero
|
||||
#
|
||||
LDFLAGS += --section-start=.prefix=0
|
||||
|
||||
# Media types.
|
||||
#
|
||||
MEDIA += rom
|
||||
|
@ -57,46 +54,11 @@ LIST_NAME_mrom := ROMS
|
|||
LIST_NAME_pcirom := ROMS
|
||||
LIST_NAME_isarom := ROMS
|
||||
|
||||
# Locations of isolinux files
|
||||
#
|
||||
SYSLINUX_DIR_LIST := \
|
||||
/usr/lib/syslinux \
|
||||
/usr/lib/syslinux/bios \
|
||||
/usr/lib/syslinux/modules/bios \
|
||||
/usr/share/syslinux \
|
||||
/usr/share/syslinux/bios \
|
||||
/usr/share/syslinux/modules/bios \
|
||||
/usr/local/share/syslinux \
|
||||
/usr/local/share/syslinux/bios \
|
||||
/usr/local/share/syslinux/modules/bios \
|
||||
/usr/lib/ISOLINUX
|
||||
ISOLINUX_BIN_LIST := \
|
||||
$(ISOLINUX_BIN) \
|
||||
$(patsubst %,%/isolinux.bin,$(SYSLINUX_DIR_LIST))
|
||||
LDLINUX_C32_LIST := \
|
||||
$(LDLINUX_C32) \
|
||||
$(patsubst %,%/ldlinux.c32,$(SYSLINUX_DIR_LIST))
|
||||
ISOLINUX_BIN = $(firstword $(wildcard $(ISOLINUX_BIN_LIST)))
|
||||
LDLINUX_C32 = $(firstword $(wildcard $(LDLINUX_C32_LIST)))
|
||||
|
||||
# rule to make a non-emulation ISO boot image
|
||||
# ISO or FAT filesystem images
|
||||
NON_AUTO_MEDIA += iso
|
||||
%iso: %lkrn util/geniso
|
||||
$(QM)$(ECHO) " [GENISO] $@"
|
||||
$(Q)ISOLINUX_BIN=$(ISOLINUX_BIN) LDLINUX_C32=$(LDLINUX_C32) \
|
||||
VERSION="$(VERSION)" bash util/geniso -o $@ $<
|
||||
|
||||
# rule to make a floppy emulation ISO boot image
|
||||
NON_AUTO_MEDIA += liso
|
||||
%liso: %lkrn util/geniso
|
||||
$(QM)$(ECHO) " [GENISO] $@"
|
||||
$(Q)VERSION="$(VERSION)" bash util/geniso -l -o $@ $<
|
||||
|
||||
# rule to make a syslinux floppy image (mountable, bootable)
|
||||
NON_AUTO_MEDIA += sdsk
|
||||
%sdsk: %lkrn util/gensdsk
|
||||
$(QM)$(ECHO) " [GENSDSK] $@"
|
||||
$(Q)bash util/gensdsk $@ $<
|
||||
$(BIN)/%.iso $(BIN)/%.sdsk: $(BIN)/%.lkrn util/genfsimg
|
||||
$(QM)$(ECHO) " [GENFSIMG] $@"
|
||||
$(Q)util/genfsimg -o $@ $<
|
||||
|
||||
# rule to write disk images to /dev/fd0
|
||||
NON_AUTO_MEDIA += fd0
|
||||
|
@ -108,12 +70,12 @@ NON_AUTO_MEDIA += fd0
|
|||
# Special target for building Master Boot Record binary
|
||||
$(BIN)/mbr.tmp : $(BIN)/mbr.o
|
||||
$(QM)$(ECHO) " [LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
|
||||
$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
|
||||
|
||||
# rule to make a USB disk image
|
||||
$(BIN)/usbdisk.tmp : $(BIN)/usbdisk.o
|
||||
$(QM)$(ECHO) " [LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
|
||||
$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
|
||||
|
||||
NON_AUTO_MEDIA += usb
|
||||
%usb: $(BIN)/usbdisk.bin %hd
|
||||
|
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <ipxe/dhcppkt.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
#include <realmode.h>
|
||||
#include <pxe_api.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Cached DHCP packet
|
||||
*
|
||||
*/
|
||||
|
||||
/** Cached DHCPACK physical address
|
||||
*
|
||||
* This can be set by the prefix.
|
||||
*/
|
||||
uint32_t __bss16 ( cached_dhcpack_phys );
|
||||
#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &cached_dhcpack_phys
|
||||
|
||||
/** Cached DHCPACK */
|
||||
static struct dhcp_packet *cached_dhcpack;
|
||||
|
||||
/**
|
||||
* Cached DHCPACK startup function
|
||||
*
|
||||
*/
|
||||
static void cachedhcp_init ( void ) {
|
||||
struct dhcp_packet *dhcppkt;
|
||||
struct dhcp_packet *tmp;
|
||||
struct dhcphdr *dhcphdr;
|
||||
size_t max_len;
|
||||
size_t len;
|
||||
|
||||
/* Do nothing if no cached DHCPACK is present */
|
||||
if ( ! cached_dhcpack_phys ) {
|
||||
DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* No reliable way to determine length before parsing packet;
|
||||
* start by assuming maximum length permitted by PXE.
|
||||
*/
|
||||
max_len = sizeof ( BOOTPLAYER_t );
|
||||
|
||||
/* Allocate and populate DHCP packet */
|
||||
dhcppkt = zalloc ( sizeof ( *dhcppkt ) + max_len );
|
||||
if ( ! dhcppkt ) {
|
||||
DBGC ( colour, "CACHEDHCP could not allocate copy\n" );
|
||||
return;
|
||||
}
|
||||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
|
||||
copy_from_user ( dhcphdr, phys_to_user ( cached_dhcpack_phys ), 0,
|
||||
max_len );
|
||||
dhcppkt_init ( dhcppkt, dhcphdr, max_len );
|
||||
|
||||
/* Shrink packet to required length. If reallocation fails,
|
||||
* just continue to use the original packet and waste the
|
||||
* unused space.
|
||||
*/
|
||||
len = dhcppkt_len ( dhcppkt );
|
||||
assert ( len <= max_len );
|
||||
tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) );
|
||||
if ( tmp )
|
||||
dhcppkt = tmp;
|
||||
|
||||
/* Reinitialise packet at new address */
|
||||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
|
||||
dhcppkt_init ( dhcppkt, dhcphdr, len );
|
||||
|
||||
/* Store as cached DHCPACK, and mark original copy as consumed */
|
||||
DBGC ( colour, "CACHEDHCP found cached DHCPACK at %08x+%zx\n",
|
||||
cached_dhcpack_phys, len );
|
||||
cached_dhcpack = dhcppkt;
|
||||
cached_dhcpack_phys = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached DHCPACK startup function
|
||||
*
|
||||
*/
|
||||
static void cachedhcp_startup ( void ) {
|
||||
|
||||
/* If cached DHCP packet was not claimed by any network device
|
||||
* during startup, then free it.
|
||||
*/
|
||||
if ( cached_dhcpack ) {
|
||||
DBGC ( colour, "CACHEDHCP freeing unclaimed cached DHCPACK\n" );
|
||||
dhcppkt_put ( cached_dhcpack );
|
||||
cached_dhcpack = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Cached DHCPACK initialisation function */
|
||||
struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
|
||||
.initialise = cachedhcp_init,
|
||||
};
|
||||
|
||||
/** Cached DHCPACK startup function */
|
||||
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
|
||||
.name = "cachedhcp",
|
||||
.startup = cachedhcp_startup,
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply cached DHCPACK to network device, if applicable
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int cachedhcp_probe ( struct net_device *netdev ) {
|
||||
struct ll_protocol *ll_protocol = netdev->ll_protocol;
|
||||
int rc;
|
||||
|
||||
/* Do nothing unless we have a cached DHCPACK */
|
||||
if ( ! cached_dhcpack )
|
||||
return 0;
|
||||
|
||||
/* Do nothing unless cached DHCPACK's MAC address matches this
|
||||
* network device.
|
||||
*/
|
||||
if ( memcmp ( netdev->ll_addr, cached_dhcpack->dhcphdr->chaddr,
|
||||
ll_protocol->ll_addr_len ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP cached DHCPACK does not match %s\n",
|
||||
netdev->name );
|
||||
return 0;
|
||||
}
|
||||
DBGC ( colour, "CACHEDHCP cached DHCPACK is for %s\n", netdev->name );
|
||||
|
||||
/* Register as DHCP settings for this network device */
|
||||
if ( ( rc = register_settings ( &cached_dhcpack->settings,
|
||||
netdev_settings ( netdev ),
|
||||
DHCP_SETTINGS_NAME ) ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP could not register settings: %s\n",
|
||||
strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Claim cached DHCPACK */
|
||||
dhcppkt_put ( cached_dhcpack );
|
||||
cached_dhcpack = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Cached DHCP packet network device driver */
|
||||
struct net_driver cachedhcp_driver __net_driver = {
|
||||
.name = "cachedhcp",
|
||||
.probe = cachedhcp_probe,
|
||||
};
|
|
@ -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];
|
||||
}
|
||||
}
|
|
@ -52,3 +52,4 @@ PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
|
|||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
|
||||
PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
|
||||
|
|
|
@ -38,7 +38,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/init.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/script.h>
|
||||
#include <ipxe/umalloc.h>
|
||||
#include <realmode.h>
|
||||
|
||||
/** Command line physical address
|
||||
|
@ -180,7 +179,6 @@ static int cmdline_init ( void ) {
|
|||
*/
|
||||
static int initrd_init ( void ) {
|
||||
struct image *image;
|
||||
int rc;
|
||||
|
||||
/* Do nothing if no initrd was specified */
|
||||
if ( ! initrd_phys ) {
|
||||
|
@ -194,53 +192,18 @@ static int initrd_init ( void ) {
|
|||
DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n",
|
||||
initrd_phys, ( initrd_phys + initrd_len ) );
|
||||
|
||||
/* Allocate image */
|
||||
image = alloc_image ( NULL );
|
||||
/* Create initrd image */
|
||||
image = image_memory ( "<INITRD>", phys_to_user ( initrd_phys ),
|
||||
initrd_len );
|
||||
if ( ! image ) {
|
||||
DBGC ( colour, "RUNTIME could not allocate image for "
|
||||
"initrd\n" );
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_image;
|
||||
DBGC ( colour, "RUNTIME could not create initrd image\n" );
|
||||
return -ENOMEM;
|
||||
}
|
||||
if ( ( rc = image_set_name ( image, "<INITRD>" ) ) != 0 ) {
|
||||
DBGC ( colour, "RUNTIME could not set image name: %s\n",
|
||||
strerror ( rc ) );
|
||||
goto err_set_name;
|
||||
}
|
||||
|
||||
/* Allocate and copy initrd content */
|
||||
image->data = umalloc ( initrd_len );
|
||||
if ( ! image->data ) {
|
||||
DBGC ( colour, "RUNTIME could not allocate %d bytes for "
|
||||
"initrd\n", initrd_len );
|
||||
rc = -ENOMEM;
|
||||
goto err_umalloc;
|
||||
}
|
||||
image->len = initrd_len;
|
||||
memcpy_user ( image->data, 0, phys_to_user ( initrd_phys ), 0,
|
||||
initrd_len );
|
||||
|
||||
/* Mark initrd as consumed */
|
||||
initrd_phys = 0;
|
||||
|
||||
/* Register image */
|
||||
if ( ( rc = register_image ( image ) ) != 0 ) {
|
||||
DBGC ( colour, "RUNTIME could not register initrd: %s\n",
|
||||
strerror ( rc ) );
|
||||
goto err_register_image;
|
||||
}
|
||||
|
||||
/* Drop our reference to the image */
|
||||
image_put ( image );
|
||||
|
||||
return 0;
|
||||
|
||||
err_register_image:
|
||||
err_umalloc:
|
||||
err_set_name:
|
||||
image_put ( image );
|
||||
err_alloc_image:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,7 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
|||
****************************************************************************
|
||||
*/
|
||||
.section ".stack", "aw", @nobits
|
||||
.align 8
|
||||
.balign 8
|
||||
.globl _stack
|
||||
_stack:
|
||||
.space STACK_SIZE
|
||||
|
|
|
@ -7,7 +7,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
|||
****************************************************************************
|
||||
*/
|
||||
.section ".stack16", "aw", @nobits
|
||||
.align 8
|
||||
.balign 8
|
||||
.globl _stack16
|
||||
_stack16:
|
||||
.space 4096
|
||||
|
|
|
@ -75,17 +75,18 @@ void bigint_multiply_raw ( const uint32_t *multiplicand0,
|
|||
*
|
||||
* a < 2^{n}, b < 2^{n} => ab < 2^{2n}
|
||||
*/
|
||||
__asm__ __volatile__ ( "mull %4\n\t"
|
||||
"addl %%eax, (%5,%2,4)\n\t"
|
||||
"adcl %%edx, 4(%5,%2,4)\n\t"
|
||||
__asm__ __volatile__ ( "mull %5\n\t"
|
||||
"addl %%eax, (%6,%2,4)\n\t"
|
||||
"adcl %%edx, 4(%6,%2,4)\n\t"
|
||||
"\n1:\n\t"
|
||||
"adcl $0, 8(%5,%2,4)\n\t"
|
||||
"adcl $0, 8(%6,%2,4)\n\t"
|
||||
"inc %2\n\t"
|
||||
/* Does not affect CF */
|
||||
"jc 1b\n\t"
|
||||
: "=&a" ( discard_a ),
|
||||
"=&d" ( discard_d ),
|
||||
"=&r" ( index )
|
||||
"=&r" ( index ),
|
||||
"+m" ( *result )
|
||||
: "0" ( multiplicand_element ),
|
||||
"g" ( multiplier_element ),
|
||||
"r" ( result_elements ),
|
||||
|
|
|
@ -30,6 +30,14 @@
|
|||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
#include <config/defaults.h>
|
||||
|
||||
/* Use generic_memcpy_reverse() if we cannot safely set the direction flag */
|
||||
#ifdef UNSAFE_STD
|
||||
#define USE_GENERIC_MEMCPY_REVERSE 1
|
||||
#else
|
||||
#define USE_GENERIC_MEMCPY_REVERSE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Copy memory area
|
||||
|
@ -77,6 +85,12 @@ void * __attribute__ (( noinline )) __memcpy_reverse ( void *dest,
|
|||
const void *esi = ( src + len - 1 );
|
||||
int discard_ecx;
|
||||
|
||||
/* Use unoptimised version if we are not permitted to modify
|
||||
* the direction flag.
|
||||
*/
|
||||
if ( USE_GENERIC_MEMCPY_REVERSE )
|
||||
return generic_memcpy_reverse ( dest, src, len );
|
||||
|
||||
/* Assume memmove() is not performance-critical, and perform a
|
||||
* bytewise copy for simplicity.
|
||||
*/
|
||||
|
|
|
@ -83,7 +83,7 @@ hv_alloc_pages ( struct hv_hypervisor *hv, ... ) {
|
|||
/* Allocate and zero pages */
|
||||
va_start ( args, hv );
|
||||
for ( i = 0 ; ( ( page = va_arg ( args, void ** ) ) != NULL ); i++ ) {
|
||||
*page = malloc_dma ( PAGE_SIZE, PAGE_SIZE );
|
||||
*page = malloc_phys ( PAGE_SIZE, PAGE_SIZE );
|
||||
if ( ! *page )
|
||||
goto err_alloc;
|
||||
memset ( *page, 0, PAGE_SIZE );
|
||||
|
@ -97,7 +97,7 @@ hv_alloc_pages ( struct hv_hypervisor *hv, ... ) {
|
|||
va_start ( args, hv );
|
||||
for ( ; i >= 0 ; i-- ) {
|
||||
page = va_arg ( args, void ** );
|
||||
free_dma ( *page, PAGE_SIZE );
|
||||
free_phys ( *page, PAGE_SIZE );
|
||||
}
|
||||
va_end ( args );
|
||||
return -ENOMEM;
|
||||
|
@ -116,7 +116,7 @@ hv_free_pages ( struct hv_hypervisor *hv, ... ) {
|
|||
|
||||
va_start ( args, hv );
|
||||
while ( ( page = va_arg ( args, void * ) ) != NULL )
|
||||
free_dma ( page, PAGE_SIZE );
|
||||
free_phys ( page, PAGE_SIZE );
|
||||
va_end ( args );
|
||||
}
|
||||
|
||||
|
@ -131,8 +131,8 @@ static int hv_alloc_message ( struct hv_hypervisor *hv ) {
|
|||
/* Allocate buffer. Must be aligned to at least 8 bytes and
|
||||
* must not cross a page boundary, so align on its own size.
|
||||
*/
|
||||
hv->message = malloc_dma ( sizeof ( *hv->message ),
|
||||
sizeof ( *hv->message ) );
|
||||
hv->message = malloc_phys ( sizeof ( *hv->message ),
|
||||
sizeof ( *hv->message ) );
|
||||
if ( ! hv->message )
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -147,7 +147,7 @@ static int hv_alloc_message ( struct hv_hypervisor *hv ) {
|
|||
static void hv_free_message ( struct hv_hypervisor *hv ) {
|
||||
|
||||
/* Free buffer */
|
||||
free_dma ( hv->message, sizeof ( *hv->message ) );
|
||||
free_phys ( hv->message, sizeof ( *hv->message ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -104,6 +104,13 @@ static union u_PXENV_ANY __bss16 ( undinet_params );
|
|||
SEGOFF16_t __bss16 ( undinet_entry_point );
|
||||
#define undinet_entry_point __use_data16 ( undinet_entry_point )
|
||||
|
||||
/* Read TSC in real mode only when profiling */
|
||||
#if PROFILING
|
||||
#define RDTSC_IF_PROFILING "rdtsc\n\t"
|
||||
#else
|
||||
#define RDTSC_IF_PROFILING ""
|
||||
#endif
|
||||
|
||||
/** IRQ profiler */
|
||||
static struct profiler undinet_irq_profiler __profiler =
|
||||
{ .name = "undinet.irq" };
|
||||
|
@ -288,14 +295,14 @@ static int undinet_call ( struct undi_nic *undinic, unsigned int function,
|
|||
*/
|
||||
profile_start ( &profiler->total );
|
||||
__asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
|
||||
"rdtsc\n\t"
|
||||
RDTSC_IF_PROFILING
|
||||
"pushl %%eax\n\t"
|
||||
"pushw %%es\n\t"
|
||||
"pushw %%di\n\t"
|
||||
"pushw %%bx\n\t"
|
||||
"lcall *undinet_entry_point\n\t"
|
||||
"movw %%ax, %%bx\n\t"
|
||||
"rdtsc\n\t"
|
||||
RDTSC_IF_PROFILING
|
||||
"addw $6, %%sp\n\t"
|
||||
"popl %%edx\n\t"
|
||||
"popl %%ebp\n\t" /* gcc bug */ )
|
||||
|
|
|
@ -106,7 +106,7 @@ static int hvm_map_hypercall ( struct hvm_device *hvm ) {
|
|||
|
||||
/* Allocate pages */
|
||||
hvm->hypercall_len = ( pages * PAGE_SIZE );
|
||||
hvm->xen.hypercall = malloc_dma ( hvm->hypercall_len, PAGE_SIZE );
|
||||
hvm->xen.hypercall = malloc_phys ( hvm->hypercall_len, PAGE_SIZE );
|
||||
if ( ! hvm->xen.hypercall ) {
|
||||
DBGC ( hvm, "HVM could not allocate %d hypercall page(s)\n",
|
||||
pages );
|
||||
|
@ -141,7 +141,7 @@ static int hvm_map_hypercall ( struct hvm_device *hvm ) {
|
|||
static void hvm_unmap_hypercall ( struct hvm_device *hvm ) {
|
||||
|
||||
/* Free pages */
|
||||
free_dma ( hvm->xen.hypercall, hvm->hypercall_len );
|
||||
free_phys ( hvm->xen.hypercall, hvm->hypercall_len );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +175,7 @@ static void * hvm_ioremap ( struct hvm_device *hvm, unsigned int space,
|
|||
}
|
||||
|
||||
/* Map this space */
|
||||
mmio = ioremap ( ( hvm->mmio + hvm->mmio_offset ), len );
|
||||
mmio = pci_ioremap ( hvm->pci, ( hvm->mmio + hvm->mmio_offset ), len );
|
||||
if ( ! mmio ) {
|
||||
DBGC ( hvm, "HVM could not map MMIO space [%08lx,%08lx)\n",
|
||||
( hvm->mmio + hvm->mmio_offset ),
|
||||
|
@ -371,7 +371,8 @@ static int hvm_map_xenstore ( struct hvm_device *hvm ) {
|
|||
xenstore_phys = ( xenstore_pfn * PAGE_SIZE );
|
||||
|
||||
/* Map XenStore */
|
||||
hvm->xen.store.intf = ioremap ( xenstore_phys, PAGE_SIZE );
|
||||
hvm->xen.store.intf = pci_ioremap ( hvm->pci, xenstore_phys,
|
||||
PAGE_SIZE );
|
||||
if ( ! hvm->xen.store.intf ) {
|
||||
DBGC ( hvm, "HVM could not map XenStore at [%08lx,%08lx)\n",
|
||||
xenstore_phys, ( xenstore_phys + PAGE_SIZE ) );
|
||||
|
@ -420,6 +421,7 @@ static int hvm_probe ( struct pci_device *pci ) {
|
|||
rc = -ENOMEM;
|
||||
goto err_alloc;
|
||||
}
|
||||
hvm->pci = pci;
|
||||
hvm->mmio = pci_bar_start ( pci, HVM_MMIO_BAR );
|
||||
hvm->mmio_len = pci_bar_size ( pci, HVM_MMIO_BAR );
|
||||
DBGC2 ( hvm, "HVM has MMIO space [%08lx,%08lx)\n",
|
||||
|
|
|
@ -39,6 +39,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
struct hvm_device {
|
||||
/** Xen hypervisor */
|
||||
struct xen_hypervisor xen;
|
||||
/** PCI device */
|
||||
struct pci_device *pci;
|
||||
/** CPUID base */
|
||||
uint32_t cpuid_base;
|
||||
/** Length of hypercall table */
|
||||
|
|
|
@ -326,32 +326,6 @@ static void bzimage_set_cmdline ( struct image *image,
|
|||
DBGC ( image, "bzImage %p command line \"%s\"\n", image, cmdline );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse standalone image command line for cpio parameters
|
||||
*
|
||||
* @v image bzImage file
|
||||
* @v cpio CPIO header
|
||||
* @v cmdline Command line
|
||||
*/
|
||||
static void bzimage_parse_cpio_cmdline ( struct image *image,
|
||||
struct cpio_header *cpio,
|
||||
const char *cmdline ) {
|
||||
char *arg;
|
||||
char *end;
|
||||
unsigned int mode;
|
||||
|
||||
/* Look for "mode=" */
|
||||
if ( ( arg = strstr ( cmdline, "mode=" ) ) ) {
|
||||
arg += 5;
|
||||
mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
|
||||
if ( *end && ( *end != ' ' ) ) {
|
||||
DBGC ( image, "bzImage %p strange \"mode=\""
|
||||
"terminator '%c'\n", image, *end );
|
||||
}
|
||||
cpio_set_field ( cpio->c_mode, ( 0100000 | mode ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Align initrd length
|
||||
*
|
||||
|
@ -374,11 +348,9 @@ static inline size_t bzimage_align ( size_t len ) {
|
|||
static size_t bzimage_load_initrd ( struct image *image,
|
||||
struct image *initrd,
|
||||
userptr_t address ) {
|
||||
char *filename = initrd->cmdline;
|
||||
char *cmdline;
|
||||
const char *filename = cpio_name ( initrd );
|
||||
struct cpio_header cpio;
|
||||
size_t offset;
|
||||
size_t name_len;
|
||||
size_t pad_len;
|
||||
|
||||
/* Do not include kernel image itself as an initrd */
|
||||
|
@ -386,25 +358,7 @@ static size_t bzimage_load_initrd ( struct image *image,
|
|||
return 0;
|
||||
|
||||
/* Create cpio header for non-prebuilt images */
|
||||
if ( filename && filename[0] ) {
|
||||
cmdline = strchr ( filename, ' ' );
|
||||
name_len = ( ( cmdline ? ( ( size_t ) ( cmdline - filename ) )
|
||||
: strlen ( filename ) ) + 1 /* NUL */ );
|
||||
memset ( &cpio, '0', sizeof ( cpio ) );
|
||||
memcpy ( cpio.c_magic, CPIO_MAGIC, sizeof ( cpio.c_magic ) );
|
||||
cpio_set_field ( cpio.c_mode, 0100644 );
|
||||
cpio_set_field ( cpio.c_nlink, 1 );
|
||||
cpio_set_field ( cpio.c_filesize, initrd->len );
|
||||
cpio_set_field ( cpio.c_namesize, name_len );
|
||||
if ( cmdline ) {
|
||||
bzimage_parse_cpio_cmdline ( image, &cpio,
|
||||
( cmdline + 1 /* ' ' */ ));
|
||||
}
|
||||
offset = ( ( sizeof ( cpio ) + name_len + 0x03 ) & ~0x03 );
|
||||
} else {
|
||||
offset = 0;
|
||||
name_len = 0;
|
||||
}
|
||||
offset = cpio_header ( initrd, &cpio );
|
||||
|
||||
/* Copy in initrd image body (and cpio header if applicable) */
|
||||
if ( address ) {
|
||||
|
@ -413,7 +367,7 @@ static size_t bzimage_load_initrd ( struct image *image,
|
|||
memset_user ( address, 0, 0, offset );
|
||||
copy_to_user ( address, 0, &cpio, sizeof ( cpio ) );
|
||||
copy_to_user ( address, sizeof ( cpio ), filename,
|
||||
( name_len - 1 /* NUL (or space) */ ) );
|
||||
cpio_name_len ( initrd ) );
|
||||
}
|
||||
DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)"
|
||||
"%s%s\n", image, initrd, user_to_phys ( address, 0 ),
|
||||
|
|
|
@ -110,7 +110,7 @@ static int com32_exec_loop ( struct image *image ) {
|
|||
/* Disable interrupts */
|
||||
"cli\n\t"
|
||||
/* Restore stack pointer */
|
||||
"movl 24(%%esp), %%esp\n\t"
|
||||
"movl 28(%%esp), %%esp\n\t"
|
||||
/* Restore registers */
|
||||
"popal\n\t" )
|
||||
:
|
||||
|
|
|
@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/uaccess.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/memblock.h>
|
||||
#include <ipxe/cpio.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
|
@ -175,18 +176,18 @@ static int initrd_swap_any ( userptr_t free, size_t free_len ) {
|
|||
/* Search for adjacent image */
|
||||
for_each_image ( high ) {
|
||||
|
||||
/* If we have found the adjacent image, swap and exit */
|
||||
if ( high->data == adjacent ) {
|
||||
initrd_swap ( low, high, free, free_len );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Stop search if all remaining potential
|
||||
* adjacent images are already in the correct
|
||||
* order.
|
||||
*/
|
||||
if ( high == low )
|
||||
break;
|
||||
|
||||
/* If we have found the adjacent image, swap and exit */
|
||||
if ( high->data == adjacent ) {
|
||||
initrd_swap ( low, high, free, free_len );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,19 +25,22 @@ typedef uint32_t bigint_element_t;
|
|||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_init_raw ( uint32_t *value0, unsigned int size,
|
||||
const void *data, size_t len ) {
|
||||
long pad_len = ( sizeof ( bigint_t ( size ) ) - len );
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
long pad_len = ( sizeof ( *value ) - len );
|
||||
void *discard_D;
|
||||
long discard_c;
|
||||
|
||||
/* Copy raw data in reverse order, padding with zeros */
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
"movb -1(%2,%1), %%al\n\t"
|
||||
"movb -1(%3,%1), %%al\n\t"
|
||||
"stosb\n\t"
|
||||
"loop 1b\n\t"
|
||||
"xorl %%eax, %%eax\n\t"
|
||||
"mov %3, %1\n\t"
|
||||
"mov %4, %1\n\t"
|
||||
"rep stosb\n\t"
|
||||
: "=&D" ( discard_D ), "=&c" ( discard_c )
|
||||
: "=&D" ( discard_D ), "=&c" ( discard_c ),
|
||||
"+m" ( *value )
|
||||
: "r" ( data ), "g" ( pad_len ), "0" ( value0 ),
|
||||
"1" ( len )
|
||||
: "eax" );
|
||||
|
@ -53,6 +56,8 @@ bigint_init_raw ( uint32_t *value0, unsigned int size,
|
|||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_add_raw ( const uint32_t *addend0, uint32_t *value0,
|
||||
unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
long index;
|
||||
void *discard_S;
|
||||
long discard_c;
|
||||
|
@ -60,11 +65,11 @@ bigint_add_raw ( const uint32_t *addend0, uint32_t *value0,
|
|||
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
|
||||
"\n1:\n\t"
|
||||
"lodsl\n\t"
|
||||
"adcl %%eax, (%3,%0,4)\n\t"
|
||||
"adcl %%eax, (%4,%0,4)\n\t"
|
||||
"inc %0\n\t" /* Does not affect CF */
|
||||
"loop 1b\n\t"
|
||||
: "=&r" ( index ), "=&S" ( discard_S ),
|
||||
"=&c" ( discard_c )
|
||||
"=&c" ( discard_c ), "+m" ( *value )
|
||||
: "r" ( value0 ), "1" ( addend0 ), "2" ( size )
|
||||
: "eax" );
|
||||
}
|
||||
|
@ -79,6 +84,8 @@ bigint_add_raw ( const uint32_t *addend0, uint32_t *value0,
|
|||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
|
||||
unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
long index;
|
||||
void *discard_S;
|
||||
long discard_c;
|
||||
|
@ -86,11 +93,11 @@ bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
|
|||
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
|
||||
"\n1:\n\t"
|
||||
"lodsl\n\t"
|
||||
"sbbl %%eax, (%3,%0,4)\n\t"
|
||||
"sbbl %%eax, (%4,%0,4)\n\t"
|
||||
"inc %0\n\t" /* Does not affect CF */
|
||||
"loop 1b\n\t"
|
||||
: "=&r" ( index ), "=&S" ( discard_S ),
|
||||
"=&c" ( discard_c )
|
||||
"=&c" ( discard_c ), "+m" ( *value )
|
||||
: "r" ( value0 ), "1" ( subtrahend0 ),
|
||||
"2" ( size )
|
||||
: "eax" );
|
||||
|
@ -104,15 +111,18 @@ bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
|
|||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_rol_raw ( uint32_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
long index;
|
||||
long discard_c;
|
||||
|
||||
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
|
||||
"\n1:\n\t"
|
||||
"rcll $1, (%2,%0,4)\n\t"
|
||||
"rcll $1, (%3,%0,4)\n\t"
|
||||
"inc %0\n\t" /* Does not affect CF */
|
||||
"loop 1b\n\t"
|
||||
: "=&r" ( index ), "=&c" ( discard_c )
|
||||
: "=&r" ( index ), "=&c" ( discard_c ),
|
||||
"+m" ( *value )
|
||||
: "r" ( value0 ), "1" ( size ) );
|
||||
}
|
||||
|
||||
|
@ -124,13 +134,15 @@ bigint_rol_raw ( uint32_t *value0, unsigned int size ) {
|
|||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_ror_raw ( uint32_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
long discard_c;
|
||||
|
||||
__asm__ __volatile__ ( "clc\n\t"
|
||||
"\n1:\n\t"
|
||||
"rcrl $1, -4(%1,%0,4)\n\t"
|
||||
"rcrl $1, -4(%2,%0,4)\n\t"
|
||||
"loop 1b\n\t"
|
||||
: "=&c" ( discard_c )
|
||||
: "=&c" ( discard_c ), "+m" ( *value )
|
||||
: "r" ( value0 ), "0" ( size ) );
|
||||
}
|
||||
|
||||
|
@ -167,28 +179,19 @@ bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
|
|||
static inline __attribute__ (( always_inline, pure )) int
|
||||
bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
|
||||
unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( const void * ) value0 );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *reference =
|
||||
( ( const void * ) reference0 );
|
||||
void *discard_S;
|
||||
void *discard_D;
|
||||
long discard_c;
|
||||
long discard_tmp;
|
||||
int result;
|
||||
|
||||
__asm__ __volatile__ ( "std\n\t"
|
||||
"\n1:\n\t"
|
||||
"lodsl\n\t"
|
||||
"scasl\n\t"
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
"movl -4(%3, %1, 4), %k2\n\t"
|
||||
"cmpl -4(%4, %1, 4), %k2\n\t"
|
||||
"loope 1b\n\t"
|
||||
"setae %b0\n\t"
|
||||
"cld\n\t"
|
||||
: "=q" ( result ), "=&S" ( discard_S ),
|
||||
"=&D" ( discard_D ), "=&c" ( discard_c )
|
||||
: "0" ( 0 ), "1" ( &value->element[ size - 1 ] ),
|
||||
"2" ( &reference->element[ size - 1 ] ),
|
||||
"3" ( size )
|
||||
: "eax" );
|
||||
: "=q" ( result ), "=&c" ( discard_c ),
|
||||
"=&r" ( discard_tmp )
|
||||
: "r" ( value0 ), "r" ( reference0 ),
|
||||
"0" ( 0 ), "1" ( size ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -248,6 +251,8 @@ bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
|
|||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
|
||||
uint32_t *dest0, unsigned int dest_size ) {
|
||||
bigint_t ( dest_size ) __attribute__ (( may_alias )) *dest =
|
||||
( ( void * ) dest0 );
|
||||
long pad_size = ( dest_size - source_size );
|
||||
void *discard_D;
|
||||
void *discard_S;
|
||||
|
@ -255,10 +260,10 @@ bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
|
|||
|
||||
__asm__ __volatile__ ( "rep movsl\n\t"
|
||||
"xorl %%eax, %%eax\n\t"
|
||||
"mov %3, %2\n\t"
|
||||
"mov %4, %2\n\t"
|
||||
"rep stosl\n\t"
|
||||
: "=&D" ( discard_D ), "=&S" ( discard_S ),
|
||||
"=&c" ( discard_c )
|
||||
"=&c" ( discard_c ), "+m" ( *dest )
|
||||
: "g" ( pad_size ), "0" ( dest0 ),
|
||||
"1" ( source0 ), "2" ( source_size )
|
||||
: "eax" );
|
||||
|
@ -275,13 +280,15 @@ bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
|
|||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
|
||||
uint32_t *dest0, unsigned int dest_size ) {
|
||||
bigint_t ( dest_size ) __attribute__ (( may_alias )) *dest =
|
||||
( ( void * ) dest0 );
|
||||
void *discard_D;
|
||||
void *discard_S;
|
||||
long discard_c;
|
||||
|
||||
__asm__ __volatile__ ( "rep movsl\n\t"
|
||||
: "=&D" ( discard_D ), "=&S" ( discard_S ),
|
||||
"=&c" ( discard_c )
|
||||
"=&c" ( discard_c ), "+m" ( *dest )
|
||||
: "0" ( dest0 ), "1" ( source0 ),
|
||||
"2" ( dest_size )
|
||||
: "eax" );
|
||||
|
@ -298,15 +305,19 @@ bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
|
|||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
|
||||
void *out, size_t len ) {
|
||||
struct {
|
||||
uint8_t bytes[len];
|
||||
} __attribute__ (( may_alias )) *out_bytes = out;
|
||||
void *discard_D;
|
||||
long discard_c;
|
||||
|
||||
/* Copy raw data in reverse order */
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
"movb -1(%2,%1), %%al\n\t"
|
||||
"movb -1(%3,%1), %%al\n\t"
|
||||
"stosb\n\t"
|
||||
"loop 1b\n\t"
|
||||
: "=&D" ( discard_D ), "=&c" ( discard_c )
|
||||
: "=&D" ( discard_D ), "=&c" ( discard_c ),
|
||||
"+m" ( *out_bytes )
|
||||
: "r" ( value0 ), "0" ( out ), "1" ( len )
|
||||
: "eax" );
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -11,13 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
#include <ipxe/uaccess.h>
|
||||
|
||||
/** Minimum alignment for initrds
|
||||
*
|
||||
* Some versions of Linux complain about initrds that are not
|
||||
* page-aligned.
|
||||
*/
|
||||
#define INITRD_ALIGN 4096
|
||||
|
||||
/** Minimum free space required to reshuffle initrds
|
||||
*
|
||||
* Chosen to avoid absurdly long reshuffling times
|
||||
|
|
|
@ -42,6 +42,12 @@ struct x86_features {
|
|||
/** Hypervisor is present */
|
||||
#define CPUID_FEATURES_INTEL_ECX_HYPERVISOR 0x80000000UL
|
||||
|
||||
/** TSC is present */
|
||||
#define CPUID_FEATURES_INTEL_EDX_TSC 0x00000010UL
|
||||
|
||||
/** FXSAVE and FXRSTOR are supported */
|
||||
#define CPUID_FEATURES_INTEL_EDX_FXSR 0x01000000UL
|
||||
|
||||
/** Get largest extended function */
|
||||
#define CPUID_AMD_MAX_FN 0x80000000UL
|
||||
|
||||
|
|
|
@ -132,4 +132,17 @@ PCIAPI_INLINE ( pcbios, pci_write_config_dword ) ( struct pci_device *pci,
|
|||
return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_DWORD | where, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map PCI bus address as an I/O address
|
||||
*
|
||||
* @v bus_addr PCI bus address
|
||||
* @v len Length of region
|
||||
* @ret io_addr I/O address, or NULL on error
|
||||
*/
|
||||
static inline __always_inline void *
|
||||
PCIAPI_INLINE ( pcbios, pci_ioremap ) ( struct pci_device *pci __unused,
|
||||
unsigned long bus_addr, size_t len ) {
|
||||
return ioremap ( bus_addr, len );
|
||||
}
|
||||
|
||||
#endif /* _IPXE_PCIBIOS_H */
|
||||
|
|
|
@ -32,8 +32,8 @@ extern void pcidirect_prepare ( struct pci_device *pci, int where );
|
|||
*/
|
||||
static inline __always_inline int
|
||||
PCIAPI_INLINE ( direct, pci_num_bus ) ( void ) {
|
||||
/* No way to work this out via Type 1 accesses */
|
||||
return 0x100;
|
||||
/* Scan first bus and rely on bridge detection to find higher buses */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,4 +138,17 @@ PCIAPI_INLINE ( direct, pci_write_config_dword ) ( struct pci_device *pci,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map PCI bus address as an I/O address
|
||||
*
|
||||
* @v bus_addr PCI bus address
|
||||
* @v len Length of region
|
||||
* @ret io_addr I/O address, or NULL on error
|
||||
*/
|
||||
static inline __always_inline void *
|
||||
PCIAPI_INLINE ( direct, pci_ioremap ) ( struct pci_device *pci __unused,
|
||||
unsigned long bus_addr, size_t len ) {
|
||||
return ioremap ( bus_addr, len );
|
||||
}
|
||||
|
||||
#endif /* _PCIDIRECT_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 */
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/cachedhcp.h>
|
||||
#include <realmode.h>
|
||||
#include <pxe_api.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Cached DHCP packet
|
||||
*
|
||||
*/
|
||||
|
||||
/** Cached DHCPACK physical address
|
||||
*
|
||||
* This can be set by the prefix.
|
||||
*/
|
||||
uint32_t __bss16 ( cached_dhcpack_phys );
|
||||
#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &cached_dhcpack_phys
|
||||
|
||||
/**
|
||||
* Cached DHCPACK initialisation function
|
||||
*
|
||||
*/
|
||||
static void cachedhcp_init ( void ) {
|
||||
int rc;
|
||||
|
||||
/* Do nothing if no cached DHCPACK is present */
|
||||
if ( ! cached_dhcpack_phys ) {
|
||||
DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Record cached DHCPACK */
|
||||
if ( ( rc = cachedhcp_record ( &cached_dhcpack,
|
||||
phys_to_user ( cached_dhcpack_phys ),
|
||||
sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n",
|
||||
strerror ( rc ) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark as consumed */
|
||||
cached_dhcpack_phys = 0;
|
||||
}
|
||||
|
||||
/** Cached DHCPACK initialisation function */
|
||||
struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
|
||||
.initialise = cachedhcp_init,
|
||||
};
|
|
@ -443,7 +443,7 @@ struct console_driver bios_console __console_driver = {
|
|||
*
|
||||
* @v ix86 Registers as passed to INT 16
|
||||
*/
|
||||
static __asmcall void bios_inject ( struct i386_all_regs *ix86 ) {
|
||||
static __asmcall __used void bios_inject ( struct i386_all_regs *ix86 ) {
|
||||
unsigned int discard_a;
|
||||
unsigned int scancode;
|
||||
unsigned int i;
|
||||
|
|
|
@ -67,7 +67,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
|||
****************************************************************************
|
||||
*/
|
||||
.section ".data16", "aw", @progbits
|
||||
.align 16
|
||||
.balign 16
|
||||
.globl hidemem_base
|
||||
.globl hidemem_umalloc
|
||||
.globl hidemem_textdata
|
||||
|
|
|
@ -678,10 +678,10 @@ static int int13_get_disk_type ( struct san_device *sandev,
|
|||
* @ret cx Extensions API support bitmap
|
||||
* @ret status Status code / API version
|
||||
*/
|
||||
static int int13_extension_check ( struct san_device *sandev __unused,
|
||||
static int int13_extension_check ( struct san_device *sandev,
|
||||
struct i386_all_regs *ix86 ) {
|
||||
|
||||
if ( ix86->regs.bx == 0x55aa ) {
|
||||
if ( ( ix86->regs.bx == 0x55aa ) && ! int13_is_fdd ( sandev ) ) {
|
||||
DBGC2 ( sandev, "INT13 extensions installation check\n" );
|
||||
ix86->regs.bx = 0xaa55;
|
||||
ix86->regs.cx = ( INT13_EXTENSION_LINEAR |
|
||||
|
@ -1064,7 +1064,7 @@ static int int13_cdrom_read_boot_catalog ( struct san_device *sandev,
|
|||
* INT 13 handler
|
||||
*
|
||||
*/
|
||||
static __asmcall void int13 ( struct i386_all_regs *ix86 ) {
|
||||
static __asmcall __used void int13 ( struct i386_all_regs *ix86 ) {
|
||||
int command = ix86->regs.ah;
|
||||
unsigned int bios_drive = ix86->regs.dl;
|
||||
struct san_device *sandev;
|
||||
|
|
|
@ -190,14 +190,14 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) {
|
|||
/* Expand/shrink block if possible */
|
||||
if ( ptr == bottom ) {
|
||||
/* Update block */
|
||||
if ( new_size > ( heap_size - extmem.size ) ) {
|
||||
DBG ( "EXTMEM out of space\n" );
|
||||
return UNULL;
|
||||
}
|
||||
new = userptr_add ( ptr, - ( new_size - extmem.size ) );
|
||||
align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) );
|
||||
new_size += align;
|
||||
new = userptr_add ( new, -align );
|
||||
if ( new_size > ( heap_size + extmem.size ) ) {
|
||||
DBG ( "EXTMEM out of space\n" );
|
||||
return UNULL;
|
||||
}
|
||||
DBG ( "EXTMEM expanding [%lx,%lx) to [%lx,%lx)\n",
|
||||
user_to_phys ( ptr, 0 ),
|
||||
user_to_phys ( ptr, extmem.size ),
|
||||
|
|
|
@ -121,3 +121,4 @@ PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_dword );
|
|||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte );
|
||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word );
|
||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
|
||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_ioremap );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <biosint.h>
|
||||
#include <pic8259.h>
|
||||
#include <rtc.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
#include <ipxe/entropy.h>
|
||||
|
||||
/** Maximum time to wait for an RTC interrupt, in milliseconds */
|
||||
|
@ -174,8 +175,17 @@ static int rtc_entropy_check ( void ) {
|
|||
* @ret rc Return status code
|
||||
*/
|
||||
static int rtc_entropy_enable ( void ) {
|
||||
struct x86_features features;
|
||||
int rc;
|
||||
|
||||
/* Check that TSC is supported */
|
||||
x86_features ( &features );
|
||||
if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_TSC ) ) {
|
||||
DBGC ( &rtc_flag, "RTC has no TSC\n" );
|
||||
rc = -ENOTSUP;
|
||||
goto err_no_tsc;
|
||||
}
|
||||
|
||||
/* Hook ISR and enable RTC interrupts */
|
||||
rtc_hook_isr();
|
||||
enable_irq ( RTC_IRQ );
|
||||
|
@ -191,6 +201,7 @@ static int rtc_entropy_enable ( void ) {
|
|||
rtc_disable_int();
|
||||
disable_irq ( RTC_IRQ );
|
||||
rtc_unhook_isr();
|
||||
err_no_tsc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
|||
*/
|
||||
.section ".text16.data", "aw", @progbits
|
||||
.globl ppxe
|
||||
.align 16
|
||||
.balign 16
|
||||
ppxe:
|
||||
.ascii "!PXE" /* Signature */
|
||||
.byte pxe_length /* StructLength */
|
||||
|
@ -72,7 +72,7 @@ undiheader:
|
|||
*/
|
||||
.section ".text16.data", "aw", @progbits
|
||||
.globl pxenv
|
||||
.align 16
|
||||
.balign 16
|
||||
pxenv:
|
||||
.ascii "PXENV+" /* Signature */
|
||||
.word 0x0201 /* Version */
|
||||
|
|
|
@ -220,7 +220,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
|
|||
/**
|
||||
* Terminate program interrupt handler
|
||||
*/
|
||||
static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) {
|
||||
static __asmcall __used void int20 ( struct i386_all_regs *ix86 __unused ) {
|
||||
rmlongjmp ( comboot_return, COMBOOT_EXIT );
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) {
|
|||
/**
|
||||
* DOS-compatible API
|
||||
*/
|
||||
static __asmcall void int21 ( struct i386_all_regs *ix86 ) {
|
||||
static __asmcall __used void int21 ( struct i386_all_regs *ix86 ) {
|
||||
ix86->flags |= CF;
|
||||
|
||||
switch ( ix86->regs.ah ) {
|
||||
|
@ -311,7 +311,7 @@ __weak int pxe_api_call_weak ( struct i386_all_regs *ix86 __unused ) {
|
|||
/**
|
||||
* SYSLINUX API
|
||||
*/
|
||||
static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
|
||||
static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) {
|
||||
ix86->flags |= CF;
|
||||
|
||||
switch ( ix86->regs.ax ) {
|
||||
|
|
|
@ -110,7 +110,7 @@ overlay:
|
|||
/* Overlay number */
|
||||
.word 0
|
||||
|
||||
.align 16, 0
|
||||
.balign 16, 0
|
||||
|
||||
.globl _exe_start
|
||||
_exe_start:
|
||||
|
|
|
@ -492,7 +492,7 @@ mromheader:
|
|||
.word 0
|
||||
.size mromheader, . - mromheader
|
||||
|
||||
.align 4
|
||||
.balign 4
|
||||
mpciheader:
|
||||
.ascii "PCIR" /* Signature */
|
||||
.word pci_vendor_id /* Vendor identification */
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Raw binary prefix
|
||||
*
|
||||
* Assumes that entire image is already loaded as a contiguous block
|
||||
* on a paragraph boundary and entered in real mode.
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.text
|
||||
.arch i386
|
||||
.org 0
|
||||
.code16
|
||||
|
||||
#include <librm.h>
|
||||
|
||||
.section ".prefix", "ax", @progbits
|
||||
.globl _raw_start
|
||||
_raw_start:
|
||||
|
||||
/* Adjust %cs so that %cs:0000 is the start of the image */
|
||||
movw %cs, %ax
|
||||
call 1f
|
||||
1: popw %bx
|
||||
subw $1b, %bx
|
||||
shrw $4, %bx
|
||||
addw %bx, %ax
|
||||
pushw %ax
|
||||
pushw $2f
|
||||
lret
|
||||
2:
|
||||
/* Install iPXE */
|
||||
call install
|
||||
|
||||
/* Set up real-mode stack */
|
||||
movw %bx, %ss
|
||||
movw $_estack16, %sp
|
||||
|
||||
/* Jump to .text16 segment */
|
||||
pushw %ax
|
||||
pushw $1f
|
||||
lret
|
||||
.section ".text16", "awx", @progbits
|
||||
1:
|
||||
/* Run iPXE */
|
||||
virtcall main
|
||||
|
||||
/* Uninstall iPXE */
|
||||
call uninstall
|
||||
|
||||
/* Boot next device */
|
||||
int $0x18
|
|
@ -88,7 +88,7 @@ checksum:
|
|||
.previous
|
||||
|
||||
.ifeqs BUSTYPE, "PCIR"
|
||||
.align 4
|
||||
.balign 4
|
||||
pciheader:
|
||||
.ascii "PCIR" /* Signature */
|
||||
.word pci_vendor_id /* Vendor identification */
|
||||
|
@ -136,7 +136,7 @@ pci_devlist_end:
|
|||
* BIOSes will scan on 16-byte boundaries rather than using
|
||||
* the offset stored at 0x1a
|
||||
*/
|
||||
.align 16
|
||||
.balign 16
|
||||
pnpheader:
|
||||
.ascii "$PnP" /* Signature */
|
||||
.byte 0x01 /* Structure revision */
|
||||
|
@ -184,7 +184,7 @@ prodstr_pci_id:
|
|||
|
||||
.globl undiheader
|
||||
.weak undiloader
|
||||
.align 4
|
||||
.balign 4
|
||||
undiheader:
|
||||
.ascii "UNDI" /* Signature */
|
||||
.byte undiheader_len /* Length of structure */
|
||||
|
@ -199,7 +199,7 @@ undiheader:
|
|||
.equ undiheader_len, . - undiheader
|
||||
.size undiheader, . - undiheader
|
||||
|
||||
.align 4
|
||||
.balign 4
|
||||
ipxeheader:
|
||||
.ascii "iPXE" /* Signature */
|
||||
.byte ipxeheader_len /* Length of structure */
|
||||
|
|
|
@ -44,7 +44,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*/
|
||||
|
||||
.text
|
||||
.arch i586
|
||||
.arch i486
|
||||
.section ".prefix.lib", "ax", @progbits
|
||||
|
||||
#ifdef CODE16
|
||||
|
@ -231,7 +231,7 @@ rep_len_dec: .space sizeof__lzma_len_dec
|
|||
literal: .rept ( ( 1 << LZMA_LC ) * 0x300 )
|
||||
.word 0
|
||||
.endr
|
||||
.align 4
|
||||
.balign 4
|
||||
.equ sizeof__lzma_dec, . - lzma_dec
|
||||
.previous
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
#include <config/console.h>
|
||||
|
||||
.text
|
||||
.arch i386
|
||||
.section ".prefix", "awx", @progbits
|
||||
|
@ -9,26 +11,68 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
|||
#include "mbr.S"
|
||||
|
||||
/* Partition table: 64 heads, 32 sectors/track (ZIP-drive compatible) */
|
||||
#define HEADS 64
|
||||
#define SECTORS 32
|
||||
#define CYLADDR(cyl) ((((cyl) * HEADS + (((cyl) == 0) & 1)) * SECTORS) * 512)
|
||||
|
||||
#ifdef CONSOLE_INT13
|
||||
#define LOGPART 1
|
||||
#define LOGSTART 0
|
||||
#define LOGCOUNT 1
|
||||
#define BOOTSTART 1
|
||||
#define BOOTCOUNT 2
|
||||
#else /* CONSOLE_INT13 */
|
||||
#define LOGPART 0
|
||||
#define BOOTSTART 0
|
||||
#define BOOTCOUNT 2
|
||||
#endif /* CONSOLE_INT13 */
|
||||
|
||||
/* Construct a C/H/S address */
|
||||
.macro chs cylinder, head, sector
|
||||
.byte \head
|
||||
.byte (((\cylinder & 0x300) >> 2) | \sector)
|
||||
.byte (\cylinder & 0x0ff)
|
||||
.endm
|
||||
|
||||
/* Construct a linear address */
|
||||
.macro linear cylinders, heads, sectors
|
||||
.long ((((\cylinders * HEADS) + \heads) * SECTORS) + \sectors - 1)
|
||||
.endm
|
||||
|
||||
/* Construct a partition table entry */
|
||||
.macro partition bootflag, type, start, count
|
||||
.byte \bootflag
|
||||
chs \start, ((\start == 0) & 1), 1
|
||||
.byte \type
|
||||
chs (\start + \count - 1), (HEADS - 1), SECTORS
|
||||
linear \start, ((\start == 0) & 1), 1
|
||||
linear \count, 0, (1 - (((\start == 0) & 1) * SECTORS))
|
||||
.endm
|
||||
|
||||
/* Partition table */
|
||||
.org 446
|
||||
.space 16
|
||||
.space 16
|
||||
/* Partition 3: log partition (for CONSOLE_INT13) */
|
||||
.byte 0x00, 0x01, 0x01, 0x00
|
||||
.byte 0xe0, 0x3f, 0x20, 0x00
|
||||
.long 0x00000020
|
||||
.long 0x000007e0
|
||||
/* Partition 4: boot partition */
|
||||
.byte 0x80, 0x00, 0x01, 0x01
|
||||
.byte 0xeb, 0x3f, 0x20, 0x02
|
||||
.long 0x00000800
|
||||
.long 0x00001000
|
||||
|
||||
/* Partition 3: log partition (for CONSOLE_INT13) */
|
||||
.if LOGPART
|
||||
partition 0x00, 0xe0, LOGSTART, LOGCOUNT
|
||||
.else
|
||||
.space 16
|
||||
.endif
|
||||
|
||||
/* Partition 4: boot partition */
|
||||
partition 0x80, 0xeb, BOOTSTART, BOOTCOUNT
|
||||
|
||||
/* Disk signature */
|
||||
.org 510
|
||||
.byte 0x55, 0xaa
|
||||
|
||||
/* Skip to start of log partition */
|
||||
.org 32 * 512
|
||||
.if LOGPART
|
||||
.org CYLADDR(LOGSTART)
|
||||
.ascii "iPXE LOG\n\n"
|
||||
.endif
|
||||
|
||||
/* Skip to start of boot partition */
|
||||
.org 2048 * 512
|
||||
.org CYLADDR(BOOTSTART)
|
||||
|
|
|
@ -58,11 +58,12 @@ SECTIONS {
|
|||
*(SORT(.pci_devlist.*))
|
||||
*(.prefix.*)
|
||||
_mprefix = .;
|
||||
} .bss.prefix (NOLOAD) : AT ( _end_lma ) {
|
||||
} .bss.prefix (NOLOAD) : AT ( _bss_prefix_lma ) {
|
||||
_eprefix = .;
|
||||
}
|
||||
_prefix_filesz = ABSOLUTE ( _mprefix ) - ABSOLUTE ( _prefix );
|
||||
_prefix_memsz = ABSOLUTE ( _eprefix ) - ABSOLUTE ( _prefix );
|
||||
_prefix_padsz = ABSOLUTE ( _eprefix ) - ABSOLUTE ( _mprefix );
|
||||
|
||||
/*
|
||||
* The 16-bit (real-mode) code section
|
||||
|
@ -82,7 +83,7 @@ SECTIONS {
|
|||
*(.text16)
|
||||
*(.text16.*)
|
||||
_mtext16 = .;
|
||||
} .bss.text16 (NOLOAD) : AT ( _end_lma ) {
|
||||
} .bss.text16 (NOLOAD) : AT ( _bss_text16_lma ) {
|
||||
_etext16 = .;
|
||||
}
|
||||
_text16_early_filesz = ABSOLUTE ( _etext16_early ) - ABSOLUTE ( _text16 );
|
||||
|
@ -90,6 +91,7 @@ SECTIONS {
|
|||
_text16_late_filesz = ABSOLUTE ( _mtext16 ) - ABSOLUTE ( _text16_late );
|
||||
_text16_late_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16_late );
|
||||
_text16_memsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16 );
|
||||
_text16_padsz = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _mtext16 );
|
||||
|
||||
/*
|
||||
* The 16-bit (real-mode) data section
|
||||
|
@ -104,7 +106,7 @@ SECTIONS {
|
|||
*(.data16)
|
||||
*(.data16.*)
|
||||
_mdata16 = .;
|
||||
} .bss.data16 (NOLOAD) : AT ( _end_lma ) {
|
||||
} .bss.data16 (NOLOAD) : AT ( _bss_data16_lma ) {
|
||||
*(.bss16)
|
||||
*(.bss16.*)
|
||||
*(.stack16)
|
||||
|
@ -114,6 +116,7 @@ SECTIONS {
|
|||
}
|
||||
_data16_filesz = ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );
|
||||
_data16_memsz = ABSOLUTE ( _edata16 ) - ABSOLUTE ( _data16 );
|
||||
_data16_padsz = ABSOLUTE ( _edata16 ) - ABSOLUTE ( _mdata16 );
|
||||
|
||||
/*
|
||||
* The 32-bit sections
|
||||
|
@ -135,7 +138,7 @@ SECTIONS {
|
|||
KEEP(*(.provided))
|
||||
KEEP(*(.provided.*))
|
||||
_mtextdata = .;
|
||||
} .bss.textdata (NOLOAD) : AT ( _end_lma ) {
|
||||
} .bss.textdata (NOLOAD) : AT ( _bss_textdata_lma ) {
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
|
@ -157,6 +160,7 @@ SECTIONS {
|
|||
}
|
||||
_textdata_filesz = ABSOLUTE ( _mtextdata ) - ABSOLUTE ( _textdata );
|
||||
_textdata_memsz = ABSOLUTE ( _etextdata ) - ABSOLUTE ( _textdata );
|
||||
_textdata_padsz = ABSOLUTE ( _etextdata ) - ABSOLUTE ( _mtextdata );
|
||||
|
||||
/*
|
||||
* Payload prefix
|
||||
|
@ -169,11 +173,12 @@ SECTIONS {
|
|||
KEEP(*(.pprefix))
|
||||
KEEP(*(.pprefix.*))
|
||||
_mpprefix = .;
|
||||
} .bss.pprefix (NOLOAD) : AT ( _end_lma ) {
|
||||
} .bss.pprefix (NOLOAD) : AT ( _bss_pprefix_lma ) {
|
||||
_epprefix = .;
|
||||
}
|
||||
_pprefix_filesz = ABSOLUTE ( _mpprefix ) - ABSOLUTE ( _pprefix );
|
||||
_pprefix_memsz = ABSOLUTE ( _epprefix ) - ABSOLUTE ( _pprefix );
|
||||
_pprefix_padsz = ABSOLUTE ( _epprefix ) - ABSOLUTE ( _mpprefix );
|
||||
|
||||
/*
|
||||
* Compressor information block
|
||||
|
@ -185,11 +190,12 @@ SECTIONS {
|
|||
KEEP(*(.zinfo))
|
||||
KEEP(*(.zinfo.*))
|
||||
_mzinfo = .;
|
||||
} .bss.zinfo (NOLOAD) : AT ( _end_lma ) {
|
||||
} .bss.zinfo (NOLOAD) : AT ( _bss_zinfo_lma ) {
|
||||
_ezinfo = .;
|
||||
}
|
||||
_zinfo_filesz = ABSOLUTE ( _mzinfo ) - ABSOLUTE ( _zinfo );
|
||||
_zinfo_memsz = ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _zinfo );
|
||||
_zinfo_padsz = ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _mzinfo );
|
||||
|
||||
/*
|
||||
* Weak symbols that need zero values if not otherwise defined
|
||||
|
@ -235,36 +241,65 @@ SECTIONS {
|
|||
|
||||
. = ALIGN ( _max_align );
|
||||
_prefix_lma = .;
|
||||
. += _prefix_filesz;
|
||||
. += ABSOLUTE ( _prefix_filesz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_text16_early_lma = .;
|
||||
. += _text16_early_filesz;
|
||||
. += ABSOLUTE ( _text16_early_filesz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
. = ALIGN ( _payload_align );
|
||||
_pprefix_lma = .;
|
||||
. += _pprefix_filesz;
|
||||
. += ABSOLUTE ( _pprefix_filesz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_payload_lma = .;
|
||||
_pprefix_skip = ABSOLUTE ( _payload_lma ) - ABSOLUTE ( _pprefix_lma );
|
||||
_text16_late_lma = .;
|
||||
. += _text16_late_filesz;
|
||||
. += ABSOLUTE ( _text16_late_filesz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_data16_lma = .;
|
||||
. += _data16_filesz;
|
||||
. += ABSOLUTE ( _data16_filesz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_textdata_lma = .;
|
||||
. += _textdata_filesz;
|
||||
. += ABSOLUTE ( _textdata_filesz );
|
||||
|
||||
_filesz = .; /* Do not include zinfo block in file size */
|
||||
_filesz = .; /* Do not include .bss.* or .zinfo in file size */
|
||||
|
||||
/*
|
||||
* Dummy load addresses for .bss.* and .zinfo sections
|
||||
*
|
||||
*/
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_bss_prefix_lma = .;
|
||||
. += ABSOLUTE ( _prefix_padsz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_bss_text16_lma = .;
|
||||
. += ABSOLUTE ( _text16_padsz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_bss_data16_lma = .;
|
||||
. += ABSOLUTE ( _data16_padsz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_bss_textdata_lma = .;
|
||||
. += ABSOLUTE ( _textdata_padsz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_bss_pprefix_lma = .;
|
||||
. += ABSOLUTE ( _pprefix_padsz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_bss_zinfo_lma = .;
|
||||
. += ABSOLUTE ( _zinfo_padsz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_zinfo_lma = .;
|
||||
. += _zinfo_filesz;
|
||||
. += ABSOLUTE ( _zinfo_filesz );
|
||||
|
||||
. = ALIGN ( _max_align );
|
||||
_end_lma = .;
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- ld-script -*- */
|
||||
|
||||
/*
|
||||
* Linker script for prefix-only binaries (e.g. USB disk MBR)
|
||||
*
|
||||
*/
|
||||
|
||||
SECTIONS {
|
||||
|
||||
.prefix 0x0 : AT ( 0x0 ) {
|
||||
*(.prefix)
|
||||
}
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.comment.*)
|
||||
*(.note)
|
||||
*(.note.*)
|
||||
*(.eh_frame)
|
||||
*(.eh_frame.*)
|
||||
*(.rel)
|
||||
*(.rel.*)
|
||||
*(.einfo)
|
||||
*(.einfo.*)
|
||||
*(.discard)
|
||||
*(.discard.*)
|
||||
}
|
||||
|
||||
}
|
|
@ -285,7 +285,7 @@ enable_a20:
|
|||
ret
|
||||
|
||||
.section ".text16.early.data", "aw", @progbits
|
||||
.align 2
|
||||
.balign 2
|
||||
enable_a20_method:
|
||||
.word 0
|
||||
.size enable_a20_method, . - enable_a20_method
|
||||
|
|
|
@ -99,7 +99,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
|||
****************************************************************************
|
||||
*/
|
||||
.section ".data16.gdt", "aw", @progbits
|
||||
.align 16
|
||||
.balign 16
|
||||
gdt:
|
||||
gdtr: /* The first GDT entry is unused, the GDTR can fit here. */
|
||||
gdt_limit: .word gdt_length - 1
|
||||
|
@ -210,9 +210,7 @@ VC_TMP_CR3: .space 4
|
|||
VC_TMP_CR4: .space 4
|
||||
VC_TMP_EMER: .space 8
|
||||
.endif
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
VC_TMP_FXSAVE: .space 512
|
||||
#endif
|
||||
VC_TMP_END:
|
||||
.previous
|
||||
|
||||
|
@ -224,7 +222,7 @@ RC_TMP_END:
|
|||
|
||||
/* Shared temporary static buffer */
|
||||
.section ".bss16.rm_tmpbuf", "aw", @nobits
|
||||
.align 16
|
||||
.balign 16
|
||||
rm_tmpbuf:
|
||||
.space VC_TMP_END
|
||||
.size rm_tmpbuf, . - rm_tmpbuf
|
||||
|
@ -350,6 +348,13 @@ init_librm_rmode:
|
|||
/* Initialise IDT */
|
||||
virtcall init_idt
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Check for FXSAVE/FXRSTOR */
|
||||
clc
|
||||
virtcall check_fxsr
|
||||
setnc fxsr_supported
|
||||
#endif
|
||||
|
||||
/* Restore registers */
|
||||
popl %edi
|
||||
popl %ebx
|
||||
|
@ -366,6 +371,10 @@ set_seg_base:
|
|||
roll $16, %eax
|
||||
ret
|
||||
|
||||
.section ".data16.fxsr_supported", "awx", @progbits
|
||||
fxsr_supported: /* FXSAVE/FXRSTOR instructions supported */
|
||||
.byte 0
|
||||
|
||||
/****************************************************************************
|
||||
* real_to_prot (real-mode near call, 32-bit virtual return address)
|
||||
*
|
||||
|
@ -1007,10 +1016,11 @@ virt_call:
|
|||
cli
|
||||
movw %cs:rm_ds, %ds
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Preserve FPU, MMX and SSE state in temporary static buffer */
|
||||
testb $0xff, fxsr_supported
|
||||
jz 1f
|
||||
fxsave ( rm_tmpbuf + VC_TMP_FXSAVE )
|
||||
#endif
|
||||
1:
|
||||
/* Preserve GDT and IDT in temporary static buffer */
|
||||
sidt ( rm_tmpbuf + VC_TMP_IDT )
|
||||
sgdt ( rm_tmpbuf + VC_TMP_GDT )
|
||||
|
@ -1077,10 +1087,11 @@ vc_rmode:
|
|||
wrmsr
|
||||
.endif
|
||||
|
||||
#ifdef TIVOLI_VMM_WORKAROUND
|
||||
/* Restore FPU, MMX and SSE state from temporary static buffer */
|
||||
testb $0xff, fxsr_supported
|
||||
jz 1f
|
||||
fxrstor ( rm_tmpbuf + VC_TMP_FXSAVE )
|
||||
#endif
|
||||
1:
|
||||
/* Restore registers and flags and return */
|
||||
popl %eax /* skip %cs and %ss */
|
||||
popw %ds
|
||||
|
@ -1470,7 +1481,7 @@ interrupt_wrapper:
|
|||
****************************************************************************
|
||||
*/
|
||||
.section ".pages", "aw", @nobits
|
||||
.align SIZEOF_PT
|
||||
.balign SIZEOF_PT
|
||||
|
||||
/* Page map level 4 entries (PML4Es)
|
||||
*
|
||||
|
|
|
@ -14,6 +14,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <realmode.h>
|
||||
#include <pic8259.h>
|
||||
#include <ipxe/shell.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
|
||||
/*
|
||||
* This file provides functions for managing librm.
|
||||
|
@ -118,7 +119,7 @@ void set_interrupt_vector ( unsigned int intr, void *vector ) {
|
|||
* Initialise interrupt descriptor table
|
||||
*
|
||||
*/
|
||||
void init_idt ( void ) {
|
||||
__asmcall void init_idt ( void ) {
|
||||
struct interrupt_vector *vec;
|
||||
unsigned int intr;
|
||||
|
||||
|
@ -386,6 +387,21 @@ static void iounmap_pages ( volatile const void *io_addr ) {
|
|||
io_addr, first, i );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for FXSAVE/FXRSTOR instruction support
|
||||
*
|
||||
*/
|
||||
__asmcall void check_fxsr ( struct i386_all_regs *regs ) {
|
||||
struct x86_features features;
|
||||
|
||||
/* Check for FXSR bit */
|
||||
x86_features ( &features );
|
||||
if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_FXSR ) )
|
||||
regs->flags |= CF;
|
||||
DBGC ( &features, "FXSAVE/FXRSTOR is%s supported\n",
|
||||
( ( regs->flags & CF ) ? " not" : "" ) );
|
||||
}
|
||||
|
||||
PROVIDE_UACCESS_INLINE ( librm, phys_to_user );
|
||||
PROVIDE_UACCESS_INLINE ( librm, user_to_phys );
|
||||
PROVIDE_UACCESS_INLINE ( librm, virt_to_user );
|
||||
|
|
|
@ -58,7 +58,8 @@ static struct profiler virt_call_profiler __profiler = { .name = "virt_call" };
|
|||
/**
|
||||
* Dummy function for profiling tests
|
||||
*/
|
||||
static __asmcall void librm_test_call ( struct i386_all_regs *ix86 __unused ) {
|
||||
static __asmcall __used void
|
||||
librm_test_call ( struct i386_all_regs *ix86 __unused ) {
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#ifndef ASSEMBLY
|
||||
|
||||
/** Declare a function with standard calling conventions */
|
||||
#define __asmcall __attribute__ (( used, regparm(0) ))
|
||||
#define __asmcall __attribute__ (( regparm(0) ))
|
||||
|
||||
/** Declare a function with libgcc implicit linkage */
|
||||
#define __libgcc
|
||||
|
|
|
@ -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 */
|
|
@ -3,6 +3,22 @@
|
|||
echo Amazon EC2 - iPXE boot via user-data
|
||||
echo CPU: ${cpuvendor} ${cpumodel}
|
||||
ifstat ||
|
||||
dhcp ||
|
||||
|
||||
set attempt:int8 1
|
||||
:dhcp_retry
|
||||
echo DHCP attempt ${attempt}
|
||||
dhcp --timeout 5000 && goto dhcp_ok ||
|
||||
ifstat ||
|
||||
inc attempt
|
||||
iseq ${attempt} 10 || goto dhcp_retry
|
||||
|
||||
:dhcp_fail
|
||||
echo DHCP failed - rebooting
|
||||
reboot ||
|
||||
exit
|
||||
|
||||
:dhcp_ok
|
||||
route ||
|
||||
chain -ar http://169.254.169.254/latest/user-data
|
||||
chain -ar http://169.254.169.254/latest/user-data ||
|
||||
ifstat ||
|
||||
exit
|
||||
|
|
|
@ -18,8 +18,13 @@
|
|||
* Note that the serial port output from an AWS EC2 virtual machine is
|
||||
* generally available (as the "System Log") only after the instance
|
||||
* has been stopped.
|
||||
*
|
||||
* Enable only for non-EFI builds, on the assumption that the standard
|
||||
* EFI firmware is likely to already be logging to the serial port.
|
||||
*/
|
||||
#ifndef PLATFORM_efi
|
||||
#define CONSOLE_SERIAL
|
||||
#endif
|
||||
|
||||
/* Log to partition on local disk
|
||||
*
|
||||
|
|
|
@ -5,4 +5,5 @@ echo CPU: ${cpuvendor} ${cpumodel}
|
|||
ifstat ||
|
||||
dhcp ||
|
||||
route ||
|
||||
chain -ar http://metadata.google.internal/computeMetadata/v1/instance/attributes/ipxeboot
|
||||
chain -ar http://metadata.google.internal/computeMetadata/v1/instance/attributes/ipxeboot ||
|
||||
ifstat ||
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
/* Enable IPv6 and HTTPS */
|
||||
#define NET_PROTO_IPV6
|
||||
#define DOWNLOAD_PROTO_HTTPS
|
||||
|
||||
/* Allow retrieval of metadata (such as an iPXE boot script) from
|
||||
* Google Compute Engine metadata server.
|
||||
*/
|
||||
#define HTTP_HACK_GCE
|
||||
|
||||
/* Allow scripts to handle errors by powering down the VM to avoid
|
||||
* incurring unnecessary costs.
|
||||
*/
|
||||
#define POWEROFF_CMD
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
/* Work around missing PCI BIOS calls in the cut-down SeaBIOS found in
|
||||
* some AWS EC2 instances.
|
||||
*/
|
||||
#ifdef PLATFORM_pcbios
|
||||
#undef PCIAPI_PCBIOS
|
||||
#define PCIAPI_DIRECT
|
||||
#endif
|
|
@ -1,4 +1,6 @@
|
|||
/* It can often be useful to know the CPU on which a cloud instance is
|
||||
* running (e.g. to isolate problems with Azure AMD instances).
|
||||
*/
|
||||
#if defined ( __i386__ ) || defined ( __x86_64__ )
|
||||
#define CPUID_SETTINGS
|
||||
#endif
|
||||
|
|
|
@ -182,6 +182,12 @@ REQUIRE_OBJECT ( efi_image );
|
|||
#ifdef IMAGE_SDI
|
||||
REQUIRE_OBJECT ( sdi );
|
||||
#endif
|
||||
#ifdef IMAGE_ZLIB
|
||||
REQUIRE_OBJECT ( zlib );
|
||||
#endif
|
||||
#ifdef IMAGE_GZIP
|
||||
REQUIRE_OBJECT ( gzip );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Drag in all requested commands
|
||||
|
@ -281,6 +287,9 @@ REQUIRE_OBJECT ( ntp_cmd );
|
|||
#ifdef CERT_CMD
|
||||
REQUIRE_OBJECT ( cert_cmd );
|
||||
#endif
|
||||
#ifdef IMAGE_MEM_CMD
|
||||
REQUIRE_OBJECT ( image_mem_cmd );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Drag in miscellaneous objects
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <config/general.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Archive image configuration
|
||||
*
|
||||
*/
|
||||
|
||||
PROVIDE_REQUIRING_SYMBOL();
|
||||
|
||||
#ifdef IMAGE_ARCHIVE_CMD
|
||||
REQUIRE_OBJECT ( image_archive_cmd );
|
||||
#endif
|
|
@ -33,6 +33,56 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
PROVIDE_REQUIRING_SYMBOL();
|
||||
|
||||
/* RSA */
|
||||
#if defined ( CRYPTO_PUBKEY_RSA )
|
||||
REQUIRE_OBJECT ( oid_rsa );
|
||||
#endif
|
||||
|
||||
/* MD4 */
|
||||
#if defined ( CRYPTO_DIGEST_MD4 )
|
||||
REQUIRE_OBJECT ( oid_md4 );
|
||||
#endif
|
||||
|
||||
/* MD5 */
|
||||
#if defined ( CRYPTO_DIGEST_MD5 )
|
||||
REQUIRE_OBJECT ( oid_md5 );
|
||||
#endif
|
||||
|
||||
/* SHA-1 */
|
||||
#if defined ( CRYPTO_DIGEST_SHA1 )
|
||||
REQUIRE_OBJECT ( oid_sha1 );
|
||||
#endif
|
||||
|
||||
/* SHA-224 */
|
||||
#if defined ( CRYPTO_DIGEST_SHA224 )
|
||||
REQUIRE_OBJECT ( oid_sha224 );
|
||||
#endif
|
||||
|
||||
/* SHA-256 */
|
||||
#if defined ( CRYPTO_DIGEST_SHA256 )
|
||||
REQUIRE_OBJECT ( oid_sha256 );
|
||||
#endif
|
||||
|
||||
/* SHA-384 */
|
||||
#if defined ( CRYPTO_DIGEST_SHA384 )
|
||||
REQUIRE_OBJECT ( oid_sha384 );
|
||||
#endif
|
||||
|
||||
/* SHA-512 */
|
||||
#if defined ( CRYPTO_DIGEST_SHA512 )
|
||||
REQUIRE_OBJECT ( oid_sha512 );
|
||||
#endif
|
||||
|
||||
/* SHA-512/224 */
|
||||
#if defined ( CRYPTO_DIGEST_SHA512_224 )
|
||||
REQUIRE_OBJECT ( oid_sha512_224 );
|
||||
#endif
|
||||
|
||||
/* SHA-512/256 */
|
||||
#if defined ( CRYPTO_DIGEST_SHA512_256 )
|
||||
REQUIRE_OBJECT ( oid_sha512_256 );
|
||||
#endif
|
||||
|
||||
/* RSA and MD5 */
|
||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_DIGEST_MD5 )
|
||||
REQUIRE_OBJECT ( rsa_md5 );
|
||||
|
|
|
@ -46,3 +46,6 @@ REQUIRE_OBJECT ( stp );
|
|||
#ifdef NET_PROTO_LACP
|
||||
REQUIRE_OBJECT ( eth_slow );
|
||||
#endif
|
||||
#ifdef NET_PROTO_EAPOL
|
||||
REQUIRE_OBJECT ( eapol );
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,9 @@ REQUIRE_OBJECT ( usbio );
|
|||
#ifdef USB_KEYBOARD
|
||||
REQUIRE_OBJECT ( usbkbd );
|
||||
#endif
|
||||
#ifdef USB_BLOCK
|
||||
REQUIRE_OBJECT ( usbblk );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Drag in USB external interfaces
|
||||
|
|
|
@ -9,31 +9,28 @@
|
|||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Minimum TLS version */
|
||||
#define TLS_VERSION_MIN TLS_VERSION_TLS_1_1
|
||||
|
||||
/** RSA public-key algorithm */
|
||||
#define CRYPTO_PUBKEY_RSA
|
||||
|
||||
/** AES-CBC block cipher */
|
||||
#define CRYPTO_CIPHER_AES_CBC
|
||||
|
||||
/** MD5 digest algorithm
|
||||
*
|
||||
* Note that use of MD5 is implicit when using TLSv1.1 or earlier.
|
||||
*/
|
||||
#define CRYPTO_DIGEST_MD5
|
||||
/** MD4 digest algorithm */
|
||||
//#define CRYPTO_DIGEST_MD4
|
||||
|
||||
/** SHA-1 digest algorithm
|
||||
*
|
||||
* Note that use of SHA-1 is implicit when using TLSv1.1 or earlier.
|
||||
*/
|
||||
/** MD5 digest algorithm */
|
||||
//#define CRYPTO_DIGEST_MD5
|
||||
|
||||
/** SHA-1 digest algorithm */
|
||||
#define CRYPTO_DIGEST_SHA1
|
||||
|
||||
/** SHA-224 digest algorithm */
|
||||
#define CRYPTO_DIGEST_SHA224
|
||||
|
||||
/** SHA-256 digest algorithm
|
||||
*
|
||||
* Note that use of SHA-256 is implicit when using TLSv1.2.
|
||||
*/
|
||||
/** SHA-256 digest algorithm */
|
||||
#define CRYPTO_DIGEST_SHA256
|
||||
|
||||
/** SHA-384 digest algorithm */
|
||||
|
@ -42,6 +39,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
/** SHA-512 digest algorithm */
|
||||
#define CRYPTO_DIGEST_SHA512
|
||||
|
||||
/** SHA-512/224 digest algorithm */
|
||||
//#define CRYPTO_DIGEST_SHA512_224
|
||||
|
||||
/** SHA-512/256 digest algorithm */
|
||||
//#define CRYPTO_DIGEST_SHA512_256
|
||||
|
||||
/** Margin of error (in seconds) allowed in signed timestamps
|
||||
*
|
||||
* We default to allowing a reasonable margin of error: 12 hours to
|
||||
|
|
|
@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define UACCESS_EFI
|
||||
#define IOMAP_VIRT
|
||||
#define PCIAPI_EFI
|
||||
#define DMAAPI_OP
|
||||
#define CONSOLE_EFI
|
||||
#define TIMER_EFI
|
||||
#define UMALLOC_EFI
|
||||
|
@ -24,6 +25,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define ACPI_EFI
|
||||
#define FDT_EFI
|
||||
|
||||
#define NET_PROTO_IPV6 /* IPv6 protocol */
|
||||
|
||||
#define DOWNLOAD_PROTO_FILE /* Local filesystem access */
|
||||
|
||||
#define IMAGE_EFI /* EFI image support */
|
||||
|
@ -39,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define USB_HCD_EHCI /* EHCI USB host controller */
|
||||
#define USB_HCD_UHCI /* UHCI USB host controller */
|
||||
#define USB_EFI /* Provide EFI_USB_IO_PROTOCOL interface */
|
||||
#define USB_BLOCK /* USB block devices */
|
||||
|
||||
#define REBOOT_CMD /* Reboot command */
|
||||
|
||||
|
@ -46,6 +50,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define IOAPI_X86
|
||||
#define NAP_EFIX86
|
||||
#define CPUID_CMD /* x86 CPU feature detection command */
|
||||
#define UNSAFE_STD /* Avoid setting direction flag */
|
||||
#endif
|
||||
|
||||
#if defined ( __arm__ ) || defined ( __aarch64__ )
|
||||
|
|
|
@ -20,6 +20,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||
#define TIME_LINUX
|
||||
#define REBOOT_NULL
|
||||
#define PCIAPI_LINUX
|
||||
#define DMAAPI_FLAT
|
||||
#define ACPI_LINUX
|
||||
|
||||
#define DRIVERS_LINUX
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define UACCESS_LIBRM
|
||||
#define IOAPI_X86
|
||||
#define PCIAPI_PCBIOS
|
||||
#define DMAAPI_FLAT
|
||||
#define TIMER_PCBIOS
|
||||
#define CONSOLE_PCBIOS
|
||||
#define NAP_PCBIOS
|
||||
|
@ -48,6 +49,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define USB_HCD_EHCI /* EHCI USB host controller */
|
||||
#define USB_HCD_UHCI /* UHCI USB host controller */
|
||||
#define USB_KEYBOARD /* USB keyboards */
|
||||
#define USB_BLOCK /* USB block devices */
|
||||
|
||||
#define REBOOT_CMD /* Reboot command */
|
||||
#define CPUID_CMD /* x86 CPU feature detection command */
|
||||
|
|
|
@ -28,7 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
* Maximum number of discovery deferrals due to blocked links
|
||||
* (e.g. from non-forwarding STP ports)
|
||||
*/
|
||||
#define DHCP_DISC_MAX_DEFERRALS 60
|
||||
#define DHCP_DISC_MAX_DEFERRALS 180
|
||||
|
||||
/*
|
||||
* ProxyDHCP offers are given precedence by continue to wait for them
|
||||
|
|
|
@ -35,10 +35,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*/
|
||||
|
||||
#define NET_PROTO_IPV4 /* IPv4 protocol */
|
||||
#undef NET_PROTO_IPV6 /* IPv6 protocol */
|
||||
//#define NET_PROTO_IPV6 /* IPv6 protocol */
|
||||
#undef NET_PROTO_FCOE /* Fibre Channel over Ethernet protocol */
|
||||
#define NET_PROTO_STP /* Spanning Tree protocol */
|
||||
#define NET_PROTO_LACP /* Link Aggregation control protocol */
|
||||
#define NET_PROTO_EAPOL /* EAP over LAN protocol */
|
||||
|
||||
/*
|
||||
* PXE support
|
||||
|
@ -116,6 +117,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define IMAGE_PNG /* PNG image support */
|
||||
#define IMAGE_DER /* DER image support */
|
||||
#define IMAGE_PEM /* PEM image support */
|
||||
//#define IMAGE_ZLIB /* ZLIB image support */
|
||||
//#define IMAGE_GZIP /* GZIP image support */
|
||||
|
||||
/*
|
||||
* Command-line commands to include
|
||||
|
@ -154,6 +157,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
//#define PROFSTAT_CMD /* Profiling commands */
|
||||
//#define NTP_CMD /* NTP commands */
|
||||
//#define CERT_CMD /* Certificate management commands */
|
||||
//#define IMAGE_MEM_CMD /* Read memory command */
|
||||
#define IMAGE_ARCHIVE_CMD /* Archive image management commands */
|
||||
|
||||
/*
|
||||
* ROM-specific options
|
||||
|
|
|
@ -14,6 +14,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
//#undef PCIAPI_PCBIOS /* Access via PCI BIOS */
|
||||
//#define PCIAPI_DIRECT /* Direct access via Type 1 accesses */
|
||||
|
||||
#include <config/named.h>
|
||||
#include NAMED_CONFIG(ioapi.h)
|
||||
#include <config/local/ioapi.h>
|
||||
#include LOCAL_NAMED_CONFIG(ioapi.h)
|
||||
|
||||
#endif /* CONFIG_IOAPI_H */
|
||||
|
|
|
@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*
|
||||
*/
|
||||
//#undef USB_KEYBOARD /* USB keyboards */
|
||||
//#undef USB_BLOCK /* USB block devices */
|
||||
|
||||
/*
|
||||
* USB external interfaces
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/image.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Archive images
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extract archive image
|
||||
*
|
||||
* @v image Image
|
||||
* @v name Extracted image name
|
||||
* @v extracted Extracted image to fill in
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int image_extract ( struct image *image, const char *name,
|
||||
struct image **extracted ) {
|
||||
char *dot;
|
||||
int rc;
|
||||
|
||||
/* Check that this image can be used to extract an archive image */
|
||||
if ( ! ( image->type && image->type->extract ) ) {
|
||||
rc = -ENOTSUP;
|
||||
goto err_unsupported;
|
||||
}
|
||||
|
||||
/* Allocate new image */
|
||||
*extracted = alloc_image ( image->uri );
|
||||
if ( ! *extracted ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
/* Set image name */
|
||||
if ( ( rc = image_set_name ( *extracted,
|
||||
( name ? name : image->name ) ) ) != 0 ) {
|
||||
goto err_set_name;
|
||||
}
|
||||
|
||||
/* Strip any archive or compression suffix from implicit name */
|
||||
if ( ( ! name ) && ( (*extracted)->name ) &&
|
||||
( ( dot = strrchr ( (*extracted)->name, '.' ) ) != NULL ) ) {
|
||||
*dot = '\0';
|
||||
}
|
||||
|
||||
/* Try extracting archive image */
|
||||
if ( ( rc = image->type->extract ( image, *extracted ) ) != 0 ) {
|
||||
DBGC ( image, "IMAGE %s could not extract image: %s\n",
|
||||
image->name, strerror ( rc ) );
|
||||
goto err_extract;
|
||||
}
|
||||
|
||||
/* Register image */
|
||||
if ( ( rc = register_image ( *extracted ) ) != 0 )
|
||||
goto err_register;
|
||||
|
||||
/* Propagate trust flag */
|
||||
if ( image->flags & IMAGE_TRUSTED )
|
||||
image_trust ( *extracted );
|
||||
|
||||
/* Drop local reference to image */
|
||||
image_put ( *extracted );
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_image ( *extracted );
|
||||
err_register:
|
||||
err_extract:
|
||||
err_set_name:
|
||||
image_put ( *extracted );
|
||||
err_alloc:
|
||||
err_unsupported:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract and execute image
|
||||
*
|
||||
* @v image Image
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int image_extract_exec ( struct image *image ) {
|
||||
struct image *extracted;
|
||||
int rc;
|
||||
|
||||
/* Extract image */
|
||||
if ( ( rc = image_extract ( image, NULL, &extracted ) ) != 0 )
|
||||
goto err_extract;
|
||||
|
||||
/* Set image command line */
|
||||
if ( ( rc = image_set_cmdline ( extracted, image->cmdline ) ) != 0 )
|
||||
goto err_set_cmdline;
|
||||
|
||||
/* Set auto-unregister flag */
|
||||
extracted->flags |= IMAGE_AUTO_UNREGISTER;
|
||||
|
||||
/* Tail-recurse into extracted image */
|
||||
return image_exec ( extracted );
|
||||
|
||||
err_set_cmdline:
|
||||
unregister_image ( extracted );
|
||||
err_extract:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Drag in objects via image_extract() */
|
||||
REQUIRING_SYMBOL ( image_extract );
|
||||
|
||||
/* Drag in archive image formats */
|
||||
REQUIRE_OBJECT ( config_archive );
|
|
@ -36,7 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*
|
||||
*/
|
||||
|
||||
static const char base64[64] =
|
||||
static const char base64[ 64 + 1 /* NUL */ ] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/**
|
||||
|
|
|
@ -242,9 +242,7 @@ int block_translate ( struct interface *block, userptr_t buffer, size_t size ) {
|
|||
}
|
||||
|
||||
/* Attach to interfaces, mortalise self, and return */
|
||||
assert ( block->dest != &null_intf );
|
||||
intf_plug_plug ( &blktrans->xfer, block->dest );
|
||||
intf_plug_plug ( &blktrans->block, block );
|
||||
intf_insert ( block, &blktrans->block, &blktrans->xfer );
|
||||
ref_put ( &blktrans->refcnt );
|
||||
|
||||
DBGC2 ( blktrans, "BLKTRANS %p created", blktrans );
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/dhcppkt.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
#include <ipxe/cachedhcp.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Cached DHCP packet
|
||||
*
|
||||
*/
|
||||
|
||||
/** A cached DHCP packet */
|
||||
struct cached_dhcp_packet {
|
||||
/** Settings block name */
|
||||
const char *name;
|
||||
/** DHCP packet (if any) */
|
||||
struct dhcp_packet *dhcppkt;
|
||||
};
|
||||
|
||||
/** Cached DHCPACK */
|
||||
struct cached_dhcp_packet cached_dhcpack = {
|
||||
.name = DHCP_SETTINGS_NAME,
|
||||
};
|
||||
|
||||
/** Cached ProxyDHCPOFFER */
|
||||
struct cached_dhcp_packet cached_proxydhcp = {
|
||||
.name = PROXYDHCP_SETTINGS_NAME,
|
||||
};
|
||||
|
||||
/** Cached PXEBSACK */
|
||||
struct cached_dhcp_packet cached_pxebs = {
|
||||
.name = PXEBS_SETTINGS_NAME,
|
||||
};
|
||||
|
||||
/** List of cached DHCP packets */
|
||||
static struct cached_dhcp_packet *cached_packets[] = {
|
||||
&cached_dhcpack,
|
||||
&cached_proxydhcp,
|
||||
&cached_pxebs,
|
||||
};
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &cached_dhcpack
|
||||
|
||||
/**
|
||||
* Free cached DHCP packet
|
||||
*
|
||||
* @v cache Cached DHCP packet
|
||||
*/
|
||||
static void cachedhcp_free ( struct cached_dhcp_packet *cache ) {
|
||||
|
||||
dhcppkt_put ( cache->dhcppkt );
|
||||
cache->dhcppkt = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply cached DHCP packet settings
|
||||
*
|
||||
* @v cache Cached DHCP packet
|
||||
* @v netdev Network device, or NULL
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
|
||||
struct net_device *netdev ) {
|
||||
struct settings *settings;
|
||||
int rc;
|
||||
|
||||
/* Do nothing if cache is empty */
|
||||
if ( ! cache->dhcppkt )
|
||||
return 0;
|
||||
|
||||
/* Do nothing unless cached packet's MAC address matches this
|
||||
* network device, if specified.
|
||||
*/
|
||||
if ( netdev ) {
|
||||
if ( memcmp ( netdev->ll_addr, cache->dhcppkt->dhcphdr->chaddr,
|
||||
netdev->ll_protocol->ll_addr_len ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP %s does not match %s\n",
|
||||
cache->name, netdev->name );
|
||||
return 0;
|
||||
}
|
||||
DBGC ( colour, "CACHEDHCP %s is for %s\n",
|
||||
cache->name, netdev->name );
|
||||
}
|
||||
|
||||
/* Select appropriate parent settings block */
|
||||
settings = ( netdev ? netdev_settings ( netdev ) : NULL );
|
||||
|
||||
/* Register settings */
|
||||
if ( ( rc = register_settings ( &cache->dhcppkt->settings, settings,
|
||||
cache->name ) ) != 0 ) {
|
||||
DBGC ( colour, "CACHEDHCP %s could not register settings: %s\n",
|
||||
cache->name, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Free cached DHCP packet */
|
||||
cachedhcp_free ( cache );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record cached DHCP packet
|
||||
*
|
||||
* @v cache Cached DHCP packet
|
||||
* @v data DHCPACK packet buffer
|
||||
* @v max_len Maximum possible length
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
|
||||
size_t max_len ) {
|
||||
struct dhcp_packet *dhcppkt;
|
||||
struct dhcp_packet *tmp;
|
||||
struct dhcphdr *dhcphdr;
|
||||
unsigned int i;
|
||||
size_t len;
|
||||
|
||||
/* Free any existing cached packet */
|
||||
cachedhcp_free ( cache );
|
||||
|
||||
/* Allocate and populate DHCP packet */
|
||||
dhcppkt = zalloc ( sizeof ( *dhcppkt ) + max_len );
|
||||
if ( ! dhcppkt ) {
|
||||
DBGC ( colour, "CACHEDHCP %s could not allocate copy\n",
|
||||
cache->name );
|
||||
return -ENOMEM;
|
||||
}
|
||||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
|
||||
copy_from_user ( dhcphdr, data, 0, max_len );
|
||||
dhcppkt_init ( dhcppkt, dhcphdr, max_len );
|
||||
|
||||
/* Shrink packet to required length. If reallocation fails,
|
||||
* just continue to use the original packet and waste the
|
||||
* unused space.
|
||||
*/
|
||||
len = dhcppkt_len ( dhcppkt );
|
||||
assert ( len <= max_len );
|
||||
tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) );
|
||||
if ( tmp )
|
||||
dhcppkt = tmp;
|
||||
|
||||
/* Reinitialise packet at new address */
|
||||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
|
||||
dhcppkt_init ( dhcppkt, dhcphdr, len );
|
||||
|
||||
/* Discard duplicate packets, since some PXE stacks (including
|
||||
* iPXE itself) will report the DHCPACK packet as the PXEBSACK
|
||||
* if no separate PXEBSACK exists.
|
||||
*/
|
||||
for ( i = 0 ; i < ( sizeof ( cached_packets ) /
|
||||
sizeof ( cached_packets[0] ) ) ; i++ ) {
|
||||
tmp = cached_packets[i]->dhcppkt;
|
||||
if ( tmp && ( dhcppkt_len ( tmp ) == len ) &&
|
||||
( memcmp ( tmp->dhcphdr, dhcppkt->dhcphdr, len ) == 0 ) ) {
|
||||
DBGC ( colour, "CACHEDHCP %s duplicates %s\n",
|
||||
cache->name, cached_packets[i]->name );
|
||||
dhcppkt_put ( dhcppkt );
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store as cached packet */
|
||||
DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name,
|
||||
user_to_phys ( data, 0 ), len, max_len );
|
||||
cache->dhcppkt = dhcppkt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached DHCPACK startup function
|
||||
*
|
||||
*/
|
||||
static void cachedhcp_startup ( void ) {
|
||||
|
||||
/* Apply cached ProxyDHCPOFFER, if any */
|
||||
cachedhcp_apply ( &cached_proxydhcp, NULL );
|
||||
|
||||
/* Apply cached PXEBSACK, if any */
|
||||
cachedhcp_apply ( &cached_pxebs, NULL );
|
||||
|
||||
/* Free any remaining cached packets */
|
||||
if ( cached_dhcpack.dhcppkt ) {
|
||||
DBGC ( colour, "CACHEDHCP %s unclaimed\n",
|
||||
cached_dhcpack.name );
|
||||
}
|
||||
cachedhcp_free ( &cached_dhcpack );
|
||||
cachedhcp_free ( &cached_proxydhcp );
|
||||
cachedhcp_free ( &cached_pxebs );
|
||||
}
|
||||
|
||||
/** Cached DHCPACK startup function */
|
||||
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
|
||||
.name = "cachedhcp",
|
||||
.startup = cachedhcp_startup,
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply cached DHCPACK to network device, if applicable
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int cachedhcp_probe ( struct net_device *netdev ) {
|
||||
|
||||
/* Apply cached DHCPACK to network device, if applicable */
|
||||
return cachedhcp_apply ( &cached_dhcpack, netdev );
|
||||
}
|
||||
|
||||
/** Cached DHCP packet network device driver */
|
||||
struct net_driver cachedhcp_driver __net_driver = {
|
||||
.name = "cachedhcp",
|
||||
.probe = cachedhcp_probe,
|
||||
};
|
|
@ -20,11 +20,12 @@ unsigned int console_height = CONSOLE_DEFAULT_HEIGHT;
|
|||
* Write a single character to each console device
|
||||
*
|
||||
* @v character Character to be written
|
||||
* @ret character Character written
|
||||
*
|
||||
* The character is written out to all enabled console devices, using
|
||||
* each device's console_driver::putchar() method.
|
||||
*/
|
||||
void putchar ( int character ) {
|
||||
int putchar ( int character ) {
|
||||
struct console_driver *console;
|
||||
|
||||
/* Automatic LF -> CR,LF translation */
|
||||
|
@ -37,6 +38,8 @@ void putchar ( int character ) {
|
|||
console->putchar )
|
||||
console->putchar ( character );
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ipxe/cpio.h>
|
||||
|
||||
|
@ -45,3 +46,87 @@ void cpio_set_field ( char *field, unsigned long value ) {
|
|||
snprintf ( buf, sizeof ( buf ), "%08lx", value );
|
||||
memcpy ( field, buf, 8 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CPIO image filename
|
||||
*
|
||||
* @v image Image
|
||||
* @ret len CPIO filename length (0 for no filename)
|
||||
*/
|
||||
size_t cpio_name_len ( struct image *image ) {
|
||||
const char *name = cpio_name ( image );
|
||||
char *sep;
|
||||
size_t len;
|
||||
|
||||
/* Check for existence of CPIO filename */
|
||||
if ( ! name )
|
||||
return 0;
|
||||
|
||||
/* Locate separator (if any) */
|
||||
sep = strchr ( name, ' ' );
|
||||
len = ( sep ? ( ( size_t ) ( sep - name ) ) : strlen ( name ) );
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CPIO image parameters
|
||||
*
|
||||
* @v image Image
|
||||
* @v cpio CPIO header to fill in
|
||||
*/
|
||||
static void cpio_parse_cmdline ( struct image *image,
|
||||
struct cpio_header *cpio ) {
|
||||
const char *cmdline;
|
||||
char *arg;
|
||||
char *end;
|
||||
unsigned int mode;
|
||||
|
||||
/* Skip image filename */
|
||||
cmdline = ( cpio_name ( image ) + cpio_name_len ( image ) );
|
||||
|
||||
/* Look for "mode=" */
|
||||
if ( ( arg = strstr ( cmdline, "mode=" ) ) ) {
|
||||
arg += 5;
|
||||
mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
|
||||
if ( *end && ( *end != ' ' ) ) {
|
||||
DBGC ( image, "CPIO %p strange \"mode=\" "
|
||||
"terminator '%c'\n", image, *end );
|
||||
}
|
||||
cpio_set_field ( cpio->c_mode, ( 0100000 | mode ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct CPIO header for image, if applicable
|
||||
*
|
||||
* @v image Image
|
||||
* @v cpio CPIO header to fill in
|
||||
* @ret len Length of magic CPIO header (including filename)
|
||||
*/
|
||||
size_t cpio_header ( struct image *image, struct cpio_header *cpio ) {
|
||||
size_t name_len;
|
||||
size_t len;
|
||||
|
||||
/* Get filename length */
|
||||
name_len = cpio_name_len ( image );
|
||||
|
||||
/* Images with no filename are assumed to already be CPIO archives */
|
||||
if ( ! name_len )
|
||||
return 0;
|
||||
|
||||
/* Construct CPIO header */
|
||||
memset ( cpio, '0', sizeof ( *cpio ) );
|
||||
memcpy ( cpio->c_magic, CPIO_MAGIC, sizeof ( cpio->c_magic ) );
|
||||
cpio_set_field ( cpio->c_mode, 0100644 );
|
||||
cpio_set_field ( cpio->c_nlink, 1 );
|
||||
cpio_set_field ( cpio->c_filesize, image->len );
|
||||
cpio_set_field ( cpio->c_namesize, ( name_len + 1 /* NUL */ ) );
|
||||
cpio_parse_cmdline ( image, cpio );
|
||||
|
||||
/* Calculate total length */
|
||||
len = ( ( sizeof ( *cpio ) + name_len + 1 /* NUL */ + CPIO_ALIGN - 1 )
|
||||
& ~( CPIO_ALIGN - 1 ) );
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/dma.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DMA mappings
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Flat address space DMA API
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_map );
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_unmap );
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_alloc );
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_free );
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_umalloc );
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_ufree );
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_set_mask );
|
||||
PROVIDE_DMAAPI_INLINE ( flat, dma_phys );
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Operations-based DMA API
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Map buffer for DMA
|
||||
*
|
||||
* @v dma DMA device
|
||||
* @v map DMA mapping to fill in
|
||||
* @v addr Buffer address
|
||||
* @v len Length of buffer
|
||||
* @v flags Mapping flags
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int dma_op_map ( struct dma_device *dma, struct dma_mapping *map,
|
||||
physaddr_t addr, size_t len, int flags ) {
|
||||
struct dma_operations *op = dma->op;
|
||||
|
||||
if ( ! op )
|
||||
return -ENODEV;
|
||||
return op->map ( dma, map, addr, len, flags );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmap buffer
|
||||
*
|
||||
* @v map DMA mapping
|
||||
*/
|
||||
static void dma_op_unmap ( struct dma_mapping *map ) {
|
||||
struct dma_device *dma = map->dma;
|
||||
|
||||
assert ( dma != NULL );
|
||||
assert ( dma->op != NULL );
|
||||
dma->op->unmap ( dma, map );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate and map DMA-coherent buffer
|
||||
*
|
||||
* @v dma DMA device
|
||||
* @v map DMA mapping to fill in
|
||||
* @v len Length of buffer
|
||||
* @v align Physical alignment
|
||||
* @ret addr Buffer address, or NULL on error
|
||||
*/
|
||||
static void * dma_op_alloc ( struct dma_device *dma, struct dma_mapping *map,
|
||||
size_t len, size_t align ) {
|
||||
struct dma_operations *op = dma->op;
|
||||
|
||||
if ( ! op )
|
||||
return NULL;
|
||||
return op->alloc ( dma, map, len, align );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmap and free DMA-coherent buffer
|
||||
*
|
||||
* @v map DMA mapping
|
||||
* @v addr Buffer address
|
||||
* @v len Length of buffer
|
||||
*/
|
||||
static void dma_op_free ( struct dma_mapping *map, void *addr, size_t len ) {
|
||||
struct dma_device *dma = map->dma;
|
||||
|
||||
assert ( dma != NULL );
|
||||
assert ( dma->op != NULL );
|
||||
dma->op->free ( dma, map, addr, len );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate and map DMA-coherent buffer from external (user) memory
|
||||
*
|
||||
* @v dma DMA device
|
||||
* @v map DMA mapping to fill in
|
||||
* @v len Length of buffer
|
||||
* @v align Physical alignment
|
||||
* @ret addr Buffer address, or NULL on error
|
||||
*/
|
||||
static userptr_t dma_op_umalloc ( struct dma_device *dma,
|
||||
struct dma_mapping *map,
|
||||
size_t len, size_t align ) {
|
||||
struct dma_operations *op = dma->op;
|
||||
|
||||
if ( ! op )
|
||||
return UNULL;
|
||||
return op->umalloc ( dma, map, len, align );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmap and free DMA-coherent buffer from external (user) memory
|
||||
*
|
||||
* @v map DMA mapping
|
||||
* @v addr Buffer address
|
||||
* @v len Length of buffer
|
||||
*/
|
||||
static void dma_op_ufree ( struct dma_mapping *map, userptr_t addr,
|
||||
size_t len ) {
|
||||
struct dma_device *dma = map->dma;
|
||||
|
||||
assert ( dma != NULL );
|
||||
assert ( dma->op != NULL );
|
||||
dma->op->ufree ( dma, map, addr, len );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set addressable space mask
|
||||
*
|
||||
* @v dma DMA device
|
||||
* @v mask Addressable space mask
|
||||
*/
|
||||
static void dma_op_set_mask ( struct dma_device *dma, physaddr_t mask ) {
|
||||
struct dma_operations *op = dma->op;
|
||||
|
||||
if ( op )
|
||||
op->set_mask ( dma, mask );
|
||||
}
|
||||
|
||||
PROVIDE_DMAAPI ( op, dma_map, dma_op_map );
|
||||
PROVIDE_DMAAPI ( op, dma_unmap, dma_op_unmap );
|
||||
PROVIDE_DMAAPI ( op, dma_alloc, dma_op_alloc );
|
||||
PROVIDE_DMAAPI ( op, dma_free, dma_op_free );
|
||||
PROVIDE_DMAAPI ( op, dma_umalloc, dma_op_umalloc );
|
||||
PROVIDE_DMAAPI ( op, dma_ufree, dma_op_ufree );
|
||||
PROVIDE_DMAAPI ( op, dma_set_mask, dma_op_set_mask );
|
||||
PROVIDE_DMAAPI_INLINE ( op, dma_phys );
|
|
@ -175,6 +175,47 @@ int image_set_cmdline ( struct image *image, const char *cmdline ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set image length
|
||||
*
|
||||
* @v image Image
|
||||
* @v len Length of image data
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int image_set_len ( struct image *image, size_t len ) {
|
||||
userptr_t new;
|
||||
|
||||
/* (Re)allocate image data */
|
||||
new = urealloc ( image->data, len );
|
||||
if ( ! new )
|
||||
return -ENOMEM;
|
||||
image->data = new;
|
||||
image->len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set image data
|
||||
*
|
||||
* @v image Image
|
||||
* @v data Image data
|
||||
* @v len Length of image data
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int image_set_data ( struct image *image, userptr_t data, size_t len ) {
|
||||
int rc;
|
||||
|
||||
/* Set image length */
|
||||
if ( ( rc = image_set_len ( image, len ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Copy in new image data */
|
||||
memcpy_user ( image->data, 0, data, 0, len );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine image type
|
||||
*
|
||||
|
@ -481,3 +522,47 @@ int image_set_trust ( int require_trusted, int permanent ) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create registered image from block of memory
|
||||
*
|
||||
* @v name Name
|
||||
* @v data Image data
|
||||
* @v len Length
|
||||
* @ret image Image, or NULL on error
|
||||
*/
|
||||
struct image * image_memory ( const char *name, userptr_t data, size_t len ) {
|
||||
struct image *image;
|
||||
int rc;
|
||||
|
||||
/* Allocate image */
|
||||
image = alloc_image ( NULL );
|
||||
if ( ! image ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_image;
|
||||
}
|
||||
|
||||
/* Set name */
|
||||
if ( ( rc = image_set_name ( image, name ) ) != 0 )
|
||||
goto err_set_name;
|
||||
|
||||
/* Set data */
|
||||
if ( ( rc = image_set_data ( image, data, len ) ) != 0 )
|
||||
goto err_set_data;
|
||||
|
||||
/* Register image */
|
||||
if ( ( rc = register_image ( image ) ) != 0 )
|
||||
goto err_register;
|
||||
|
||||
/* Drop local reference to image */
|
||||
image_put ( image );
|
||||
|
||||
return image;
|
||||
|
||||
err_register:
|
||||
err_set_data:
|
||||
err_set_name:
|
||||
image_put ( image );
|
||||
err_alloc_image:
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -81,9 +81,14 @@ struct interface null_intf = INTF_INIT ( null_intf_desc );
|
|||
* interface is updated to point to the new destination interface.
|
||||
*/
|
||||
void intf_plug ( struct interface *intf, struct interface *dest ) {
|
||||
|
||||
if ( intf == &null_intf )
|
||||
return;
|
||||
|
||||
DBGC ( INTF_COL ( intf ),
|
||||
"INTF " INTF_INTF_FMT " replug to " INTF_FMT "\n",
|
||||
INTF_INTF_DBG ( intf, intf->dest ), INTF_DBG ( dest ) );
|
||||
|
||||
intf_get ( dest );
|
||||
intf_put ( intf->dest );
|
||||
intf->dest = dest;
|
||||
|
@ -385,6 +390,23 @@ void intfs_restart ( int rc, ... ) {
|
|||
va_end ( intfs );
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a filter interface
|
||||
*
|
||||
* @v intf Object interface
|
||||
* @v upper Upper end of filter
|
||||
* @v lower Lower end of filter
|
||||
*/
|
||||
void intf_insert ( struct interface *intf, struct interface *upper,
|
||||
struct interface *lower ) {
|
||||
struct interface *dest = intf->dest;
|
||||
|
||||
intf_get ( dest );
|
||||
intf_plug_plug ( intf, upper );
|
||||
intf_plug_plug ( lower, dest );
|
||||
intf_put ( dest );
|
||||
}
|
||||
|
||||
/**
|
||||
* Poke an object interface
|
||||
*
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue