Warner Losh [Wed, 30 Nov 2022 22:10:23 +0000 (15:10 -0700)]
stand/ofw: Refactor ofw parsedev
Both ofw_disk and ofw_net use the same parsedev routine, except for the
string passed in to match the ofw device node's type. Create a routine
to do that and connect these two users up to that.
Warner Losh [Wed, 30 Nov 2022 22:10:11 +0000 (15:10 -0700)]
ofw/disk: Add parsedev support
Add a parsedev support for OpenFirmware disks. We must look at
characteristics of the OFW node to know if we match this device (so
supply a match routine) or not. Add a parsing routine to allocate
devdesc for OpenFirmware disks as well.
Warner Losh [Wed, 30 Nov 2022 22:09:51 +0000 (15:09 -0700)]
stand: Add dv_match
On OpenFirmware, and possibly kboot, we use full path names for the
objects that are the 'device'. kboot uses a hack of knowing that all
disk device nodes start with '/dev', but this generalizes it for
OpenFirmware where both 'block' and 'network' devices live in the same
namespace and one must ask the OF node its type to know if this device
type matches.
For drivers that don't specify, the current convention of using
strncmp() is retained. This is done only in devparse(), but everything
uses it directly (or will soon).
Warner Losh [Wed, 30 Nov 2022 22:09:36 +0000 (15:09 -0700)]
stand: parsedev API change: devspec now points to start of full device name
To support more flexible device matching, we now pass in the full
devspec to the parsedev routines. For everything execpt uboot, this is
just a drop in (since everything except uboot and openfirmware always
uses disk...: and/or zfs:, but openfirmware isn't really affected).
uboot we kludge around it by subtracting 4 from where the rest of the
device name starts. This is unforunate, and can compute the address one
before the string. But we never dereference that address. uboot needs
more work, and this is an acceptable UB until that other work happens.
OFW doesn't really use the parsedev routines these days (since none of
the supported device uses this... yet). It too needs more work, but it
needs device matching support first.
Warner Losh [Wed, 30 Nov 2022 22:09:23 +0000 (15:09 -0700)]
stand/ofw: ofw_disk isn't really a disk
The rest of the code in the tree assumes that a DEVT_DISK uses a
disk_devdesc to represent the device. However ofw_disk diesn't, so we
can't use disk_fmtdev, nor disk_parsedev. ofw needs to have a
dv_match-like routine to use devpasrse, though, since we have two
drivers (net and block) that claim the same sort of devices (eg
/path/to/ofw-dev) based on the device-type property. In the interim, we
can't use devmatch and ofw_disk's and the default net driver's parsing
is offloaded ofw_parsedev.
Warner Losh [Wed, 30 Nov 2022 22:08:42 +0000 (15:08 -0700)]
stand: Introduce devparse to parse device / path strings
devparse is now the preferred interface to use to parse device
strings or device:/path strings. It parses the passed in string,
mallocs the device's particular devdesc string and returns the
'remainder' of the device:/path for further processing.
Warner Losh [Wed, 30 Nov 2022 22:08:36 +0000 (15:08 -0700)]
stand: Introduce new dv_parsedev routine
Allow device classes to define a parsing routine. Most device classes
already have these routines, but there's much duplication in their
use. Define an interface for a common routine to parse an individual
device. By convetion, files have the form "[device:]/path/to/file"
where device is optional (filled in to be the value of currdev)
and it starts with the dv_name field of the device, with the rest
of the name up to the device (typically a unit number, but disks
add partition inforation, and other devices may do artibtrary
otehr things).
Warner Losh [Wed, 30 Nov 2022 22:08:22 +0000 (15:08 -0700)]
stand: Change zfs_parsedev() API
Change the first argument to zfs_parsedev() to be a pointer to a struct
devdesc *. This now gets filled in with a malloc'd structure that's
returned to the caller that the caller is repsonsible for freeing. Most
nplaces in the tree passed in a malloc'd pointer anyway, and this moves
knowledge of zfs_devdesc more firmly into the zfs.c code.
Warner Losh [Wed, 30 Nov 2022 22:08:15 +0000 (15:08 -0700)]
stand: Change disk_parsedev() API
Change the first argument to disk_parsedev() to be a pointer to a struct
devdesc *. This now gets filled in with a malloc'd structure that's
returned to the caller that the caller is repsonsible for freeing. Most
places in the tree passed in a malloc'd pointer anyway, and this moves
knowledge of disk_devdesc more firmly into the disk.[ch] code.
Warner Losh [Tue, 29 Nov 2022 20:02:40 +0000 (13:02 -0700)]
stand/ofw: Use strpbrk instead of two strchrs
No need to call strchr twice, when one call to strpbrk will do the
job.. Test booted with qemu-powerpc + mac99 successfully.
Minor style(9) tweaks as well.
Warner Losh [Sun, 27 Nov 2022 20:23:28 +0000 (13:23 -0700)]
ofw: Cast function pointer to proper type
clang 15 insists that we call entry() via a function prototype. Rather
than copping out and using (...), cast it to the same prototype that's
used elsewhere (with tweaks to pointers to make them fit into that
prototype). No functional change.
Warner Losh [Fri, 4 Nov 2022 21:28:26 +0000 (15:28 -0600)]
stand: Remove unused enum
enum disk_ioctl is unused. It's only ever defined. All of the stand
code uses DIOCGSECTORSIZE and DIOCGMEDIASIZE instead, both to query and
to implement ioctl.
Warner Losh [Thu, 27 Oct 2022 17:37:54 +0000 (11:37 -0600)]
kboot: Add hostfs
Add hostfs for the Linux environment. We can't use the userboot one
that's kinda similar because the Linux system calls we have in kboot are
not quite POSIX compliant (Linux takes care of providing the POSIX
interface in libc), so we have to cope with a number of quirks in that
area.
Warner Losh [Thu, 27 Oct 2022 17:36:51 +0000 (11:36 -0600)]
stand/kboot: Make FDT fixup per-arch
The fixups needed vary somewhat by architecture, so move the FDT fixup
to be per-arch. Rename the fdt_linux_fixup() routine to be
fdt_arch_fixup() and expect all architecutres to fix things up as
needed.
Warner Losh [Sat, 22 Oct 2022 15:09:23 +0000 (09:09 -0600)]
stand/kboot: hostdisk isn't a DEVT_DISK, use a different value.
We assume in all the code that a DEVT_DISK uses common/disk.c and/or
common/part.c and we can access a struct disk_devdesc. hostdisk.c
opens raw devices directly, so has no such structures. Define a
kboot-specific DEVT_HOSTDISK and use that instead.
In addition, disk_fmtdev assumes it is working with a struct
disk_devdesc, so write hostdisk_fmtdev as well.
Warner Losh [Fri, 21 Oct 2022 23:39:34 +0000 (17:39 -0600)]
stabd/geli: Bail out if you can't get the disks size
If the DIOCGMEDIASIZE ioctl fails, assume the disk doesn't have geli
encryption. While all disks should implement this, fail safe for disks /
partitions that do not.
Warner Losh [Sat, 8 Oct 2022 05:40:56 +0000 (23:40 -0600)]
kboot: Move load address stuff to MD code
The load address computations are highly architecture specific. There
are generic ways that are augmented by specific constraints of specific
way things work on each architecture. Move the current load segment
computations into a MD routine load_addr.
As part of the move, I'm marking kboot_get_kernel_machine_bits as
unused. This arrived in a prior commit, but never seems to have been
connected, suggesting an incomplete merge at the time, or a path not yet
taken.
Create a stub for amd64 that will be filled in with a later commit.
Warner Losh [Fri, 16 Sep 2022 15:10:14 +0000 (09:10 -0600)]
stand/elf: Only support swapping headers on powerpc.
Powerpc is currently the only architecture that we support more than one
endian. It's the only one that benefits from this swapping, so restrict
the code to there. This saves about 1k in the i386 BIOS loader.
Warner Losh [Fri, 16 Sep 2022 15:09:07 +0000 (09:09 -0600)]
stand: Stop support booting 4.x and earlier kernels
FreeBSD 4.x and earlier used the bi_bios_geom to get the geometry of the
device. Starting in 5.x, with the wdc -> ata rewrite, it was used only
in pc98 kernels to report geometry of the drives. It can be safely
removed as booting kernels this old is no longer supported. This saves
176 bytes in the BIOS loader.
Warner Losh [Fri, 16 Sep 2022 15:09:02 +0000 (09:09 -0600)]
stand: Remove dead store to bi_kernelname
We set this value twice: once to 0 and once to the VA that has the name
of the kernel. The first store is redundant. In addition, these two
stores of 0 are also redundant. Since we never set them, they will
always be zero, even if we're called multiple times. This saves 21
bytes on BIOS loader.
Warner Losh [Fri, 16 Sep 2022 15:08:47 +0000 (09:08 -0600)]
stand: Move md_copymodules into modinfo.c and reduce copies
md_copymodules, bi_copymdoules, bi_copymodules32 (x2) and
bi_copymodules64 (x2) are all the same routine... Replace them all with
md_copymodules. This saves about 800 bytes on i386 BIOS loader, which is
a nice bonus.
stand/efi: Call md_copymodules based on __LP64__ to fix 32-bit arm
When I refactored everything, I neglected to pass in the proper is64
value on 32-bit platforms. This corrects that. This prevented armv7 and
armv6 platforms from booting due to misaligned data in the kernel. The
only platform we support 32-bit booting in armv[67], which I apparently
neglected to test before commiting my refactoring.
Warner Losh [Fri, 16 Sep 2022 15:08:42 +0000 (09:08 -0600)]
stand: Create common/modinfo.h
Move all the MOD_xxx macros to this header. Each user of this interface
is currently required to define MOD_ALIGNMENT(l). modinfo was selected
because it sits inbetween modules and metadata and will make it easier
to migrate to new, shared intefaces.
Warner Losh [Fri, 16 Sep 2022 15:08:32 +0000 (09:08 -0600)]
stand: use archsw.arch_copyin instead of direct call
This replaces the CALLBACK(copyin, ...) with a call to
archsw.arch_copyin which points to a function that does the
callback. More diff reduction for the multiple copies of these routines
in the tree.
Warner Losh [Fri, 16 Sep 2022 15:08:23 +0000 (09:08 -0600)]
stand: use archsw.arch_copyin instead of i386_copyin
Since archsw.arch_copyin is always i386_copyin, this will be a nop in
terms of functionality. This is a diff reduction against other copies of
the code that differ only by what copyin routine they call.
loader.efi(8): document slop control, amd64 nocopy, and amd64 fault commands
Reviewed by: imp
Discussed with: gbe (man pages)
English wording help by: rpokala
Sponsored by: The FreeBSD Foundation
MFC after: 3 days
Differential revision: https://reviews.freebsd.org/D36435
Warner Losh [Sun, 4 Sep 2022 15:31:51 +0000 (09:31 -0600)]
stand/kboot: Add note about why we use MACHINE_ARCH here
Normally in the boot loader, we key off of MACHINE since that specifies
the kernel and the loader is very tuned to each type of MACHINE in
general. In this case, however, we're producing a Linux binary, with
Linux system calls encoded in it. These align better along the
MACHINE_ARCH axis of FreeBSD. For PowerPC the system calls are radically
different for each of our MACHINE_ARCHes, with only powerpc64 and
powerpc64le sharing the same numbers and memory layout. The same was
true about mips when it was in the tree. 32-bit arm uses the same
layout, however, for both armv6 and armv7 ports: that can be easily
shared in the unlikely event we support that in the future.
This allows the "Multi user" in "[B]oot Multi user" to be substituted
with another string, for example with "Installer" in installer media.
Note that this is lua-only at the moment, since loader.4th's menu.rc
defines the alternate name as Boot [M]ulti User, unlike lualoader which
leaves it as [B]oot Multi user. Ideally loader.4th would adopt the newer
and simpler lualoader behaviour and then it could gain support for this
option, but loader.4th is on the way out and isn't used by any official
installer media so this is not a significant concern.
Add a smbios.bios.revision kenv, which contains the system BIOS revision
as defined in SMBIOS specification, section 3.3.1.
Since the revision is stored in two separate byte fields,
the smbios_setenv helper can't be used.
Read and construct the kenv manually instead.
Warner Losh [Thu, 1 Sep 2022 17:06:43 +0000 (11:06 -0600)]
kboot: add minmalist init functionality
It is desirable to run kboot as the first program in some LinuxBoot
environments. This is the traditional "pid 1" or "init" program. When
running as pid 1. rovide a minimal environment based on what sysvinit,
u-root, initramfs-tools and other like projects do. We mount /dev, /sys,
/proc, make symlinks from /dev/fd to /dev/proc, and create /tmp, /run,
and /var. We also setup stdin/out/err to the console, set the tty
characteristics of same and block the appropriate signals.
This is indended as an environment that never does a fork/exec. If
that's required, the process groups, session leaders and all things
POSIX terminal handlers will need to be added.
Unlike the general purpose linux projects in this area, no attempt is
made to support very old kernels.
Warner Losh [Thu, 1 Sep 2022 17:05:42 +0000 (11:05 -0600)]
stand: separate the command lookup from the command execution
Factor out interp_lookup_cmd to search for a command from
interp_builtin_cmd. This simplifies the latter and can be used to expand
lua to ask if a command exists.
Warner Losh [Thu, 1 Sep 2022 16:34:30 +0000 (10:34 -0600)]
stand: Document EFI consoles
Document how EFI consoles work, at least on x86. There's a number of
weird quirks and limitations that are generally known, but not
documented until now. Include information on how EFI decides what the
defualt console is, how to set it and how to cope with common
situations. Note limitations and mismatch between ACPI (which uses UID
to identify a device) and our console code (which uses a raw address)
and explain why we can't translate between them in the loader.
Warner Losh [Fri, 26 Aug 2022 21:47:21 +0000 (15:47 -0600)]
stand: Document that boot0 uses BIOS
And thus has a limited range of supported baud rates. Also add that
setting BOOT_BOOT0_COMCONSOLE_SPEED=0 will leave it unchanged which
sometimes can give you 115200 if the BIOS initialized things outside of
the normal BIOS baud rates (which many x86 enbedded-targetted boards
do).
Warner Losh [Fri, 26 Aug 2022 21:46:33 +0000 (15:46 -0600)]
stand: More sensible defaults when ConOut is missing
When ConOut is missing, we used to default to serial. Except we did it
in the worst way possible by just setting the howto bits and not
updating the console setting, which lead to weird behavior where we'd
get some things on the video port, others on serial.
Instead, set console to "efi,comconsole" for this case. Also set
RB_MULTIPLE always (so we get dual consoles from the kernel) and or in
RB_SERIAL when we can't find GOPs that suggest the precense of a video
console. This will put output in the most places and have a sensible
default for 'primary' console.
Sponsored by: Netflix
Reviewed by: emaste, manu
Differential Revision: https://reviews.freebsd.org/D36299
Warner Losh [Fri, 12 Aug 2022 04:59:51 +0000 (22:59 -0600)]
stand: Raise limit to 550,000 bytes for loader
Raise the limit for /boot/loader to be 550k. The IBM PC imposes a limit
of 640k of RAM below 1MB, which is needed for real mode calls. BTX takes
40k of that. The BIOS takes some amount (25k seems a good "99% take less
than or equal to this" estimate for that, though some systems consume
more). Most typical setups need 25k of stack. This leaves 550k for
code. We set the limit to 550,000 which gives about an extra 13,000
bytes of buffer for machines that whose setups use a little more stack
or whose BIOS reserves a bit more...
Add this derivation in the Makefile. Also recommend setting LOADERSIZE
lower in /etc/src.conf when the loader has to run on a system whose BIOS
takes up more space, or for a complex setup. Add a recipe for how to
find how much RAM your BIOS uses as well (thanks to jhb@ for the
trick). Network cards that boot via PXE and HBAs with their BIOS enabled
are known to be large consumers of lomem space.
Warner Losh [Thu, 11 Aug 2022 23:29:10 +0000 (17:29 -0600)]
stand: Go back to a.out format for /boot/loader
Turns out there's two hidden a.out dependencies. pxeldr.S assumes it has
access to the a.out header from /boot/loader and cdboot.S assumes that
/boot/loader is also a.out and doesn't use boot2.
So, go back to making a.out files for these and adjust the size checks
to use ls, but we only need to check loader.bin. Trim the size we check
against by 2,000. The difference in size between loader and loader.bin
is about 3000 bytes, but clang15 produces binaries that are a smidge
bigger so we need to relax the check just a little and accept some
additional risk for the moment.
Add some comments to loader's Makefile about this.
Warner Losh [Thu, 11 Aug 2022 16:24:58 +0000 (10:24 -0600)]
stand: Make BIOS loader size limits settable
It's sometimes desirable to override the size limit: It's a soft limit
and there are times we exceed the limit by just a little bit and don't
want the build to fail (or we are hitting runtime failures below the
510,000 byte limit).
Warner Losh [Thu, 11 Aug 2022 15:08:26 +0000 (09:08 -0600)]
stand: userboot_fmtdev can be reduced to devformat
devformat produces the same output as userboot_fmtdev, so just use it to
reduce on the dependencies. In addition, we don't need to use the
incomplete struct userboot_devdesc type, we can use struct devdesc
instead (in fact, there's no userboot_devdesc defined anywhere).
Warner Losh [Thu, 11 Aug 2022 15:07:13 +0000 (09:07 -0600)]
stand: Use devformat instead of disk_devfmt
Use devformat instead of disk_devfmt. This allows us to avoid knowing
the details of the device that's underneath us. Remove disk.h include
and the -I${LDRSRC} from the build of ufs.c since they are no longer
needed.
Warner Losh [Thu, 11 Aug 2022 15:06:53 +0000 (09:06 -0600)]
stand: Use devformat rather than disk_devfmt
Fix layering violation and use devformat to get the string
representation of the device to see if we're mounted yet or not. Remove
added include to pickup disk.h.
Warner Losh [Thu, 11 Aug 2022 15:06:28 +0000 (09:06 -0600)]
stand: Add disk_fmtdev for dv_fmtdev for all the disk devices
All of the archsw fmtdev functions treat DEVT_DISK as a call to
disk_fmtdev. Set all disks' dv_fmtdev to disk_fmtdev so devformat
will return the same thing.
Warner Losh [Thu, 11 Aug 2022 15:05:34 +0000 (09:05 -0600)]
stand: Add dv_devfmt to return a string represenation of the device
Add a new pointer, dv_devfmt, to allow devices to format themselves. We
will use this to simplify many of the fmtdev functions in the tree as
they are all almost the same, or all are isomorphic to each other.
Warner Losh [Thu, 11 Aug 2022 15:04:50 +0000 (09:04 -0600)]
stand: Change disk_fmtdev to take a struct devdesc *
We do a number of games with ploymorphism for different types struct
*devdesc. Adjust one place that this affects to take the address of the
base class (most others have void * at the moment). This is more type
safe than a bare void *.
Warner Losh [Thu, 11 Aug 2022 15:04:08 +0000 (09:04 -0600)]
stand: Move i386_devdesc to a union
Rather than have the magic, hand-crafted fields that have to align with
fields in other structures at the end of i386_devdesc, make it into
anonymous union and adjust the code accordingly. This is safer and
similar to what CAM does.
Warner Losh [Thu, 11 Aug 2022 03:19:01 +0000 (21:19 -0600)]
stand: impose 510,000 byte limit for /boot/loader and /boot/pxeldr
The BIOS method of booting imposes an absolute limit of 640k for the
size of the program being run due to btx. In practice, this means that
programs larger than about 500kiB will fail in odd ways as the stack /
heap will overflow.
Pick 510,000 as the cutoff line semi-arbitrarily. loader_lua is now
almost too big and we want to break the build when it crosses this
threshold. In my experience, below 500,000 always works, above 520,000
always seems to fail with things getting bad somewhere between 512,000
to 515,000. 510,000 is as close to the line as I think we can go, though
experience may dictate we need to lower this in the future.
This is at-best a stop-breakage until we have a better way to subset the
boot loader for BIOS booting to allow better, more fined-tuned
/boot/loaders for the many different environments they have to run
in. This likely means we'll have a graphical loader than understands a
few filesystmes for installation, and a non-graphical loader that
understands the most filesystems possible for everything else in the
future. Our build infrastructure needs some work before we can do that,
however.
At this late date, it likely isn't worth the efforts to move parts of
the loader into high memory. There's a number of assumptions about where
the stack is, where buffers reside, etc that are fulfilled when it lives
in the first 640k that would need bounce buffers and/or other counter
measures if we were to split it up. All BIOS calls are done in 16-bit
mode with SEG:OFF addresses, requiring them to be in the first 640k of
RAM. And nearly all machines in the last decade can boot with UEFI
(though there's some exceptions, so it isn't worth killing outright
yet).
Warner Losh [Thu, 11 Aug 2022 03:18:32 +0000 (21:18 -0600)]
stand: i386/amd64: Always use elf format for /boot/loader and pxeldr
The first level boot blocks have understood how to load ELF code since
1999. Switch /boot/loader and /boot/pxeldr over to being ELF format so
that in-tree tools can examine them more closely. In addition, one
could, in theory, now have a 'lo-mem' and a 'hi-mem' segment (though a
lot of work would need to be done with bounce buffers, btx, code segment
marking, etc for an arrangement like that to work).
As far as I can tell, this is the last a.out binary in the tree. There
are several raw binaries left, but everything else is ELF.
Warner Losh [Wed, 3 Aug 2022 16:50:14 +0000 (10:50 -0600)]
stand: use snprintf here
This code was written prior to snprintf being in the then libstand (now
libsa). Since we have it, use it for extra safety. The code already
tries to be safe, but since we have snprintf as well, the added layer of
protection will suffice. The current code reserves 16 bytes (plus a NUL)
at the end for worst case of inet_ntoa, which is still a little
pessimal, but safe from overflow.
Warner Losh [Sat, 30 Jul 2022 11:01:47 +0000 (05:01 -0600)]
stand: Add a helper 'universe' target
Add a shortcut for invokging ${SRCTOP}/tools/boot/universe.sh by
creating a 'universe' target in src/stand. This will make it easier to
test out all the different combinations of boot loaders that we build.
Warner Losh [Sat, 30 Jul 2022 10:43:21 +0000 (04:43 -0600)]
stand: Move quit command to common commands
Since both EFI and the future kboot will benefit from a 'quit' command,
move it from efi/loader/main.c to common/commands.c. In EFI this command
exits back to the boot loader (which will cause the next BootXXXX in the
BootOrder list to be attempted). In kboot, this will exit back to
whatever called loader.kboot. In uboot this will cause a reset (which
will restart uboot, not quite a simple exit, but will look similar)
and in OFW it will execute OF_exit which should return to the
openfirmware prompt.
Sponsored by: Netflix
[[ tweaked because mips is still in stable/13 leading to conflict ]]
Warner Losh [Tue, 26 Jul 2022 23:39:45 +0000 (17:39 -0600)]
kboot: Make console raw when we start
Put the console into raw mode on startup. This allows the menus to work
as expected. Boot is now interruptable.
Note: Likely should restore the terminal settings on most exists. It's
not clear the best way to do this, and most shells have an auto stty
sane anyway, so note it for future improvement.
Warner Losh [Tue, 26 Jul 2022 23:31:23 +0000 (17:31 -0600)]
kboot: implement stripped down termios
Implement a stripped down termios, obtained from various files in musl
and HOST_ or host_ prepended to most things and a few unavoidable style
tweaks. Only implements the bits of termios we need for the boot loader:
put the terminal into raw mode, restore terminal settings and speed
stuff.