the PowerPC port with all the Open Firmware bits removed and replaced by
their EFI counterparts. On the whole, I think I prefer Open Firmware.
This code is supposed to be an immutable shim that sits on the EFI system
partition, loads /boot/loader.efi from UFS and tells the real loader what
disk/partition to look at. It finds the UFS root partition by the somewhat
braindead approach of picking the first UFS partition it can find. Better
approaches are called for, but this works for now. This shim loader will
also be useful for secure boot in the future, which will require some
rearchitecture.
when MBR contains only PMBR entry or it is bootcamp-compatible.
If MBR has PMBR entry and some other, the loader rejects it.
Make these checks to be less strict. If loader decided that PMBR
isn't suitable for GPT, it will use MBR.
Reported by: Paul Thornton
Tested by: Paul Thornton
MFC after: 1 week
fragments; while this won't actually be used for anything (yet), it
doesn't hurt to ensure it is exposed to the tinderbox.
Requested by: imp, jmallett
MFC after: 3 weeks
arguments from type,filename to filename,type to be consistant with other
public file_whatever() functions, and change it to return a pointer to
the preloaded_file struct describing the file. Adjust existing callers.
- Similar to the hack for bootinfo32.c in userboot, define
_MACHINE_ELF_WANT_32BIT in the load_elf32 file handlers in userboot.
This allows userboot to load 32-bit kernels and modules.
- Copy the SMAP generation code out of bootinfo64.c and into its own
file so it can be shared with bootinfo32.c to pass an SMAP to the i386
kernel.
- Use uint32_t instead of u_long when aligning module metadata in
bootinfo32.c in userboot, as otherwise the metadata used 64-bit
alignment which corrupted the layout.
- Populate the basemem and extmem members of the bootinfo struct passed
to 32-bit kernels.
- Fix the 32-bit stack in userboot to start at the top of the stack
instead of the bottom so that there is room to grow before the
kernel switches to its own stack.
- Push a fake return address onto the 32-bit stack in addition to the
arguments normally passed to exec() in the loader. This return
address is needed to convince recover_bootinfo() in the 32-bit
locore code that it is being invoked from a "new" boot block.
- Add a routine to libvmmapi to setup a 32-bit flat mode register state
including a GDT and TSS that is able to start the i386 kernel and
update bhyveload to use it when booting an i386 kernel.
- Use the guest register state to determine the CPU's current instruction
mode (32-bit vs 64-bit) and paging mode (flat, 32-bit, PAE, or long
mode) in the instruction emulation code. Update the gla2gpa() routine
used when fetching instructions to handle flat mode, 32-bit paging, and
PAE paging in addition to long mode paging. Don't look for a REX
prefix when the CPU is in 32-bit mode, and use the detected mode to
enable the existing 32-bit mode code when decoding the mod r/m byte.
Reviewed by: grehan, neel
MFC after: 1 month
they can easily be used by later post-processing. When searching for
a compiled-in fdt blob, use the section headers to get the size and
location of the .dynsym section to do a symbol search.
This fixes a problem where the search could overshoot the symbol
table and wander into the string table. Sometimes that was harmless
and sometimes it lead to spurious panic messages about an offset
bigger than the module size.
elf headers, mask out the high nibble of that address. This effectly makes
the entry point the offset from the load address, and it gets adjusted for
the actual load address before jumping to it.
Masking the high nibble makes assumptions about memory layout that are true
for all the arm platforms we support right now, but it makes me uneasy.
This needs to be revisited.
After digging through more carefully, it looks like there's
no real need to have the DTB in the module directory.
So we can simplify a lot: Just copy DTB into local heap
for "fdt addr" and U-Boot integration, drop all the extra
COPYIN() calls.
I've left one final COPYIN() to update the in-kernel DTB
for consistency with how this code used to work, but I'm
no longer convinced it's appropriate here.
I've also remove the mem_load_raw() utility that I added
to boot/common/module.c with r247045 since it's no longer
necessary.
This will be used by some upcoming changes to loader(8) FDT
handling to allow it to use an FDT provided by an earlier
boot stage the same as an FDT loaded from disk.
r238966
Bump up the heap size to 1MB. With a few kernel modules, libstand
zalloc and userboot seem to want to use ~600KB of heap space, which
results in a segfault when malloc fails in bhyveload.
r241180
Clarify comment about default number of FICL dictionary cells.
r241153
Allow the number of FICL dictionary cells to be overridden.
Loading a 7.3 ISO with userboot/amd64 takes up 10035 cells,
overflowing the long-standing default of 10000.
Bump userboot's value up to 15000 cells.
Reviewed by: dteske (r238966,241180)
Obtained from: NetApp
command execution. In case of such unhandled exception, vmReset() inside
ficlExecC() flushes the VM state. Attempt to return back to Forth after
that cause garbage dereference with unexpected results. To avoid that
situation call vmThrow() directly instead of expecting Forth to do it.
- clarify meaning of console flags
- perform i/o via a console only if both of the following conditions are met:
o console is active (selected by user or config)
o console flags that it can perform the operation
- warn if a chosen console can not work (the warning may go nowhere without
working and active console, though)
Reviewed by: jhb
Tested by: Uffe Jakobsen <uffe@uffe.org>,
Olivier Cochard-Labbe' <olivier@cochard.me>
MFC after: 26 days
disk_open(). Very often this is called several times for one file.
This leads to reading partition table metadata for each call. To
reduce the number of disk I/O we have a simple block cache, but it
is very dumb and more than half of I/O operations related to reading
metadata, misses this cache.
Introduce new cache layer to resolve this problem. It is independent
and doesn't need initialization like bcache, and will work by default
for all loaders which use the new DISK API. A successful disk_open()
call to each new disk or partition produces new entry in the cache.
Even more, when disk was already open, now opening of any nested
partitions does not require reading top level partition table.
So, if without this cache, partition table metadata was read around
20-50 times during boot, now it reads only once. This affects the booting
from GPT and MBR from the UFS.
number is not exactly specified. When the disk has MBR, also try to read
BSD label after ptable_getpart() call. When the disk has GPT, also set
d_partition to 255. Mostly, this is how it worked before.
When we open the disk, check the type of partition table, that has
been detected. If this is BSD label, then we assume this is DD mode.
Reported by: dim@
It uses new API from the part.c to work with partition tables.
Update userboot's disk driver to use new API. Note that struct
loader_callbacks_v1 has changed.
This way with the new zfsloader there is no need to explicitly set zfs
root filesystem either via vfs.root.mountfrom or fstab.
It should be automatically picked up from currdev which is by default
is set from bootfs.
Tested by: Florian Wagner <florian@wagner-flo.net> (x86)
MFC after: 1 month
In zfs loader zfs device name format now is "zfs:pool/fs",
fully qualified file path is "zfs:pool/fs:/path/to/file"
loader allows accessing files from various pools and filesystems as well
as changing currdev to a different pool/filesystem.
zfsboot accepts kernel/loader name in a format pool:fs:path/to/file or,
as before, pool:path/to/file; in the latter case a default filesystem
is used (pool root or bootfs). zfsboot passes guids of the selected
pool and dataset to zfsloader to be used as its defaults.
zfs support should be architecture independent and is provided
in a separate library, but architectures wishing to use this zfs support
still have to provide some glue code and their devdesc should be
compatible with zfs_devdesc.
arch_zfs_probe method is used to discover all disk devices that may
be part of ZFS pool(s).
libi386 unconditionally includes zfs support, but some zfs-specific
functions are stubbed out as weak symbols. The strong definitions
are provided in libzfsboot.
This change mean that the size of i386_devspec becomes larger
to match zfs_devspec.
Backward-compatibility shims are provided for recently added sparc64
zfs boot support. Currently that architecture still works the old
way and does not support the new features.
TODO:
- clear up pool root filesystem vs pool bootfs filesystem distinction
- update sparc64 support
- set vfs.root.mountfrom based on currdev (for zfs)
Mid-future TODO:
- loader sub-menu for selecting alternative boot environment
Distant future TODO:
- support accessing snapshots, using a snapshot as readonly root
Reviewed by: marius (sparc64),
Gavin Mu <gavin.mu@gmail.com> (sparc64)
Tested by: Florian Wagner <florian@wagner-flo.net> (x86),
marius (sparc64)
No objections: fs@, hackers@
MFC after: 1 month
table aren't valid. If they are ok, use hdr_lba_alt value to read backup
header. This will make gptboot happy when GPT used atop of some GEOM
provider, e.g. GEOM_MIRROR.
Reviewed by: pjd
MFC after: 2 weeks
quantum bytewise to the address of a 64-bit variable results in writing
to the "wrong" 32-bit half so adjust the address accordingly. This fix
is implemented in a hackish way for two reasons:
o in order to be able to get it into 8.3 with zero impact on the little-
endian architectures where this bug has no effect and
o to avoid blowing the x86 boot2 out of the water again when compiling
it with clang, which all sane versions of this fix tested do.
This change fixes booting from UFS1 file systems on big-endian machines.
MFC after: 3 days
The index() and rindex() functions were marked LEGACY in the 2001
revision of POSIX and were subsequently removed from the 2008 revision.
The strchr() and strrchr() functions are part of the C standard.
This makes the source code a lot more consistent, as most of these C
files also call into other str*() routines. In fact, about a dozen
already perform strchr() calls.
In an example of boot command:
- rename wd(4) IDE disk drives name to ad(4) for the time being.
- update the used kernel path "/kernel" to the current default.
[It still worked occasionally by looking into the /boot/kernel directory,
so the resulting path was "/boot//kernel/kernel", with two slashes.]
Bump .Dd for this and previous changes.
MFC after: 1 week
large (>= 10^10) numbers. In theory, 20 characaters should be enough,
but bump the buffer to 32 characters, so we have some room for the
future.
Reviewed by: pjd
Approved by: re (kib)
bogusly casts its contents around causing alignment faults on sparc64 and
most likely also on at least powerpc. Fix this by copying the contents
bytewise instead as partly already done here. Solving this the right way
costs some space, i.e. 148 bytes with GCC and 16 bytes with clang on x86
there are still some bytes left there though, and an acceptable hack which
tricks the compiler into only using a 2-byte alignment instead of the native
one when accessing the contents turned out to even take up more space that.
Some of loader filesystems are very ill equipped to handle seeking
backwards within the file. Namely, tftp requires trasfer to be
restarted from the start of the file every time we go backwards.
Discussed on hackers and recommended for inclusion into 9.0 at the devsummit.
All support email to devin dteske at vicor dot ignoreme dot com .
Submitted by: dteske at vicor dot ignoreme dot com
Reviewed by: me and many others
Some files keep the SUN4V tags as a code reference, for the future,
if any rewamped sun4v support wants to be added again.
Reviewed by: marius
Tested by: sbruno
Approved by: re
to the l_load() method in the file_formats structure, while being passed
an address as an argument (dest). With file_load() calling arch_loadaddr()
now, this bug is a little bit more significant.
Spotted by: nyan@ (nice catch!)
1. arch_loadaddr - used by platform code to adjust the address at which
the object gets loaded. Implement PC98 using this new interface instead
of using conditional compilation. For ELF objects the ELF header is
passed as the data pointer. For raw files it's the filename. Note that
ELF objects are first considered as raw files.
2. arch_loadseg - used by platform code to keep track of actual segments,
so that (instruction) caches can be flushed or translations can be
created. Both the ELF header as well as the program header are passed
to allow platform code to treat the kernel proper differently from any
additional modules and to have all the relevant details of the loaded
segment (e.g. protection).
Add support for Pre-Boot Virtual Memory (PBVM) to the loader.
PBVM allows us to link the kernel at a fixed virtual address without
having to make any assumptions about the physical memory layout. On
the SGI Altix 350 for example, there's no usuable physical memory
below 192GB. Also, the PBVM allows us to control better where we're
going to physically load the kernel and its modules so that we can
make sure we load the kernel in memory that's close to the BSP.
The PBVM is managed by a simple page table. The minimum size of the
page table is 4KB (EFI page size) and the maximum is currently set
to 1MB. A page in the PBVM is 64KB, as that's the maximum alignment
one can specify in a linker script. The bottom line is that PBVM is
between 64KB and 8GB in size.
The loader maps the PBVM page table at a fixed virtual address and
using a single translations. The PBVM itself is also mapped using a
single translation for a maximum of 32MB.
While here, increase the heap in the EFI loader from 512KB to 2MB
and set the stage for supporting relocatable modules.
o bunch of variables are turned into uint8_t
o initial setting of namep[] in lookup() is removed
as it's only overwritten a few lines down
o kname is explicitly initialized in main() as BSS
in boot2 is not zeroed
o the setting and reading of "fmt" in load() is removed
o buf in printf() is made static to save space
Reviewed by: jhb
Tested by: me and Fabian Keil <freebsd-listen fabiankeil de>
little further. This gets us further on the way to be able to build it
successfully with clang. Using in-tree gcc, this shrinks boot2.bin with
60 bytes, the in-tree clang shaves off 72 bytes, and ToT clang 84 bytes.
Submitted by: rdivacky
Reviewed by: imp
clean up most layering violations:
sys/boot/i386/common/rbx.h:
RBX_* defines
OPT_SET()
OPT_CHECK()
sys/boot/common/util.[ch]:
memcpy()
memset()
memcmp()
bcpy()
bzero()
bcmp()
strcmp()
strncmp() [new]
strcpy()
strcat()
strchr()
strlen()
printf()
sys/boot/i386/common/cons.[ch]:
ioctrl
putc()
xputc()
putchar()
getc()
xgetc()
keyhit() [now takes number of seconds as an argument]
getstr()
sys/boot/i386/common/drv.[ch]:
struct dsk
drvread()
drvwrite() [new]
drvsize() [new]
sys/boot/common/crc32.[ch] [new]
sys/boot/common/gpt.[ch] [new]
- Teach gptboot and gptzfsboot about new files. I haven't touched the
rest, but there is still a lot of code duplication to be removed.
- Implement full GPT support. Currently we just read primary header and
partition table and don't care about checksums, etc. After this change we
verify checksums of primary header and primary partition table and if
there is a problem we fall back to backup header and backup partition
table.
- Clean up most messages to use prefix of boot program, so in case of an
error we know where the error comes from, eg.:
gptboot: unable to read primary GPT header
- If we can't boot, print boot prompt only once and not every five
seconds.
- Honour newly added GPT attributes:
bootme - this is bootable partition
bootonce - try to boot from this partition only once
bootfailed - we failed to boot from this partition
- Change boot order of gptboot to the following:
1. Try to boot from all the partitions that have both 'bootme'
and 'bootonce' attributes one by one.
2. Try to boot from all the partitions that have only 'bootme'
attribute one by one.
3. If there are no partitions with 'bootme' attribute, boot from
the first UFS partition.
- The 'bootonce' functionality is implemented in the following way:
1. Walk through all the partitions and when 'bootonce'
attribute is found without 'bootme' attribute, remove
'bootonce' attribute and set 'bootfailed' attribute.
'bootonce' attribute alone means that we tried to boot from
this partition, but boot failed after leaving gptboot and
machine was restarted.
2. Find partition with both 'bootme' and 'bootonce' attributes.
3. Remove 'bootme' attribute.
4. Try to execute /boot/loader or /boot/kernel/kernel from that
partition. If succeeded we stop here.
5. If execution failed, remove 'bootonce' and set 'bootfailed'.
6. Go to 2.
If whole boot succeeded there is new /etc/rc.d/gptboot script coming
that will log all partitions that we failed to boot from (the ones with
'bootfailed' attribute) and will remove this attribute. It will also
find partition with 'bootonce' attribute - this is the partition we
booted from successfully. The script will log success and remove the
attribute.
All the GPT updates we do here goes to both primary and backup GPT if
they are valid. We don't touch headers or partition tables when
checksum doesn't match.
Reviewed by: arch (Message-ID: <20100917234542.GE1902@garage.freebsd.pl>)
Obtained from: Wheel Systems Sp. z o.o. http://www.wheelsystems.com
MFC after: 2 weeks
Clang to compile this file: it was using the builtin memcpy and we want
to use the memcpy defined in gptboot.c. (Clang can't compile boot2 yet).
Submitted by: Dimitry Andric <dimitry at andric.com>
Reviewed by: jhb
Current code doesn't check size of elf sections and may perform needless
actions of zero-sized memory allocation and similar.
The bigger issue is that alignment requirement of a zero-sized section
gets effectively applied to the next section if it has smaller alignment
requirement. But other tools, like gdb and consequently kgdb,
completely ignore zero-sized sections and thus may map symbols to
addresses differently.
Zero-sized sections are not typical in general.
Their typical (only, even) cause in FreeBSD modules is inline assembly that
creates custom sections which is found in pcpu.h and vnet.h. Mere inclusion
of one of those header files produces a custom section in elf output.
If there is no actual use for the section in a given module, then the
section remains empty.
Better solution is to avoid creating zero-sized sections altogether,
which is in plans.
Preloaded modules are handled in boot code (load_elf_obj.c), while
dynamically loaded modules are handled by kernel (link_elf_obj.c).
Based on code by: np
MFC after: 3 weeks
as this only allows us to access file systems that EFI knows about.
With a loader that can only use EFI-supported file systems, we're
forced to put /boot on the EFI system partition. This is suboptimal
in the following ways:
1. With /boot a symlink to /efi/boot, mergemaster complains about
the mismatch and there's no quick solution.
2. The EFI loader can only boot a single version of FreeBSD. There's
no way to install multiple versions of FreeBSD and select one
at the loader prompt.
3. ZFS maintains /boot/zfs/zpool.cache and with /boot a symlink we
end up with the file on a MSDOS file system. ZFS does not have
proper handling of file systems that are under Giant.
Implement a disk device based on the block I/O protocol instead and
pull in file system code from libstand. The disk devices are really
the partitions that EFI knows about.
This change is backward compatible.
MFC after: 1 week
by keeping it opened after the first open and closing it via the
cleanup handler when NETIF_OPEN_CLOSE_ONCE is defined in order to
avoid the open-close-dance on every file access which with firmware
that for example performs an auto-negotiation on every open causes
netbooting to take horribly long. Basically the behavior with this
knob enabled resembles the one employed between r60506 and r177108
(and for sparc64 also again since r182919) with the addition that
the network device now is closed eventually before entering the
kernel and before rebooting. Actually I think this should be the
desired MI behavior, however the U-Boot loader actually requires
net_close() to be called after every transaction in order for some
local shutdown operations to be performed (and which I think thus
will break on concurrent opens, i.e. when netdev_opens is > 1, like
the loader does at least for disks when LOADER_GZIP_SUPPORT is
enabled).
- Use NETIF_OPEN_CLOSE_ONCE to replace the hack, which artificially
increased netdev_opens for sparc64 in order to keep the network
device opened forever, as at least some firmware versions require
the network device to be closed eventually before entering the
kernel or otherwise will DMA received packets to stale memory.
The powerpc OFW loader probably wants NETIF_OPEN_CLOSE_ONCE to be
set as well for the same reasons.