Compare commits

..

1 Commits
ena ... snppad

Author SHA1 Message Date
8c7e2d6068 [snp] Pad transmit buffer length to work around buggy vendor drivers
The Mellanox/Nvidia UEFI SNP driver is built from the same codebase as
the iPXE driver, and appears to contain the bug that was fixed in
commit c11734e ("[golan] Use ETH_HLEN for inline header size").  This
results in identical failures when using the SNP interface (via e.g.
snponly.efi) to drive a Mellanox card while EAPoL is enabled.

Work around the underlying UEFI SNP driver bug by padding transmit I/O
buffers to the minimum Ethernet frame length before passing them to
the underlying SNP driver's Transmit() function.

This padding is not technically necessary, since almost all modern
hardware will insert transmit padding as necessary (and where the
hardware does not support doing so, the underlying SNP driver is
responsible for adding any necessary padding).  However, it is
guaranteed to be harmless (other than a miniscule performance impact):
the Ethernet specification requires zero padding up to the minimum
frame length for packets that are transmitted onto the wire, and so
the receiver will see the same packet whether or not we manually
insert this padding in software.

The additional padding causes the underlying Mellanox SNP driver to
avoid its faulty code path, since it will never be asked to transmit a
very short packet.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-03-18 15:36:15 +00:00
229 changed files with 5380 additions and 11840 deletions

View File

@ -1,167 +0,0 @@
#!/usr/bin/env python3
import argparse
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import date
import io
import subprocess
import tarfile
from uuid import uuid4
from google.cloud import compute
from google.cloud import exceptions
from google.cloud import storage
IPXE_STORAGE_PREFIX = 'ipxe-upload-temp-'
FEATURE_GVNIC = compute.GuestOsFeature(type_="GVNIC")
FEATURE_IDPF = compute.GuestOsFeature(type_="IDPF")
FEATURE_UEFI = compute.GuestOsFeature(type_="UEFI_COMPATIBLE")
POLICY_PUBLIC = compute.Policy(bindings=[{
"role": "roles/compute.imageUser",
"members": ["allAuthenticatedUsers"],
}])
def delete_temp_bucket(bucket):
"""Remove temporary bucket"""
assert bucket.name.startswith(IPXE_STORAGE_PREFIX)
for blob in bucket.list_blobs(prefix=IPXE_STORAGE_PREFIX):
assert blob.name.startswith(IPXE_STORAGE_PREFIX)
blob.delete()
if not list(bucket.list_blobs()):
bucket.delete()
def create_temp_bucket(location):
"""Create temporary bucket (and remove any stale temporary buckets)"""
client = storage.Client()
for bucket in client.list_buckets(prefix=IPXE_STORAGE_PREFIX):
delete_temp_bucket(bucket)
name = '%s%s' % (IPXE_STORAGE_PREFIX, uuid4())
return client.create_bucket(name, location=location)
def create_tarball(image):
"""Create raw disk image tarball"""
tarball = io.BytesIO()
with tarfile.open(fileobj=tarball, mode='w:gz',
format=tarfile.GNU_FORMAT) as tar:
tar.add(image, arcname='disk.raw')
tarball.seek(0)
return tarball
def upload_blob(bucket, image):
"""Upload raw disk image blob"""
blob = bucket.blob('%s%s.tar.gz' % (IPXE_STORAGE_PREFIX, uuid4()))
tarball = create_tarball(image)
blob.upload_from_file(tarball)
return blob
def detect_uefi(image):
"""Identify UEFI CPU architecture(s)"""
mdir = subprocess.run(['mdir', '-b', '-i', image, '::/EFI/BOOT'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
check=False)
mapping = {
b'BOOTX64.EFI': 'x86_64',
b'BOOTAA64.EFI': 'arm64',
}
uefi = [
arch
for filename, arch in mapping.items()
if filename in mdir.stdout
]
return uefi
def image_architecture(uefi):
"""Get image architecture"""
return uefi[0] if len(uefi) == 1 else None if uefi else 'x86_64'
def image_features(uefi):
"""Get image feature list"""
features = [FEATURE_GVNIC, FEATURE_IDPF]
if uefi:
features.append(FEATURE_UEFI)
return features
def image_name(base, uefi):
"""Calculate image name or family name"""
suffix = ('-uefi-%s' % uefi[0].replace('_', '-') if len(uefi) == 1 else
'-uefi-multi' if uefi else '')
return '%s%s' % (base, suffix)
def create_image(project, basename, basefamily, overwrite, public, bucket,
image):
"""Create image"""
client = compute.ImagesClient()
uefi = detect_uefi(image)
architecture = image_architecture(uefi)
features = image_features(uefi)
name = image_name(basename, uefi)
family = image_name(basefamily, uefi)
if overwrite:
try:
client.delete(project=project, image=name).result()
except exceptions.NotFound:
pass
blob = upload_blob(bucket, image)
disk = compute.RawDisk(source=blob.public_url)
image = compute.Image(name=name, family=family, architecture=architecture,
guest_os_features=features, raw_disk=disk)
client.insert(project=project, image_resource=image).result()
if public:
request = compute.GlobalSetPolicyRequest(policy=POLICY_PUBLIC)
client.set_iam_policy(project=project, resource=name,
global_set_policy_request_resource=request)
image = client.get(project=project, image=name)
return image
# Parse command-line arguments
#
parser = argparse.ArgumentParser(description="Import Google Cloud image")
parser.add_argument('--name', '-n',
help="Base image name")
parser.add_argument('--family', '-f',
help="Base family name")
parser.add_argument('--public', '-p', action='store_true',
help="Make image public")
parser.add_argument('--overwrite', action='store_true',
help="Overwrite any existing image with same name")
parser.add_argument('--project', '-j', default="ipxe-images",
help="Google Cloud project")
parser.add_argument('--location', '-l',
help="Google Cloud Storage initial location")
parser.add_argument('image', nargs='+', help="iPXE disk image")
args = parser.parse_args()
# Use default family name if none specified
if not args.family:
args.family = 'ipxe'
# Use default name if none specified
if not args.name:
args.name = '%s-%s' % (args.family, date.today().strftime('%Y%m%d'))
# Create temporary upload bucket
bucket = create_temp_bucket(args.location)
# Use one thread per image to maximise parallelism
with ThreadPoolExecutor(max_workers=len(args.image)) as executor:
futures = {executor.submit(create_image,
project=args.project,
basename=args.name,
basefamily=args.family,
overwrite=args.overwrite,
public=args.public,
bucket=bucket,
image=image): image
for image in args.image}
results = {futures[future]: future.result()
for future in as_completed(futures)}
# Delete temporary upload bucket
delete_temp_bucket(bucket)
# Show created images
for image in args.image:
result = results[image]
print("%s (%s) %s" % (result.name, result.family, result.status))

View File

@ -1,146 +0,0 @@
#!/usr/bin/env python3
import argparse
import textwrap
import time
from uuid import uuid4
from google.cloud import compute
IPXE_LOG_PREFIX = 'ipxe-log-temp-'
IPXE_LOG_MAGIC = 'iPXE LOG'
IPXE_LOG_END = '----- END OF iPXE LOG -----'
def get_log_disk(instances, project, zone, name):
"""Get log disk source URL"""
instance = instances.get(project=project, zone=zone, instance=name)
disk = next(x for x in instance.disks if x.boot)
return disk.source
def delete_temp_snapshot(snapshots, project, name):
"""Delete temporary snapshot"""
assert name.startswith(IPXE_LOG_PREFIX)
snapshots.delete(project=project, snapshot=name)
def delete_temp_snapshots(snapshots, project):
"""Delete all old temporary snapshots"""
filter = "name eq %s.+" % IPXE_LOG_PREFIX
request = compute.ListSnapshotsRequest(project=project, filter=filter)
for snapshot in snapshots.list(request=request):
delete_temp_snapshot(snapshots, project, snapshot.name)
def create_temp_snapshot(snapshots, project, source):
"""Create temporary snapshot"""
name = '%s%s' % (IPXE_LOG_PREFIX, uuid4())
snapshot = compute.Snapshot(name=name, source_disk=source)
snapshots.insert(project=project, snapshot_resource=snapshot).result()
return name
def delete_temp_instance(instances, project, zone, name):
"""Delete log dumper temporary instance"""
assert name.startswith(IPXE_LOG_PREFIX)
instances.delete(project=project, zone=zone, instance=name)
def delete_temp_instances(instances, project, zone):
"""Delete all old log dumper temporary instances"""
filter = "name eq %s.+" % IPXE_LOG_PREFIX
request = compute.ListInstancesRequest(project=project, zone=zone,
filter=filter)
for instance in instances.list(request=request):
delete_temp_instance(instances, project, zone, instance.name)
def create_temp_instance(instances, project, zone, family, image, machine,
snapshot):
"""Create log dumper temporary instance"""
image = "projects/%s/global/images/family/%s" % (family, image)
machine_type = "zones/%s/machineTypes/%s" % (zone, machine)
logsource = "global/snapshots/%s" % snapshot
bootparams = compute.AttachedDiskInitializeParams(source_image=image)
bootdisk = compute.AttachedDisk(boot=True, auto_delete=True,
initialize_params=bootparams)
logparams = compute.AttachedDiskInitializeParams(source_snapshot=logsource)
logdisk = compute.AttachedDisk(boot=False, auto_delete=True,
initialize_params=logparams,
device_name="ipxelog")
nic = compute.NetworkInterface()
name = '%s%s' % (IPXE_LOG_PREFIX, uuid4())
script = textwrap.dedent(f"""
#!/bin/sh
tr -d '\\000' < /dev/disk/by-id/google-ipxelog-part3 > /dev/ttyS3
echo "{IPXE_LOG_END}" > /dev/ttyS3
""").strip()
items = compute.Items(key="startup-script", value=script)
metadata = compute.Metadata(items=[items])
instance = compute.Instance(name=name, machine_type=machine_type,
network_interfaces=[nic], metadata=metadata,
disks=[bootdisk, logdisk])
instances.insert(project=project, zone=zone,
instance_resource=instance).result()
return name
def get_log_output(instances, project, zone, name):
"""Get iPXE log output"""
request = compute.GetSerialPortOutputInstanceRequest(project=project,
zone=zone, port=4,
instance=name)
while True:
log = instances.get_serial_port_output(request=request).contents.strip()
if log.endswith(IPXE_LOG_END):
if log.startswith(IPXE_LOG_MAGIC):
return log[len(IPXE_LOG_MAGIC):-len(IPXE_LOG_END)]
else:
return log[:-len(IPXE_LOG_END)]
time.sleep(1)
# Parse command-line arguments
#
parser = argparse.ArgumentParser(description="Import Google Cloud image")
parser.add_argument('--project', '-j', default="ipxe-images",
help="Google Cloud project")
parser.add_argument('--zone', '-z', required=True,
help="Google Cloud zone")
parser.add_argument('--family', '-f', default="debian-cloud",
help="Helper OS image family")
parser.add_argument('--image', '-i', default="debian-12",
help="Helper OS image")
parser.add_argument('--machine', '-m', default="e2-micro",
help="Helper machine type")
parser.add_argument('instance', help="Instance name")
args = parser.parse_args()
# Construct client objects
#
instances = compute.InstancesClient()
snapshots = compute.SnapshotsClient()
# Clean up old temporary objects
#
delete_temp_instances(instances, project=args.project, zone=args.zone)
delete_temp_snapshots(snapshots, project=args.project)
# Create log disk snapshot
#
logdisk = get_log_disk(instances, project=args.project, zone=args.zone,
name=args.instance)
logsnap = create_temp_snapshot(snapshots, project=args.project, source=logdisk)
# Create log dumper instance
#
dumper = create_temp_instance(instances, project=args.project, zone=args.zone,
family=args.family, image=args.image,
machine=args.machine, snapshot=logsnap)
# Wait for log output
#
output = get_log_output(instances, project=args.project, zone=args.zone,
name=dumper)
# Print log output
#
print(output)
# Clean up
#
delete_temp_instance(instances, project=args.project, zone=args.zone,
name=dumper)
delete_temp_snapshot(snapshots, project=args.project, name=logsnap)

View File

@ -1,80 +0,0 @@
#!/usr/bin/env python3
"""Detach CMS encrypted data.
Detach encrypted data from a CMS envelopedData or authEnvelopedData
message into a separate file.
"""
import argparse
import asn1
# Parse command-line arguments
#
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("-d", "--data", metavar="FILE",
help="Write detached data (without envelope) to FILE")
parser.add_argument("-e", "--envelope", metavar="FILE",
help="Write envelope (without data) to FILE")
parser.add_argument("-o", "--overwrite", action="store_true",
help="Overwrite output files")
parser.add_argument("file", help="Input envelope file")
args = parser.parse_args()
if args.data is None and args.envelope is None:
parser.error("at least one of --data and --envelope is required")
outmode = "wb" if args.overwrite else "xb"
# Create decoder
#
decoder = asn1.Decoder()
with open(args.file, mode="rb") as fh:
decoder.start(fh.read())
# Create encoder
#
encoder = asn1.Encoder()
encoder.start()
# Detach encrypted data
#
data = None
datastack = [
asn1.Numbers.Sequence, 0, asn1.Numbers.Sequence, asn1.Numbers.Sequence
]
stack = []
while stack or not decoder.eof():
if decoder.eof():
encoder.leave()
decoder.leave()
stack.pop()
else:
tag = decoder.peek()
if tag.typ == asn1.Types.Constructed:
encoder.enter(nr=tag.nr, cls=tag.cls)
decoder.enter()
stack.append(tag.nr)
else:
(tag, value) = decoder.read()
if stack == datastack and tag.nr == 0:
data = value
else:
encoder.write(value, nr=tag.nr, cls=tag.cls)
envelope = encoder.output()
if data is None:
parser.error("Input file does not contain any encrypted data")
# Write envelope (without data), if applicable
#
if args.envelope:
with open(args.envelope, mode=outmode) as fh:
fh.write(envelope)
# Write data (without envelope), if applicable
#
if args.data:
with open(args.data, mode=outmode) as fh:
fh.write(data)

View File

@ -0,0 +1,62 @@
ROM-o-matic web interface for building iPXE ROMs
------------------------------------------------
This web application generates iPXE images and sends them to a web
browser.
Available as part of the iPXE source code distribution, which can be
downlaoded from http://etherboot.org/
Author: Marty Connor <mdc@etherboot.org>
License: GPLv2
Support: http://etherboot.org/mailman/listinfo/ipxe
Please send support questions to the iPXE mailing list
System Requirements
-------------------
- Apache web server
- PHP 4+
- Tools required to build iPXE installed on the server
- gcc, mtools, syslinux, perl, etc.
Setup
-----
As distributed, it is expected that the rom-o-matic source code
directory is in the contrib directory of a iPXE source distribution.
The easiest way to do this is to simply put a iPXE source distribution
in a web server accessible directory.
If this is not the case, you will need to either edit the file
"globals.php"
or create a file called
"local-config.php"
containing the following lines:
<?php
$src_dir = "../../src";
?>
Then change the line beginning "$src_dir = " to the path of your iPXE
source code tree.
To make build times shorter, before you run rom-o-matic for the first time
you should cd to the ipxe "src" directory and enter the following
commands:
$ make
$ make bin/NIC
This will pro-compile most object files and will make your rom-o-matic
builds much faster.
Running rom-o-matic from a web browser
--------------------------------------
Enter a URL like:
http://example.com/ipxe-1.x.x/contrib/rom-o-matic

View File

@ -0,0 +1,62 @@
<?php
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
?>
<hr>
<h4>
Resources:
</h4>
<ul>
<li>
Source code for iPXE images is available at
<a href="http://www.ipxe.org/download" target="_blank">
http://www.ipxe.org/download</a>
<br><br>
</li>
<li>
For general information about using iPXE, please visit the
<a href="http://www.ipxe.org/" target="_blank">
iPXE Project Home Page</a>
<br><br>
</li>
<li>
For Email-based support for iPXE please join
<a href="http://www.ipxe.org/contact" target="_blank">
iPXE Project mailing lists.</a>
<br><br>
</li>
<li>
For real-time online iPXE support via IRC please visit the
<a href="irc://irc.freenode.net/%23ipxe"> #ipxe channel
of irc.freenode.net</a>.
<br><br>
</li>
</ul>
<hr>
<font size="-1">
<br>
Please email <a href="mailto:<?php echo "${webmaster_email}" ?>"><?php echo "${webmaster_email}"?></a>
with questions or comments about this website.
</font>
<br><br>
<hr>
</body>
</html>

View File

@ -0,0 +1,311 @@
<?php // -*- Mode: PHP; -*-
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Get utility functions and set globals
require_once "utils.php";
// Make sure at least $A (action) was supplied
if ( ! isset ( $_POST['A'] ) ) {
// Present user with form to customize build options
require_once "customize-flags.php";
exit ();
// If user chose "Customize" option on form
} else if ( $_POST['A'] == "Customize" ) {
// Present user with form to customize build options
require_once "customize-flags.php";
exit ();
// The following conditional includes all other cases except "Get Image"
// particularly the explicit ($A == "Start Over") case
} else if ( $_POST['A'] != "Get Image" ) {
// Note that this method of redirections discards all the
// configuration flags, which is intentional in this case.
$dest = curDirURL ();
header ( "Location: $dest" );
// This next "echo" should normally not be seen, because
// the "header" statement above should cause immediate
// redirection but just in case...
echo "Try this link: <a href=\"$dest\">$dest</a>";
exit ();
}
// OK, we're going to try to use whatever options have been set
// to build an image.
// Make sure at least $nic was supplied
if ( ! isset ( $_POST['nic'] ) ) {
die ( "No NIC supplied!" );
}
if ( isset ( $nics[$_POST['nic']] ) ) {
$nic = $nics[$_POST['nic']];
} else {
die ( "Invalid NIC \"${_POST['nic']}\" supplied!" );
}
// Fetch flags
$flags = get_flags ();
// Get requested format
$ofmt = isset ( $_POST['ofmt'] ) ? $_POST['ofmt'] : "";
$fmt_extension = isset ( $ofmts[$ofmt] ) ? $ofmts[$ofmt] : 'dsk';
// Handle some special cases
$pci_vendor_code = "";
$pci_device_code = "";
if ( $nic == 'undionly' && $fmt_extension == "pxe" ) {
// undionly.pxe can't work because it unloads the PXE stack
// that it needs to communicate with, so we set the extension
// to .kpxe, which has a chance of working. The extension
// .kkpxe is another option.
$fmt_extension = "kpxe";
} else if ( $fmt_extension == "rom" ) {
if ( ! isset ( $_POST['pci_vendor_code'] )
|| ! isset ( $_POST['pci_device_code'] ) ) {
die ( "rom output format selected but PCI code(s) missing!" );
}
$pci_vendor_code = $_POST['pci_vendor_code'];
$pci_device_code = $_POST['pci_device_code'];
if ( $pci_vendor_code == ""
|| $pci_device_code == "" ) {
die ( "rom output format selected but PCI code(s) missing!" );
}
// Try to be forgiving of 0xAAAA format
if ( strtolower ( substr ( $pci_vendor_code, 0, 2 ) ) == "0x"
&& strlen ( $pci_vendor_code ) == 6 ) {
$pci_vendor_code = substr ( $pci_vendor_code, 2, 4 );
}
if ( strtolower ( substr ( $pci_device_code, 0, 2 ) ) == "0x"
&& strlen ( $pci_device_code ) == 6 ) {
$pci_device_code = substr ( $pci_device_code, 2, 4 );
}
// concatenate the pci codes to get the $nic part of the
// Make target
$pci_codes = strtolower ( $pci_vendor_code . $pci_device_code );
$nic = $pci_codes;
if ( ! isset ( $roms[$pci_codes] ) ) {
die ( "Sorry, no network driver supports PCI codes<br>"
. "${_POST['pci_vendor_code']}:"
. "${_POST['pci_device_code']}" );
}
} else if ( $fmt_extension != "rom"
&& ( $pci_vendor_code != "" || $pci_device_code != "" ) ) {
die ( "'$fmt_extension' format was selected but PCI IDs were"
. " also entered.<br>Did you mean to select 'rom' output format"
. " instead?" );
}
/**
* remove temporary build directory
*
* @return bool true if removal is successful, false otherwise
*/
function rm_build_dir ()
{
global $build_dir;
global $keep_build_dir;
if ( $keep_build_dir !== true ) {
rm_file_or_dir ( $build_dir );
}
}
// Arrange for the build directory to always be removed on exit.
$build_dir = "";
$keep_build_dir = false;
register_shutdown_function ( 'rm_build_dir' );
// Make temporary copy of src directory
$build_dir = mktempcopy ( "$src_dir", "/tmp", "MDCROM" );
$config_dir = $build_dir . "/config";
// Write config files with supplied flags
write_ipxe_config_files ( $config_dir, $flags );
// Handle a possible embedded script
$emb_script_cmd = "";
$embedded_script = isset ( $_POST['embedded_script'] ) ? $_POST['embedded_script'] : "";
if ( $embedded_script != "" ) {
$emb_script_path = "$build_dir" . "/script0.ipxe";
if ( substr ( $embedded_script, 0, 5 ) != "#!ipxe" ) {
$embedded_script = "#!ipxe\n" . $embedded_script;
}
// iPXE 0.9.7 doesn't like '\r\n" in the shebang...
$embedded_script = str_replace ( "\r\n", "\n", $embedded_script );
write_file_from_string ( $emb_script_path, $embedded_script );
$emb_script_cmd = "EMBEDDED_IMAGE=${emb_script_path}";
}
// Make the requested image. $status is set to 0 on success
$make_target = "bin/${nic}.${fmt_extension}";
$gitversion = exec('git describe --always --abbrev=1 --match "" 2>/dev/null');
if ($gitversion) {
$gitversion = "GITVERSION=$gitversion";
}
$make_cmd = "make -C '$build_dir' '$make_target' $gitversion $emb_script_cmd 2>&1";
exec ( $make_cmd, $maketxt, $status );
// Uncomment the following section for debugging
/**
echo "<h2>build.php:</h2>";
echo "<h3>Begin debugging output</h3>";
//echo "<h3>\$_POST variables</h3>";
//echo "<pre>"; var_dump ( $_POST ); echo "</pre>";
echo "<h3>Build options:</h3>";
echo "<strong>Build directory is:</strong> $build_dir" . "<br><br>";
echo "\$_POST['ofmt'] = " . "\"${_POST['ofmt']}\"" . "<br>";
echo "\$_POST['nic'] = " . "\"${_POST['nic']}\"" . "<br>";
echo "\$_POST['pci_vendor_code'] = " . "\"${_POST['pci_vendor_code']}\"" . "<br>";
echo "\$_POST['pci_device_code'] = " . "\"${_POST['pci_device_code']}\"" . "<br>";
echo "<h3>Flags:</h3>";
show_flags ( $flags );
if ( $embedded_script != "" ) {
echo "<h3>Embedded script:</h3>";
echo "<blockquote>"."<pre>";
echo $embedded_script;
echo "</pre>"."</blockquote>";
}
echo "<h3>Make output:</h3>";
echo "Make command: " . $make_cmd . "<br>";
echo "Build status = <? echo $status ?>" . "<br>";
echo "<blockquote>"."<pre>";
echo htmlentities ( implode ("\n", $maketxt ) );
echo "</pre>"."</blockquote>";
// Uncomment the next line if you want to keep the
// build directory around for inspection after building.
$keep_build_dir = true;
die ( "<h3>End debugging output</h3>" );
**/ // End debugging section
// Send ROM to browser (with extreme prejudice)
if ( $status == 0 ) {
$fp = fopen("${build_dir}/${make_target}", "rb" );
if ( $fp > 0 ) {
$len = filesize ( "${build_dir}/${make_target}" );
if ( $len > 0 ) {
$buf = fread ( $fp, $len );
fclose ( $fp );
// Delete build directory as soon as it is not needed
rm_build_dir ();
$output_filename = preg_replace('/[^a-z0-9\+\.\-]/i', '', "ipxe-${version}-${nic}.${fmt_extension}");
// Try to force IE to handle downloading right.
Header ( "Cache-control: private");
Header ( "Content-Type: application/x-octet-stream; " .
"name=$output_filename");
Header ( "Content-Disposition: attachment; " .
"Filename=$output_filename");
Header ( "Content-Location: $output_filename");
Header ( "Content-Length: $len");
echo $buf;
exit ();
}
}
}
/*
* If we reach this point, the build has failed, and we provide
* debugging information for a potential bug report
*
*/
// Remove build directory
rm_build_dir ();
// Announce failure if $status from make was non-zero
echo "<h2>Build failed. Status = " . $status . "</h2>";
echo "<h2>build.php:</h2>";
echo "<h3>Build options:</h3>";
echo "<strong>Build directory is:</strong> $build_dir" . "<br><br>";
echo "\$_POST['ofmt'] = " . "\"${_POST['ofmt']}\"" . "<br>";
echo "\$_POST['nic'] = " . "\"${_POST['nic']}\"" . "<br>";
echo "\$_POST['pci_vendor_code'] = " . "\"${_POST['pci_vendor_code']}\"" . "<br>";
echo "\$_POST['pci_device_code'] = " . "\"${_POST['pci_device_code']}\"" . "<br>";
echo "<h3>Flags:</h3>";
show_flags ( $flags );
if ( $embedded_script != "" ) {
echo "<h3>Embedded script:</h3>";
echo "<blockquote>"."<pre>";
echo $embedded_script;
echo "</pre>"."</blockquote>";
}
echo "<h3>Make output:</h3>";
echo "Make command: " . $make_cmd . "<br>";
echo "<blockquote>"."<pre>";
echo htmlentities ( implode ("\n", $maketxt ) );
echo "</pre>"."</blockquote>";
echo "Please let us know that this happened, and paste the above output into your email message.<br>";
include_once $bottom_inc;
// For emacs:
// Local variables:
// c-basic-offset: 4
// c-indent-level: 4
// tab-width: 4
// End:
?>

View File

@ -0,0 +1,69 @@
<?php // -*- Mode: PHP; -*-
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Get utility functions and set globals
require_once "utils.php";
// Prepare settable compile options for presentation to user
$flags = default_flags ();
$build = "<input type=\"submit\" name=\"A\" value=\"Get Image\">";
$restart = "<input type=\"submit\" name=\"A\" value=\"Start Over\">";
// Begin html output
include_once $top_inc;
?>
<form action="build.php" method=POST>
<input type="hidden" name="version" value = "<?php echo $version ?>">
<input type="hidden" name="use_flags" value="1">
<h3>
Make changes below and press <?php echo $build ?> to create an image, <br>
Or press <?php echo $restart ?> to return to the main page.
</h3>
<hr>
<ul>
<?php require ( "directions.php" ); ?>
</ul>
<hr>
<?php echo_flags( $flags ); ?>
<hr>
<h3>Embedded Script:</h3>
<?php echo textarea ( "embedded_script", "", "10", "50" ); ?>
<br><br>
<hr>
<center><table width="35%"><tr>
<td align="left"> <?php echo $build; ?> </td>
<td align="right"> <?php echo $restart ?></td>
</tr></table></center>
</form>
<?php include_once $bottom_inc; ?>
<?
// For emacs:
//
// Local variables:
// c-basic-offset: 4
// c-indent-level: 4
// tab-width: 4
// End:
?>

View File

@ -0,0 +1,63 @@
<?php
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
?>
<li>
Choose an output format: <?php echo keys_menubox ( "ofmt", $ofmts,
isset ( $_POST['ofmt'] ) ? $_POST['ofmt'] : "") ?>
<br><br>
</li>
<li>
Choose a NIC type: <?php echo keys_menubox ( "nic", $nics,
isset ( $_POST['nic'] ) ? $_POST['nic'] : "" ) ?>
<br><br>
</li>
<li>
<strong>( optional &mdash; for binary ROM image format only )</strong> <br><br>
If you choose <em>Binary ROM image</em> as your output format, you must<br>
enter <strong>4 hex digits</strong> below for
<em>PCI VENDOR CODE</em> and <em>PCI DEVICE CODE</em> <br>
that match the NIC device for which you are making this image.<br><br>
Information on how to determine NIC PCI IDs may be found
<a href="http://www.ipxe.org/howto/romburning"
target="_blank">here</a>.
<br><br>
PCI VENDOR CODE: <?php echo textbox ( "pci_vendor_code",
isset ( $_POST['pci_vendor_code'] ) ? $_POST['pci_vendor_code']
: "", 6 ); ?>
&nbsp;&nbsp;
PCI DEVICE CODE: <?php echo textbox ( "pci_device_code",
isset ( $_POST['pci_device_code'] ) ? $_POST['pci_device_code']
: "", 6 ); ?>
<h4>Please note for ROM images:</h4>
<ul>
<li>
If you enter PCI IDs, we will attempt to determine the correct<br>
driver to support them, and will ignore any NIC type entered
above.<br><br>
</li>
<li>
iPXE does not support all possible PCI IDs for supported
NICs.
<br><br>
</li>
</ul>
</li>

View File

@ -0,0 +1 @@
Automatic booting

View File

@ -0,0 +1 @@
Tenths of a second for which the shell banner should appear

View File

@ -0,0 +1,3 @@
Serial Console I/O port address. Common addresses are:<br>
COM1 => 0x3f8, COM2 => 0x2f8, COM3 => 0x3e8, COM4 => 0x2e8

View File

@ -0,0 +1 @@
Serial Console Data bits

View File

@ -0,0 +1 @@
Serial Console Parity: 0=None, 1=Odd, 2=Even

View File

@ -0,0 +1 @@
Keep settings from a previous user of the serial port

View File

@ -0,0 +1 @@
Serial Console Baud rate

View File

@ -0,0 +1 @@
Serial Console Stop bits

View File

@ -0,0 +1 @@
Option configuration console

View File

@ -0,0 +1 @@
Enable Default BIOS console

View File

@ -0,0 +1 @@
Enable Serial port console

View File

@ -0,0 +1 @@
Wireless WEP encryption support

View File

@ -0,0 +1 @@
Wireless WPA encryption support

View File

@ -0,0 +1 @@
Wireless WPA2 encryption support

View File

@ -0,0 +1 @@
DHCP management commands

View File

@ -0,0 +1 @@
DNS resolver

View File

@ -0,0 +1 @@
File Transfer Protocol

View File

@ -0,0 +1 @@
Hypertext Transfer Protocol

View File

@ -0,0 +1 @@
Trivial File Transfer Protocol

View File

@ -0,0 +1 @@
Interface management commands

View File

@ -0,0 +1 @@
Linux bzImage image support

View File

@ -0,0 +1 @@
Image management commands

View File

@ -0,0 +1 @@
ELF image support

View File

@ -0,0 +1 @@
MultiBoot image support

View File

@ -0,0 +1 @@
NBI image support

View File

@ -0,0 +1 @@
PXE image support

View File

@ -0,0 +1 @@
iPXE script image support

View File

@ -0,0 +1 @@
Wireless interface management commands

View File

@ -0,0 +1 @@
NMB resolver

View File

@ -0,0 +1 @@
Non-volatile option storage commands

View File

@ -0,0 +1 @@
Routing table management commands

View File

@ -0,0 +1 @@
SAN boot commands

View File

@ -0,0 +1,531 @@
<?php // -*- Mode: PHP; -*-
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
$ofmts = array
( "Floppy bootable image (.dsk)" => "dsk",
"SYSLINUX-based bootable floppy image (.sdsk)" => "sdsk",
"ISO bootable image (.iso)" => "iso",
"ISO bootable image with legacy floppy emulation (.liso)" => "liso",
"Linux kernel (SYSLINUX/GRUB/LILO) loadable image (.lkrn)" => "lkrn",
"USB Keychain disk image (.usb)" => "usb",
"ROM binary (flashable) image (.rom)" => "rom",
"ROM binary (flashable) for problem PMM BIOSES (.hrom)" => "hrom",
"PXE bootstrap loader image [Unload PXE stack] (.pxe)" => "pxe",
"PXE bootstrap loader keep [Keep PXE stack method 1] (.kpxe)" => "kpxe",
"PXE bootstrap loader keep [Keep PXE stack method 2] (.kkpxe)" => "kkpxe",
);
$flag_table = array (
// Begin General Options:
"HDR_MISC_OPTIONS"
=> array (
"flag" => "HDR_MISC_OPTIONS",
"hide_from_user" => "yes", // Hide even the header
"type" => "header",
"label" => "Miscellaneous Options"
),
"PRODUCT_NAME"
=> array (
"flag" => "PRODUCT_NAME",
"hide_from_user" => "yes",
"type" => "string",
"value" => "",
"cfgsec" => "general"
),
"PRODUCT_SHORT_NAME"
=> array (
"flag" => "PRODUCT_SHORT_NAME",
"hide_from_user" => "yes",
"type" => "string",
"value" => "iPXE",
"cfgsec" => "general"
),
// End General Options:
// Begin Console Options:
"HDR_CONSOLE_OPTIONS"
=> array (
"flag" => "HDR_CONSOLE_OPTIONS",
"type" => "header",
"label" => "Console Options"
),
"CONSOLE_PCBIOS"
=> array (
"flag" => "CONSOLE_PCBIOS",
"type" => "on/off",
"value" => "on",
"cfgsec" => "console"
),
"CONSOLE_SERIAL"
=> array (
"flag" => "CONSOLE_SERIAL",
"type" => "on/off",
"value" => "off",
"cfgsec" => "console"
),
"BANNER_TIMEOUT"
=> array (
"flag" => "BANNER_TIMEOUT",
"type" => "integer",
"value" => "20",
"cfgsec" => "general"
),
"KEYBOARD_MAP"
=> array (
"flag" => "KEYBOARD_MAP",
"type" => "choice",
"options" => array("al","az","bg","by","cf","cz","de","dk","es","et","fi","fr",
"gr","hu","il","it","lt","mk","mt","nl","no","pl","pt","ro","ru","sg","sr",
"th","ua","uk","us","wo"),
"value" => "us",
"cfgsec" => "console"
),
"LOG_LEVEL"
=> array (
"flag" => "LOG_LEVEL",
"type" => "choice",
"options" => array("LOG_NONE","LOG_EMERG","LOG_ALERT","LOG_CRIT","LOG_ERR",
"LOG_WARNING","LOG_NOTICE","LOG_INFO","LOG_DEBUG","LOG_ALL"),
"value" => "LOG_NONE",
"cfgsec" => "console"
),
// End Console Options
// Begin Network Protocol Options:
"HDR_NETWORK_PROTOCOL_OPTIONS"
=> array (
"flag" => "HDR_NETWORK_PROTOCOL_OPTIONS",
"hide_from_user" => "yes", // Hide even the header
"type" => "header",
"label" => "Network Protocol Options"
),
"NET_PROTO_IPV4"
=> array (
"flag" => "NET_PROTO_IPV4",
"type" => "on/off",
"value" => "on",
"hide_from_user" => "yes",
"cfgsec" => "general"
),
// End Network Protocol Options
// Begin Serial Port configuration
"HDR_SERIAL_PORT_OPTIONS"
=> array (
"flag" => "HDR_SERIAL_PORT_OPTIONS",
"type" => "header",
"label" => "Serial Port Options"
),
"COMCONSOLE"
=> array (
"flag" => "COMCONSOLE",
"type" => "integer-hex", // e.g. 0x378
"value" => "0x3F8",
"cfgsec" => "serial"
),
"COMPRESERVE"
=> array (
"flag" => "COMPRESERVE",
"type" => "on/off",
"value" => "off",
"cfgsec" => "serial"
),
"COMSPEED"
=> array (
"flag" => "COMSPEED",
"type" => "integer",
"value" => "115200",
"cfgsec" => "serial"
),
"COMDATA"
=> array (
"flag" => "COMDATA",
"type" => "integer",
"value" => "8",
"cfgsec" => "serial"
),
"COMPARITY"
=> array (
"flag" => "COMPARITY",
"type" => "integer",
"value" => "0",
"cfgsec" => "serial"
),
"COMSTOP"
=> array (
"flag" => "COMSTOP",
"type" => "integer",
"value" => "1",
"cfgsec" => "serial"
),
// End Serial Options
// Begin Download Protocols
"HDR_DOWNLOAD_PROTOCOLS"
=> array (
"flag" => "HDR_DOWNLOAD_PROTOCOLS",
"type" => "header",
"label" => "Download Protocols"
),
"DOWNLOAD_PROTO_TFTP"
=> array (
"flag" => "DOWNLOAD_PROTO_TFTP",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"DOWNLOAD_PROTO_HTTP"
=> array (
"flag" => "DOWNLOAD_PROTO_HTTP",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"DOWNLOAD_PROTO_HTTPS"
=> array (
"flag" => "DOWNLOAD_PROTO_HTTPS",
"type" => "on/off",
"value" => "off",
"cfgsec" => "general"
),
"DOWNLOAD_PROTO_FTP"
=> array (
"flag" => "DOWNLOAD_PROTO_FTP",
"type" => "on/off",
"value" => "off",
"cfgsec" => "general"
),
// End Download Protocols
// Begin SAN boot protocols
"HDR_SANBOOT_PROTOCOLS"
=> array (
"flag" => "HDR_SANBOOT_PROTOCOLS",
"type" => "header",
"label" => "SAN Boot Protocols"
),
"SANBOOT_PROTO_ISCSI"
=> array (
"flag" => "SANBOOT_PROTO_ISCSI",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"SANBOOT_PROTO_AOE"
=> array (
"flag" => "SANBOOT_PROTO_AOE",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
// End SAN boot protocols
// Begin Name resolution modules
"HDR_NAME_RESOLUTION_MODULES"
=> array (
"flag" => "HDR_NAME_RESOLUTION_MODULES",
"type" => "header",
"label" => "Name Resolution Modules"
),
"DNS_RESOLVER"
=> array (
"flag" => "DNS_RESOLVER",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"NMB_RESOLVER"
=> array (
"flag" => "NMB_RESOLVER",
"type" => "on/off",
"value" => "off",
"hide_from_user" => "yes",
"cfgsec" => "general"
),
// End Name resolution modules
// Begin Image types
"HDR_IMAGE_TYPES"
=> array (
"flag" => "HDR_IMAGE_TYPES",
"type" => "header",
"label" => "Image Types",
),
"IMAGE_ELF"
=> array (
"flag" => "IMAGE_ELF",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IMAGE_NBI"
=> array (
"flag" => "IMAGE_NBI",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IMAGE_MULTIBOOT"
=> array (
"flag" => "IMAGE_MULTIBOOT",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IMAGE_PXE"
=> array (
"flag" => "IMAGE_PXE",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IMAGE_SCRIPT"
=> array (
"flag" => "IMAGE_SCRIPT",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IMAGE_BZIMAGE"
=> array (
"flag" => "IMAGE_BZIMAGE",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IMAGE_COMBOOT"
=> array (
"flag" => "IMAGE_COMBOOT",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
// End Image types
// Begin Command-line commands to include
"HDR_COMMAND_LINE_OPTIONS"
=> array (
"flag" => "HDR_COMMAND_LINE_OPTIONS",
"type" => "header",
"label" => "Command Line Options",
),
"AUTOBOOT_CMD"
=> array (
"flag" => "AUTOBOOT_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"NVO_CMD"
=> array (
"flag" => "NVO_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"CONFIG_CMD"
=> array (
"flag" => "CONFIG_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IFMGMT_CMD"
=> array (
"flag" => "IFMGMT_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IWMGMT_CMD"
=> array (
"flag" => "IWMGMT_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"ROUTE_CMD"
=> array (
"flag" => "ROUTE_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"IMAGE_CMD"
=> array (
"flag" => "IMAGE_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"DHCP_CMD"
=> array (
"flag" => "DHCP_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"SANBOOT_CMD"
=> array (
"flag" => "SANBOOT_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"LOGIN_CMD"
=> array (
"flag" => "LOGIN_CMD",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"TIME_CMD"
=> array (
"flag" => "TIME_CMD",
"type" => "on/off",
"value" => "off",
"cfgsec" => "general"
),
"DIGEST_CMD"
=> array (
"flag" => "DIGEST_CMD",
"type" => "on/off",
"value" => "off",
"cfgsec" => "general"
),
// End Command-line commands to include
// Begin Wireless options
"HDR_WIRELESS_OPTIONS"
=> array (
"flag" => "HDR_WIRELESS_OPTIONS",
"type" => "header",
"label" => "Wireless Interface Options",
),
"CRYPTO_80211_WEP"
=> array (
"flag" => "CRYPTO_80211_WEP",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"CRYPTO_80211_WPA"
=> array (
"flag" => "CRYPTO_80211_WPA",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
"CRYPTO_80211_WPA2"
=> array (
"flag" => "CRYPTO_80211_WPA2",
"type" => "on/off",
"value" => "on",
"cfgsec" => "general"
),
// End Wireless options
// Obscure options required to compile
"NETDEV_DISCARD_RATE"
=> array (
"flag" => "NETDEV_DISCARD_RATE",
"type" => "integer",
"value" => "0",
"cfgsec" => "general",
"hide_from_user" => true
)
// End Obscure options
);
// For emacs:
// Local variables:
// c-basic-offset: 4
// c-indent-level: 4
// tab-width: 4
// End:
?>

View File

@ -0,0 +1,51 @@
<?php // -*- Mode: PHP; -*-
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Directory containing iPXE source code tree
$src_dir = "../../src";
// Compute iPXE version based on source tree
exec ( "make -C '$src_dir' version 2>&1", $make_output, $status );
$version = ( $status == 0 && count ( $make_output ) > 1 )
? trim ( $make_output[count ( $make_output ) - 2] )
: "";
// Email address of person responsible for this website
$webmaster_email = "webmaster@example.com";
// Files that header and footer text
$top_inc = "top.php";
$bottom_inc = "bottom.php";
// Descriptive strings
$header_title = "ROM-o-matic for iPXE $version";
$html_tagline = "ROM-o-matic dynamically generates iPXE images";
$html_title = "ROM-o-matic for iPXE $version";
$description = "a dynamic iPXE image generator";
// For emacs:
// Local variables:
// c-basic-offset: 4
// c-indent-level: 4
// tab-width: 4
// End:
?>

View File

@ -0,0 +1,47 @@
<?php // -*- Mode: PHP; -*-
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Get utility functions and set globals
require_once "utils.php";
// Begin html output
include_once $top_inc;
?>
<form action="build.php" method=POST>
<input type="hidden" name="version" value = "<?php echo $version ?>">
<h3>To create an image:</h3>
<ol>
<?php require ( "directions.php" ); ?>
<li>
Generate and download an image:
<input type="submit" name="A" value="Get Image">
<br><br>
</li>
<li>
(optional) Customize image configuration options:
<input type="submit" name="A" value="Customize">
<br><br>
</li>
</ol>
</form>
<?php include_once $bottom_inc ?>

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<?php
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
?>
<html>
<head>
<link rev="made" href="mailto:<?php echo "${webmaster_email}" ?>">
<meta name="keywords" content="rom, etherboot, ipxe, open source, rom-o-matic.net">
<title><?php echo $header_title ?></title>
<meta name="description" content="<?php echo $description ?>">
</head>
<h1>
<?php echo "$html_title" ?>&nbsp;
</h1>
<hr>
<h2>
<?php echo "$html_tagline" ?>
</h2>
</form>
<hr>

View File

@ -0,0 +1,684 @@
<?php // -*- Mode: PHP; -*-
/**
* Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
* Copyright (C) 2009 Entity Cyber, Inc.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Include table of user-configurable iPXE options
require_once "flag-table.php";
// Include user-shadowable globals
require_once "globals.php";
// Allow user to shadow globals
if ( is_file ( 'local-config.php' ) ) {
include_once "local-config.php";
}
////
// General utility functions
////
/**
* Remove undesirable characters from a given string
*
* Certain characters have the potential to be used for
* malicious purposes by web-based attackers. This routine
* filters out such characters.
*
* @param string $s supplied string
*
* @return string returned string with unwanted characters
* removed
*/
function cleanstring ( $s )
{
$len = strlen ( $s );
if ( $len > 80 ) {
$s = substr ( $s, 0, 80 );
}
$s = trim ( $s );
$pos = 0;
$result = "";
while ( $pos < $len ) {
$ltr = ord ( ucfirst ( $s[$pos] ) );
if ( ( $ltr >= ord ( "A" ) ) && ( $ltr <= ord ( "Z" ) ) ||
( $ltr >= ord ( "0" ) ) && ( $ltr <= ord ( "9" ) ) ||
( $ltr == ord ( "." ) ) && ( strlen ( $result ) > 0 ) ||
( $ltr == ord ( "_" ) ) ||
( $ltr == ord ( "+" ) ) ||
( $ltr == ord ( ":" ) ) ||
( $ltr == ord ( "/" ) ) ||
( $ltr == ord ( "-" ) ) ) {
$result .= $s[$pos];
}
$pos++;
}
return $result;
}
/**
* Return URL of the currently running script, minus the filename
*
* @return string the URL of the currently running script, minus the filename
*/
function curDirURL ()
{
$dir = dirname ( $_SERVER['PHP_SELF'] );
if ( $dir == "." || $dir == "/" ) {
$dir = "";
}
$isHTTPS = ( isset ( $_SERVER["HTTPS"] ) && $_SERVER["HTTPS"] == "on" );
$port = ( isset($_SERVER["SERVER_PORT"] ) &&
( ( !$isHTTPS && $_SERVER["SERVER_PORT"] != "80" ) ||
( $isHTTPS && $_SERVER["SERVER_PORT"] != "443" ) ) );
$port = ( $port ) ? ':' . $_SERVER["SERVER_PORT"] : '';
$dest = ( $isHTTPS ? 'https://' : 'http://' ) .
$_SERVER["SERVER_NAME"] . $dir . "/";
return $dest;
}
/**
* Extract NIC families and associated ROM PCI IDs from the src/bin/NIC file.
*
* $src_dir must contain the path of the iPXE src directory for this build
*
* @return array[0] array $new_nics
* @return array[1] array $roms
*/
function parse_nic_file ()
{
global $src_dir;
$fd = fopen ( "$src_dir/bin/NIC", "r" );
if ( ! $fd ) {
die ( "Missing src/bin/NIC file. 'make bin/NIC'" );
}
$nics = array ();
$roms = array ();
$nic = "";
while ( !feof ( $fd ) ) {
$line = trim ( fgets ( $fd, 200 ) );
$first_eight_chars = substr ( $line, 0, 8 );
settype ( $first_eight_chars, "string" );
if ( strpos ( $first_eight_chars, "family" ) === 0 ) {
// get pathname of NIC driver
#list ( $dummy, $nic ) = split( "[ \t]+", $line );
list ( $dummy, $nic ) = explode("\t", $line);
settype ( $nic, "string" );
// extract filename name of driver from pathname
$nic = substr ( $nic, strrpos ( $nic, "/" ) + 1,
strlen ( $nic ) - strrpos ( $nic, "/" ) + 1 );
$nics[$nic] = $nic;
// For each ISA NIC, there can only be one ROM variant
$roms[$nic] = $nic;
}
// If the first 8 digits of the line are hex digits
// add this rom to the current nic family.
if ( ( strlen ( $first_eight_chars ) == 8 )
&& ( ctype_xdigit ( $first_eight_chars ) )
&& ( $nic != "" ) ) {
$roms[$first_eight_chars] = $nic;
}
}
fclose ( $fd );
// put most NICs in nice alpha order for menu
ksort ( $nics );
// add special cases to the top
$new_nics = array ( "all-drivers" => "ipxe",
"undionly" => "undionly",
"undi" => "undi",
);
foreach ( $nics as $key => $value ) {
// skip the undi driver
if ( $key != "undi" ) {
$new_nics[$key] = $value;
}
}
return array ( $new_nics, $roms );
}
////
// HTML form utility functions
////
/**
* Return html code to create hidden form input fields
*
* @param string $flag name of form variable to set
* @param string $value value to give form variable
*
* @return string html code for given hidden form input field
*/
function hidden ( $flag, $value )
{
$value = htmlentities ( $value );
return "<input type=\"hidden\" value=\"$value\" name=\"$flag\"></input>";
}
/**
* Return html code to create checkbox form input fields
*
* @param string $flag name of form variable to set
* @param string $value "on" means box should be checked
*
* @return string html code for given hidden form input field
*/
function checkbox ( $flag, $value )
{
return "<input type=\"checkbox\" value=\"on\" name=\"$flag\"" .
($value == "on" ? " checked>" : ">" );
}
/**
* Return html code to create text form input fields
*
* @param string $flag name of form variable to set
* @param string $value initial contents of field
* @param string $size size in characters of text box
*
* @return string html code for given text input field
*/
function textbox ( $flag, $value, $size )
{
$value = htmlentities ( $value );
return "<input type=\"text\" size=\"$size\" value=\"$value\" name=\"$flag\">";
}
/**
* Return html code to create textarea form fields
*
* @param string $flag name of form variable to set
* @param string $value initial contents of textarea
* @param string $rows height of text area in rows
* @param string $cols width of text area in columns
*
* @return string html code for given textarea input field
*/
function textarea ( $flag, $value, $rows, $cols )
{
$value = htmlentities ( $value );
return "<textarea name=\"$flag\" rows=\"$rows\" cols=\"$cols\">"
. $value . "</textarea>";
}
/**
* Return html code to create select (menu) form fields
*
* Use array of strings as menu choices
*
* @param string $flag name of form variable to set
* @param array $options array of strings representing choices
* @param string $value value of choice to select in menu
*
* @return string html code for given select (menu) input field
*/
function menubox ( $name, $options, $value )
{
$s="<select name=\"$name\">";
foreach ( $options as $ignore => $option ) {
if ( !$value ) $value = $option;
$s .= "<option" . ( $option == $value ? " selected>" : ">" ) .
htmlentities ( $option ) . "</option>";
}
return $s . "</select>";
}
/**
* Return html code to create select (menu) form fields
*
* Use indices of array of strings as menu choices rather than
* the values pointed to by the indicies.
*
* @param string $flag name of form variable to set
* @param array $options array of strings representing choices
* @param string $value value of choice to select in menu
*
* @return string html code for given select (menu) input field
*/
function keys_menubox ( $name, $options, $value )
{
$s="<select name=\"$name\">";
foreach ( $options as $option => $ignore ) {
if ( !$value ) $value = $option;
$s .= "<option" . ( $option == $value ? " selected>" : ">" ) .
htmlentities ( $option ) . "</option>";
}
return $s . "</select>";
}
////
// Flag (compile option) handling functions
////
/**
* Return default compile options (flags)
*
* Initial compile options are in a global called $flag_table.
* Create and return an array containing the ones we want.
*
* @return array default compile options (flags)
*/
function default_flags ()
{
global $flag_table;
$flags = array ();
foreach ( $flag_table as $key => $props ) {
$flag = $props["flag"];
$type = $props["type"];
// Fields like headers have no "value" property
if ( isset ( $props["value"] ) ) {
$flags[$flag] = $props["value"];
}
}
return $flags;
}
/**
* Return combination of default and user compile options (flags)
*
* Initial compile options are in a global called $flag_table.
* Compile options may have been changed via form input. We return
* an array with either the default value of each option or a user
* supplied value from form input.
*
* @return array combined default and user supplied compile options (flags)
*/
function get_flags ()
{
global $flag_table;
$flags = default_flags ();
if ( ! isset ( $_POST["use_flags"] ) )
return $flags;
foreach ( $flag_table as $key => $props ) {
$flag = $props["flag"];
$type = $props["type"];
if ( isset ( $_POST["$flag"] ) ) {
$flags[$flag] = $_POST["$flag"];
if ( $type == "integer-hex" ) {
if ( strtolower ( substr ( $flags[$flag], 0, 2 ) ) != "0x" ) {
$flags[$flag] = "0x" . $flags[$flag];
}
}
} else if ( $type == "on/off" ) {
// Unchecked checkboxes don't pass any POST value
// so we must check for them specially. At this
// point we know that there is no $_POST value set
// for this option. If it is a checkbox, this means
// it is unchecked, so record that in $flags so we
// can later generate an #undef for this option.
$flags[$flag] = "off";
}
}
return $flags;
}
/**
* Output given value in appropriate format for iPXE config file
*
* iPXE config/*.h files use C pre-processor syntax. Output the given
* compile option in a format appropriate to its type
*
* @param string $key index into $flag_table for given compile option
* @param string $value value we wish to set compile option to
*
* @return string code to set compile option to given value
*/
function pprint_flag ( $key, $value )
{
global $flag_table;
// Determine type of given compile option (flag)
$type = $flag_table[$key]["type"];
$s = "";
if ( $type == "on/off" && $value == "on" ) {
$s = "#define $key";
} else if ( $type == "on/off" && $value != "on" ) {
$s = "#undef $key";
} else if ( $type == "string" ) {
$s = ( "#define $key \"" . cleanstring ( $value ) . "\"" );
} else if ($type == "qstring" ) {
$s = ( "#define $key \\\"" . cleanstring ( $value ) . "\\\"" );
} else {
$s = "#define $key " . cleanstring ( $value );
}
return $s;
}
/**
* Output html code to display all compile options as a table
*
* @param array $flags array of compile options
*
* @return void
*/
function echo_flags ( $flags )
{
global $flag_table;
echo "<table>\n";
foreach ( $flag_table as $key => $props ) {
// Hide parameters from users that should not be changed.
$hide_from_user = isset ( $props["hide_from_user"] ) ? $props["hide_from_user"] : "no";
$flag = $props["flag"];
$type = $props["type"];
$value = isset ( $flags[$flag] ) ? $flags[$flag] : '';
if ( $hide_from_user == "yes" ) {
// Hidden flags cannot not be set by the user. We use hidden form
// fields to keep them at their default values.
if ( $type != "header" ) {
echo hidden ( $flag, $value );
}
} else {
// Flag (iPXE compile option) should be displayed to user
if ( $type == "header" ) {
$label = $props["label"];
echo "<td colspan=2><hr><h3>$label</h3><hr></td>";
} else if ($type == "on/off" ) {
echo "<td>", checkbox ( $flag, $value ), "</td><td><strong>$flag</strong></td>";
} else { // don't display checkbox for non-on/off flags
echo "<td>&nbsp;</td><td><strong>$flag: </strong>";
if ($type == "choice" ) {
$options = $props["options"];
echo menubox($flag, $options, $value);
} else {
echo textbox($flag, $value, ($type == "integer" ||
$type == "integer-hex"
? 7 : 25));
}
echo "</td>";
}
echo "</tr>\n";
if ( $type != "header" ) {
echo "<tr><td>&nbsp;</td>";
echo "<td>\n";
if ( is_file ( "doc/$flag.html" ) ) {
include_once "doc/$flag.html";
}
echo "\n</td></tr>\n";
}
}
}
echo "</table>";
}
/**
* Return an array of configuration sections used in all compile options
*
* $flag_table, the global list of compile options contains a 'cfgsec'
* property for each flag we are interested in. We return a list of
* all the unique cfgsec options we find in $flag_table.
*
* @return array an array of strings representing all unique cfgsec values
* found in $flag_table
*/
function get_flag_cfgsecs ()
{
global $flag_table;
$cfgsecs = array ();
foreach ( $flag_table as $key => $props ) {
if ( isset ( $props['cfgsec'] ) ) {
$cfgsec = $props["cfgsec"];
$cfgsecs[$cfgsec] = $cfgsec;
}
}
return $cfgsecs;
}
////
// File and directory handling functions
////
/**
* Create a copy of a given source directory to a given destination
*
* Since we are going to modify the source directory, we create a copy
* of the directory with a unique name in the given destination directory.
* We supply a prefix for the tempnam call to prepend to the random filename
* it generates.
*
* @param string $src source directory
* @param string $dst destination directory
* @param string $prefix string to append to directory created
*
* @return string absolute path to destination directory
*/
function mktempcopy ( $src, $dst, $prefix )
{
if ( $src[0] != "/" ) {
$src = dirname ( $_SERVER['SCRIPT_FILENAME'] ) . "/" . $src;
}
// Create a file in the given destination directory with a unique name
$dir = tempnam ( $dst, $prefix );
// Delete the file just created, since it would interfere with the copy we
// are about to do. We only care that the dir name we copy to is unique.
unlink ( $dir );
exec ( "/bin/cp -a '$src' '$dir' 2>&1", $cpytxt, $status );
if ( $status != 0 ) {
die ( "src directory copy failed!" );
}
return $dir;
}
/**
* Write iPXE config files based on value of given flags
*
* iPXE compile options are stored in src/config/*.h .
* We write out a config file for each set of options.
*
* @param string $config_dir directory to write .h files to
* @param array $flags array of compile options for this build
*
* @return void
*/
function write_ipxe_config_files ( $config_dir, $flags )
{
global $flag_table;
$cfgsecs = get_flag_cfgsecs ();
foreach ( $cfgsecs as $cfgsec ) {
$fname = $config_dir . "/" . $cfgsec . ".h";
$fp = fopen ( $fname, "wb" );
if ( $fp <= 0 ) {
die ( "Unable to open $fname file for output!" );
}
$ifdef_secname = "CONFIG_" . strtoupper ( $cfgsec ) . "_H";
fwrite ( $fp, "#ifndef ${ifdef_secname}\n" );
fwrite ( $fp, "#define ${ifdef_secname}\n" );
fwrite ( $fp, "#include <config/defaults.h>\n" );
foreach ( $flags as $key => $value ) {
// When the flag matches this section name, write it out
if ( $flag_table[$key]["cfgsec"] == $cfgsec ) {
fwrite ( $fp, pprint_flag ( $key, $value ) . "\n" );
}
}
fwrite ( $fp, "#endif /* ${ifdef_secname} */\n" );
fclose ( $fp );
}
}
/**
* Output a string to a file
*
* Output a given string to a given pathname. The file will be created if
* necessary, and the string will replace the file's contents in all cases.
*
* @param string $fname pathname of file to output string to
* @param string $ftext text to output to file
*
* @return void
*/
function write_file_from_string ( $fname, $ftext )
{
$fp = fopen ( $fname, "wb" );
if ( ! $fp ) {
die ( "Unable to open $fname file for output!" );
}
fwrite ( $fp, $ftext );
fclose ( $fp );
}
/**
* Delete a file or recursively delete a directory tree
*
* @param string $file_or_dir_name name of file or directory to delete
* @return bool Returns TRUE on success, FALSE on failure
*/
function rm_file_or_dir ( $file_or_dir_name )
{
if ( ! file_exists ( $file_or_dir_name ) ) {
return false;
}
if ( is_file ( $file_or_dir_name ) || is_link ( $file_or_dir_name ) ) {
return unlink ( $file_or_dir_name );
}
$dir = dir ( $file_or_dir_name );
while ( ( $dir_entry = $dir->read () ) !== false ) {
if ( $dir_entry == '.' || $dir_entry == '..') {
continue;
}
rm_file_or_dir ( $file_or_dir_name . '/' . $dir_entry );
}
$dir->close();
return rmdir ( $file_or_dir_name );
}
////
// Debugging functions
////
/**
* Emit html code to display given array of compile options (flags)
*
* @param array $flags array of compile options for this build
*
* @return void
*/
function show_flags ( $flags )
{
echo ( "\$flags contains " . count ( $flags ) . " elements:" . "<br>" );
foreach ( $flags as $key => $flag ) {
echo ( "\$flags[" . $key . "]=" . "\"$flag\"" . "<br>" );
}
}
/**
* Emit HTML code to display default array of compile options (flags)
*
* $flag_table contains default compile options and properties. This
* routine outputs HTML code to display all properties of $flag_table.
*
* @return void
*/
function dump_flag_table ()
{
global $flag_table;
echo ( "\$flag_table contains " . count ( $flag_table ) . " elements:" . "<br>" );
foreach ( $flag_table as $key => $props ) {
print ( "flag_table[" . $key . "] = " . "<br>" );
foreach ( $props as $key2 => $props2 ) {
print ( "&nbsp;&nbsp;&nbsp;" . $key2 . " = " . $props2 . "<br>" );
}
}
}
// Parse src/bin/NIC file
list ( $nics, $roms ) = parse_nic_file ();
// For emacs:
// Local variables:
// c-basic-offset: 4
// c-indent-level: 4
// tab-width: 4
// End:
?>

View File

@ -77,7 +77,6 @@ SRCDIRS += drivers/net/efi
SRCDIRS += drivers/net/tg3
SRCDIRS += drivers/net/bnxt
SRCDIRS += drivers/net/sfc
SRCDIRS += drivers/net/marvell
SRCDIRS += drivers/block
SRCDIRS += drivers/nvs
SRCDIRS += drivers/bitbash

View File

@ -23,9 +23,9 @@ NON_AUTO_MEDIA += efidrv
NON_AUTO_MEDIA += drv.efi
NON_AUTO_MEDIA += efirom
# Include SNP and MNP drivers in the all-drivers build
# Include SNP driver in the all-drivers build
#
DRIVERS_net += snp mnp
DRIVERS_net += snp
# Rules for building EFI files
#

View File

@ -366,6 +366,11 @@ MAKEDEPS += arch/$(ARCH)/Makefile
include arch/$(ARCH)/Makefile
endif
# Include architecture-specific include path
ifdef ARCH
INCDIRS += arch/$(ARCH)/include
endif
###############################################################################
#
# Especially ugly workarounds

View File

@ -3,9 +3,9 @@
ASM_TCHAR := %
ASM_TCHAR_OPS := %%
# Include ARM-specific headers
# Include common ARM headers
#
INCDIRS := arch/$(ARCH)/include arch/arm/include $(INCDIRS)
INCDIRS += arch/arm/include
# ARM-specific directories containing source files
#

View File

@ -0,0 +1,12 @@
#ifndef _BITS_ACPI_H
#define _BITS_ACPI_H
/** @file
*
* ARM-specific ACPI API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_ACPI_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_HYPERV_H
#define _BITS_HYPERV_H
/** @file
*
* Hyper-V interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_HYPERV_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_IOMAP_H
#define _BITS_IOMAP_H
/** @file
*
* ARM-specific I/O mapping API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_IOMAP_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_MP_H
#define _BITS_MP_H
/** @file
*
* ARM-specific multiprocessor API implementation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_MP_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_PCI_IO_H
#define _BITS_PCI_IO_H
/** @file
*
* ARM PCI I/O API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_PCI_IO_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_REBOOT_H
#define _BITS_REBOOT_H
/** @file
*
* ARM-specific reboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_REBOOT_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_SANBOOT_H
#define _BITS_SANBOOT_H
/** @file
*
* ARM-specific sanboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SANBOOT_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_SMBIOS_H
#define _BITS_SMBIOS_H
/** @file
*
* ARM-specific SMBIOS API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SMBIOS_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_TIME_H
#define _BITS_TIME_H
/** @file
*
* ARM-specific time API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_TIME_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_UACCESS_H
#define _BITS_UACCESS_H
/** @file
*
* ARM-specific user access API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UACCESS_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_UART_H
#define _BITS_UART_H
/** @file
*
* 16550-compatible UART
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UART_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_UMALLOC_H
#define _BITS_UMALLOC_H
/** @file
*
* ARM-specific user memory allocation API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UMALLOC_H */

View File

@ -0,0 +1,19 @@
#ifndef _BITS_TCPIP_H
#define _BITS_TCPIP_H
/** @file
*
* Transport-network layer interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static inline __attribute__ (( always_inline )) uint16_t
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
/* Not yet optimised */
return generic_tcpip_continue_chksum ( partial, data, len );
}
#endif /* _BITS_TCPIP_H */

View File

@ -1,12 +1,12 @@
#ifndef _BITS_GDBMACH_H
#define _BITS_GDBMACH_H
#ifndef GDBMACH_H
#define GDBMACH_H
/** @file
*
* Dummy GDB architecture specifics
* GDB architecture specifics
*
* This file is included only if the architecture does not provide its
* own version of this file.
* This file declares functions for manipulating the machine state and
* debugging context.
*
*/
@ -42,4 +42,4 @@ extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
int enable );
extern void gdbmach_init ( void );
#endif /* _BITS_GDBMACH_H */
#endif /* GDBMACH_H */

View File

@ -0,0 +1,45 @@
#ifndef GDBMACH_H
#define GDBMACH_H
/** @file
*
* GDB architecture specifics
*
* This file declares functions for manipulating the machine state and
* debugging context.
*
*/
#include <stdint.h>
typedef unsigned long gdbreg_t;
/* Register snapshot */
enum {
/* Not yet implemented */
GDBMACH_NREGS,
};
#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
/* Not yet implemented */
( void ) regs;
( void ) pc;
}
static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
/* Not yet implemented */
( void ) regs;
( void ) step;
}
static inline void gdbmach_breakpoint ( void ) {
/* Not yet implemented */
}
extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
int enable );
extern void gdbmach_init ( void );
#endif /* GDBMACH_H */

View File

@ -18,9 +18,6 @@ endif
# EFI requires -fshort-wchar, and nothing else currently uses wchar_t
CFLAGS += -fshort-wchar
# Include LoongArch64-specific headers
INCDIRS := arch/$(ARCH)/include $(INCDIRS)
# LoongArch64-specific directories containing source files
SRCDIRS += arch/loong64/core
SRCDIRS += arch/loong64/interface/efi

View File

@ -0,0 +1,12 @@
#ifndef _BITS_ACPI_H
#define _BITS_ACPI_H
/** @file
*
* LoongArch64-specific ACPI API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_ACPI_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_HYPERV_H
#define _BITS_HYPERV_H
/** @file
*
* Hyper-V interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_HYPERV_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_IOMAP_H
#define _BITS_IOMAP_H
/** @file
*
* LoongArch64-specific I/O mapping API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_IOMAP_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_MP_H
#define _BITS_MP_H
/** @file
*
* LoongArch64-specific multiprocessor API implementation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_MP_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_PCI_IO_H
#define _BITS_PCI_IO_H
/** @file
*
* LoongArch64-specific PCI I/O API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_PCI_IO_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_REBOOT_H
#define _BITS_REBOOT_H
/** @file
*
* LoongArch64-specific reboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_REBOOT_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_SANBOOT_H
#define _BITS_SANBOOT_H
/** @file
*
* LoongArch64-specific sanboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SANBOOT_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_SMBIOS_H
#define _BITS_SMBIOS_H
/** @file
*
* LoongArch64-specific SMBIOS API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_SMBIOS_H */

View File

@ -0,0 +1,19 @@
#ifndef _BITS_TCPIP_H
#define _BITS_TCPIP_H
/** @file
*
* Transport-network layer interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static inline __attribute__ (( always_inline )) uint16_t
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
/* Not yet optimised */
return generic_tcpip_continue_chksum ( partial, data, len );
}
#endif /* _BITS_TCPIP_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_TIME_H
#define _BITS_TIME_H
/** @file
*
* LoongArch64-specific time API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_TIME_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_UACCESS_H
#define _BITS_UACCESS_H
/** @file
*
* LoongArch64-specific user access API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UACCESS_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_UART_H
#define _BITS_UART_H
/** @file
*
* 16550-compatible UART
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UART_H */

View File

@ -0,0 +1,12 @@
#ifndef _BITS_UMALLOC_H
#define _BITS_UMALLOC_H
/** @file
*
* LoongArch64-specific user memory allocation API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#endif /* _BITS_UMALLOC_H */

View File

@ -3,10 +3,7 @@
/** @file
*
* Dummy architecture-specific Xen interface
*
* This file is included only if the architecture does not provide its
* own version of this file.
* Xen interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

View File

@ -0,0 +1,45 @@
#ifndef GDBMACH_H
#define GDBMACH_H
/** @file
*
* GDB architecture specifics
*
* This file declares functions for manipulating the machine state and
* debugging context.
*
*/
#include <stdint.h>
typedef unsigned long gdbreg_t;
/* Register snapshot */
enum {
/* Not yet implemented */
GDBMACH_NREGS,
};
#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
/* Not yet implemented */
( void ) regs;
( void ) pc;
}
static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
/* Not yet implemented */
( void ) regs;
( void ) step;
}
static inline void gdbmach_breakpoint ( void ) {
/* Not yet implemented */
}
extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
int enable );
extern void gdbmach_init ( void );
#endif /* GDBMACH_H */

View File

@ -3,9 +3,9 @@
ASM_TCHAR := @
ASM_TCHAR_OPS := @
# Include x86-specific headers
# Include common x86 headers
#
INCDIRS := arch/$(ARCH)/include arch/x86/include $(INCDIRS)
INCDIRS += arch/x86/include
# x86-specific directories containing source files
#

View File

@ -84,8 +84,8 @@ int cpuid_supported ( uint32_t function ) {
return rc;
/* Find highest supported function number within this family */
cpuid ( ( function & ( CPUID_EXTENDED | CPUID_HYPERVISOR ) ), 0,
&max_function, &discard_b, &discard_c, &discard_d );
cpuid ( ( function & CPUID_EXTENDED ), 0, &max_function, &discard_b,
&discard_c, &discard_d );
/* Fail if maximum function number is meaningless (e.g. if we
* are attempting to call an extended function on a CPU which

View File

@ -38,8 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
* Bit 31 Extended function
* Bits 30-24 (bit 22 = 1) Subfunction number
* Bit 30 (bit 22 = 0) Hypervisor function
* Bits 29-24 (bit 22 = 0) Number of consecutive functions to call, minus one
* (bit 22 = 0) Number of consecutive functions to call, minus one
* Bit 23 Return result as little-endian (used for strings)
* Bit 22 Interpret bits 30-24 as a subfunction number
* Bits 21-18 Unused
@ -99,7 +98,7 @@ enum cpuid_flags {
* @v tag Setting tag
* @ret function Starting function number
*/
#define CPUID_FUNCTION( tag ) ( (tag) & 0xc00000ffUL )
#define CPUID_FUNCTION( tag ) ( (tag) & 0x800000ffUL )
/**
* Extract subfunction number from CPUID setting tag
@ -109,14 +108,6 @@ enum cpuid_flags {
*/
#define CPUID_SUBFUNCTION( tag ) ( ( (tag) >> 24 ) & 0x7f )
/**
* Extract number of consecutive functions from CPUID setting tag
*
* @v tag Setting tag
* @ret num_functions Number of consecutive functions
*/
#define CPUID_NUM_FUNCTIONS( tag ) ( ( ( (tag) >> 24 ) & 0x3f ) + 1 )
/**
* Extract register array from CPUID setting tag
*
@ -174,13 +165,12 @@ static int cpuid_settings_fetch ( struct settings *settings,
/* Call each function in turn */
function = CPUID_FUNCTION ( setting->tag );
subfunction = CPUID_SUBFUNCTION ( setting->tag );
if ( setting->tag & CPUID_USE_SUBFUNCTION ) {
function &= ~CPUID_HYPERVISOR;
subfunction = CPUID_SUBFUNCTION ( setting->tag );
num_functions = 1;
} else {
num_functions = ( subfunction + 1 );
subfunction = 0;
num_functions = CPUID_NUM_FUNCTIONS ( setting->tag );
}
for ( ; num_functions-- ; function++ ) {

View File

@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/uaccess.h>
#include <ipxe/gdbstub.h>
#include <librm.h>
#include <gdbmach.h>
/** @file
*

View File

@ -45,7 +45,6 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) {
PCIDIRECT_CONFIG_ADDRESS );
}
PROVIDE_PCIAPI_INLINE ( direct, pci_can_probe );
PROVIDE_PCIAPI_INLINE ( direct, pci_discover );
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte );
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );

View File

@ -33,9 +33,6 @@ struct x86_features {
/** CPUID extended function */
#define CPUID_EXTENDED 0x80000000UL
/** CPUID hypervisor function */
#define CPUID_HYPERVISOR 0x40000000UL
/** Get vendor ID and largest standard function */
#define CPUID_VENDOR_ID 0x00000000UL

View File

@ -32,16 +32,6 @@ extern int pcibios_read ( struct pci_device *pci, uint32_t command,
extern int pcibios_write ( struct pci_device *pci, uint32_t command,
uint32_t value );
/**
* Check if PCI bus probing is allowed
*
* @ret ok Bus probing is allowed
*/
static inline __always_inline int
PCIAPI_INLINE ( pcbios, pci_can_probe ) ( void ) {
return 1;
}
/**
* Read byte from PCI configuration space via PCI BIOS
*

View File

@ -15,14 +15,4 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define PCIAPI_PREFIX_cloud __cloud_
#endif
/**
* Check if PCI bus probing is allowed
*
* @ret ok Bus probing is allowed
*/
static inline __always_inline int
PCIAPI_INLINE ( cloud, pci_can_probe ) ( void ) {
return 1;
}
#endif /* _IPXE_PCICLOUD_H */

View File

@ -25,16 +25,6 @@ struct pci_device;
extern void pcidirect_prepare ( struct pci_device *pci, int where );
/**
* Check if PCI bus probing is allowed
*
* @ret ok Bus probing is allowed
*/
static inline __always_inline int
PCIAPI_INLINE ( direct, pci_can_probe ) ( void ) {
return 1;
}
/**
* Find next PCI bus:dev.fn address range in system
*

View File

@ -120,7 +120,6 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
return ( status >> 8 );
}
PROVIDE_PCIAPI_INLINE ( pcbios, pci_can_probe );
PROVIDE_PCIAPI ( pcbios, pci_discover, pcibios_discover );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte );
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word );

View File

@ -148,7 +148,6 @@ static void * pcicloud_ioremap ( struct pci_device *pci,
return pcicloud->pci_ioremap ( pci, bus_addr, len );
}
PROVIDE_PCIAPI_INLINE ( cloud, pci_can_probe );
PROVIDE_PCIAPI ( cloud, pci_discover, pcicloud_discover );
PROVIDE_PCIAPI ( cloud, pci_read_config_byte, pcicloud_read_config_byte );
PROVIDE_PCIAPI ( cloud, pci_read_config_word, pcicloud_read_config_word );

View File

@ -225,10 +225,7 @@ REQUIRE_OBJECT ( dhcp_cmd );
REQUIRE_OBJECT ( sanboot_cmd );
#endif
#ifdef MENU_CMD
REQUIRE_OBJECT ( dynui_cmd );
#endif
#ifdef FORM_CMD
REQUIRE_OBJECT ( dynui_cmd );
REQUIRE_OBJECT ( menu_cmd );
#endif
#ifdef LOGIN_CMD
REQUIRE_OBJECT ( login_cmd );
@ -299,9 +296,6 @@ REQUIRE_OBJECT ( image_mem_cmd );
#ifdef SHIM_CMD
REQUIRE_OBJECT ( shim_cmd );
#endif
#ifdef IMAGE_CRYPT_CMD
REQUIRE_OBJECT ( image_crypt_cmd );
#endif
/*
* Drag in miscellaneous objects

View File

@ -88,16 +88,6 @@ REQUIRE_OBJECT ( oid_sha512_256 );
REQUIRE_OBJECT ( oid_x25519 );
#endif
/* AES-CBC */
#if defined ( CRYPTO_CIPHER_AES_CBC )
REQUIRE_OBJECT ( oid_aes_cbc );
#endif
/* AES-GCM */
#if defined ( CRYPTO_CIPHER_AES_GCM )
REQUIRE_OBJECT ( oid_aes_gcm );
#endif
/* RSA and MD5 */
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_DIGEST_MD5 )
REQUIRE_OBJECT ( rsa_md5 );

View File

@ -29,9 +29,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Corrupt every N received PeerDist packets */
#define PEERBLK_CORRUPT_RATE 0
/* Experience virtual machine migration on every N watchdog checks */
#define VM_MIGRATED_RATE 0
#include <config/local/fault.h>
#endif /* CONFIG_FAULT_H */

View File

@ -145,7 +145,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define DHCP_CMD /* DHCP management commands */
#define SANBOOT_CMD /* SAN boot commands */
#define MENU_CMD /* Menu commands */
#define FORM_CMD /* Form commands */
#define LOGIN_CMD /* Login command */
#define SYNC_CMD /* Sync command */
#define SHELL_CMD /* Shell command */
@ -158,7 +157,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
//#define REBOOT_CMD /* Reboot command */
//#define POWEROFF_CMD /* Power off command */
//#define IMAGE_TRUST_CMD /* Image trust management commands */
//#define IMAGE_CRYPT_CMD /* Image encryption management commands */
//#define PCI_CMD /* PCI commands */
//#define PARAM_CMD /* Request parameter commands */
//#define NEIGHBOUR_CMD /* Neighbour management commands */

View File

@ -43,6 +43,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*/
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 */
@ -65,8 +66,10 @@ int image_extract ( struct image *image, const char *name,
}
/* Strip any archive or compression suffix from implicit name */
if ( ! name )
image_strip_suffix ( *extracted );
if ( ( ! name ) && ( (*extracted)->name ) &&
( ( dot = strrchr ( (*extracted)->name, '.' ) ) != NULL ) ) {
*dot = '\0';
}
/* Try extracting archive image */
if ( ( rc = image->type->extract ( image, *extracted ) ) != 0 ) {

View File

@ -46,20 +46,11 @@ struct cached_dhcp_packet {
struct dhcp_packet *dhcppkt;
/** VLAN tag (if applicable) */
unsigned int vlan;
/** Flags */
unsigned int flags;
};
/** Cached DHCP packet should be retained */
#define CACHEDHCP_RETAIN 0x0001
/** Cached DHCP packet has been used */
#define CACHEDHCP_USED 0x0002
/** Cached DHCPACK */
struct cached_dhcp_packet cached_dhcpack = {
.name = DHCP_SETTINGS_NAME,
.flags = CACHEDHCP_RETAIN,
};
/** Cached ProxyDHCPOFFER */
@ -110,8 +101,8 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
size_t ll_addr_len;
int rc;
/* Do nothing if cache is empty or already in use */
if ( ( ! cache->dhcppkt ) || ( cache->flags & CACHEDHCP_USED ) )
/* Do nothing if cache is empty */
if ( ! cache->dhcppkt )
return 0;
chaddr = cache->dhcppkt->dhcphdr->chaddr;
@ -178,12 +169,8 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
return rc;
}
/* Mark as used */
cache->flags |= CACHEDHCP_USED;
/* Free cached DHCP packet, if applicable */
if ( ! ( cache->flags & CACHEDHCP_RETAIN ) )
cachedhcp_free ( cache );
/* Free cached DHCP packet */
cachedhcp_free ( cache );
return 0;
}
@ -259,10 +246,10 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan,
}
/**
* Cached DHCP packet early startup function
* Cached DHCP packet startup function
*
*/
static void cachedhcp_startup_early ( void ) {
static void cachedhcp_startup ( void ) {
/* Apply cached ProxyDHCPOFFER, if any */
cachedhcp_apply ( &cached_proxydhcp, NULL );
@ -271,20 +258,6 @@ static void cachedhcp_startup_early ( void ) {
/* Apply cached PXEBSACK, if any */
cachedhcp_apply ( &cached_pxebs, NULL );
cachedhcp_free ( &cached_pxebs );
}
/**
* Cache DHCP packet late startup function
*
*/
static void cachedhcp_startup_late ( void ) {
/* Clear retention flag */
cached_dhcpack.flags &= ~CACHEDHCP_RETAIN;
/* Free cached DHCPACK, if used by a network device */
if ( cached_dhcpack.flags & CACHEDHCP_USED )
cachedhcp_free ( &cached_dhcpack );
/* Report unclaimed DHCPACK, if any. Do not free yet, since
* it may still be claimed by a dynamically created device
@ -311,16 +284,10 @@ static void cachedhcp_shutdown ( int booting __unused ) {
cachedhcp_free ( &cached_dhcpack );
}
/** Cached DHCP packet early startup function */
struct startup_fn cachedhcp_early_fn __startup_fn ( STARTUP_EARLY ) = {
.name = "cachedhcp1",
.startup = cachedhcp_startup_early,
};
/** Cached DHCP packet late startup function */
struct startup_fn cachedhcp_late_fn __startup_fn ( STARTUP_LATE ) = {
.name = "cachedhcp2",
.startup = cachedhcp_startup_late,
/** Cached DHCPACK startup function */
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
.name = "cachedhcp",
.startup = cachedhcp_startup,
.shutdown = cachedhcp_shutdown,
};
@ -342,25 +309,3 @@ struct net_driver cachedhcp_driver __net_driver = {
.name = "cachedhcp",
.probe = cachedhcp_probe,
};
/**
* Recycle cached DHCPACK
*
* @v netdev Network device
* @v priv Private data
*/
void cachedhcp_recycle ( struct net_device *netdev ) {
struct cached_dhcp_packet *cache = &cached_dhcpack;
struct settings *settings;
/* Return DHCPACK to cache, if applicable */
settings = find_child_settings ( netdev_settings ( netdev ),
cache->name );
if ( cache->dhcppkt && ( settings == &cache->dhcppkt->settings ) ) {
DBGC ( colour, "CACHEDHCP %s recycled from %s\n",
cache->name, netdev->name );
assert ( cache->flags & CACHEDHCP_USED );
unregister_settings ( settings );
cache->flags &= ~CACHEDHCP_USED;
}
}

View File

@ -1,220 +0,0 @@
/*
* Copyright (C) 2012 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 );
/** @file
*
* Dynamic user interfaces
*
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ipxe/list.h>
#include <ipxe/dynui.h>
/** List of all dynamic user interfaces */
static LIST_HEAD ( dynamic_uis );
/**
* Create dynamic user interface
*
* @v name User interface name, or NULL
* @v title User interface title, or NULL
* @ret dynui Dynamic user interface, or NULL on failure
*/
struct dynamic_ui * create_dynui ( const char *name, const char *title ) {
struct dynamic_ui *dynui;
size_t name_len;
size_t title_len;
size_t len;
char *name_copy;
char *title_copy;
/* Destroy any existing user interface of this name */
dynui = find_dynui ( name );
if ( dynui )
destroy_dynui ( dynui );
/* Use empty title if none given */
if ( ! title )
title = "";
/* Allocate user interface */
name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
title_len = ( strlen ( title ) + 1 /* NUL */ );
len = ( sizeof ( *dynui ) + name_len + title_len );
dynui = zalloc ( len );
if ( ! dynui )
return NULL;
name_copy = ( ( void * ) ( dynui + 1 ) );
title_copy = ( name_copy + name_len );
/* Initialise user interface */
if ( name ) {
strcpy ( name_copy, name );
dynui->name = name_copy;
}
strcpy ( title_copy, title );
dynui->title = title_copy;
INIT_LIST_HEAD ( &dynui->items );
/* Add to list of user interfaces */
list_add_tail ( &dynui->list, &dynamic_uis );
DBGC ( dynui, "DYNUI %s created with title \"%s\"\n",
dynui->name, dynui->title );
return dynui;
}
/**
* Add dynamic user interface item
*
* @v dynui Dynamic user interface
* @v name Name, or NULL
* @v text Text, or NULL
* @v flags Flags
* @v shortcut Shortcut key
* @ret item User interface item, or NULL on failure
*/
struct dynamic_item * add_dynui_item ( struct dynamic_ui *dynui,
const char *name, const char *text,
unsigned int flags, int shortcut ) {
struct dynamic_item *item;
size_t name_len;
size_t text_len;
size_t len;
char *name_copy;
char *text_copy;
/* Use empty text if none given */
if ( ! text )
text = "";
/* Allocate item */
name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
text_len = ( strlen ( text ) + 1 /* NUL */ );
len = ( sizeof ( *item ) + name_len + text_len );
item = zalloc ( len );
if ( ! item )
return NULL;
name_copy = ( ( void * ) ( item + 1 ) );
text_copy = ( name_copy + name_len );
/* Initialise item */
if ( name ) {
strcpy ( name_copy, name );
item->name = name_copy;
}
strcpy ( text_copy, text );
item->text = text_copy;
item->index = dynui->count++;
item->flags = flags;
item->shortcut = shortcut;
/* Add to list of items */
list_add_tail ( &item->list, &dynui->items );
return item;
}
/**
* Destroy dynamic user interface
*
* @v dynui Dynamic user interface
*/
void destroy_dynui ( struct dynamic_ui *dynui ) {
struct dynamic_item *item;
struct dynamic_item *tmp;
/* Remove from list of user interfaces */
list_del ( &dynui->list );
/* Free items */
list_for_each_entry_safe ( item, tmp, &dynui->items, list ) {
list_del ( &item->list );
free ( item );
}
/* Free user interface */
free ( dynui );
}
/**
* Find dynamic user interface
*
* @v name User interface name, or NULL
* @ret dynui Dynamic user interface, or NULL if not found
*/
struct dynamic_ui * find_dynui ( const char *name ) {
struct dynamic_ui *dynui;
list_for_each_entry ( dynui, &dynamic_uis, list ) {
if ( ( dynui->name == name ) ||
( strcmp ( dynui->name, name ) == 0 ) ) {
return dynui;
}
}
return NULL;
}
/**
* Find dynamic user interface item by index
*
* @v dynui Dynamic user interface
* @v index Index
* @ret item User interface item, or NULL if not found
*/
struct dynamic_item * dynui_item ( struct dynamic_ui *dynui,
unsigned int index ) {
struct dynamic_item *item;
list_for_each_entry ( item, &dynui->items, list ) {
if ( index-- == 0 )
return item;
}
return NULL;
}
/**
* Find dynamic user interface item by shortcut key
*
* @v dynui Dynamic user interface
* @v key Shortcut key
* @ret item User interface item, or NULL if not found
*/
struct dynamic_item * dynui_shortcut ( struct dynamic_ui *dynui, int key ) {
struct dynamic_item *item;
list_for_each_entry ( item, &dynui->items, list ) {
if ( key && ( key == item->shortcut ) )
return item;
}
return NULL;
}

Some files were not shown because too many files have changed in this diff Show More