Commit Graph

94 Commits

Author SHA1 Message Date
gonzo
16ac02a4b8 Remove extra 0x before %p format strings introduced by r296182 2016-07-08 22:32:03 +00:00
imp
aec599f958 Fix several instances where the boot loader ignored pager_output
return value when it could return 1 (indicating we should stop).
Fix a few instances of pager_open() / pager_close() not being called.
Actually use these routines for the environment variable printing code
I just committed.
2016-05-18 05:59:05 +00:00
pfg
3a9fc3c9d5 sys/boot: spelling fixes in comments.
No functional change.
2016-04-30 00:26:38 +00:00
gonzo
7f83a48e54 Add FDT overlays support to ubldr
FDT overlays is de-facto standard for describing expansion boards like
Beaglebone capes or Raspberry Pi shields. The ides is to have basic
DTB for base board and overlays DTB for shields/capes and to construct
final DTB either using human-readable configuration or some
self-discovery mechanism. I believe this approach can also be expanded
to support dynamically loadable FPGA bitstreams on systems like
Zedboard/Zybo.

Overlaying process is simmilar to executable link process for
binaries: each DTB has "exported" symbols and "undefined" symbols, the
latter are resolved using information for the former obtained from
base DTB or one of the overlays applied earlier (more rare case).

This symbols information is not generated by standard dtc that FreeBSD
has in base system, patched[1] version required to produces
overlay-compatible blobs. So although DTB files generated by
buildkernel do not support overlays there are enough
vendor/community-provided DTB blobs ciruclating around to justify
committing this change to ubldr.

This commit introduces handler for "fdt_overlays" variable that can be
defined either as a loader env variable or U-Boot env variable.
fdt_overlays is comma-separated list of .dtbo files located in
/boot/dtb/ directory along with base .dtb. ubldr loads files and
applies them one-by-one to base .dtb and then passes result blob to
the kernel.

[1] dd6a0533e8

Differential Revision:	https://reviews.freebsd.org/D3180
2016-04-29 22:42:59 +00:00
pfg
99e9a53c81 sys/boot: use our nitems() macro when it is available through param.h.
No functional change, only trivial cases are done in this sweep,

Discussed in:	freebsd-current
2016-04-19 23:44:33 +00:00
allanjude
2b75f57932 A new implementation of the loader block cache
The block cache implementation in loader has proven to be almost useless, and in worst case even slowing down the disk reads due to insufficient cache size and extra memory copy.
Also the current cache implementation does not cache reads from CDs, or work with zfs built on top of multiple disks.
Instead of an LRU, this code uses a simple hash (O(1) read from cache), and instead of a single global cache, a separate cache per block device.
The cache also implements limited read-ahead to increase performance.
To simplify read ahead management, the read ahead will not wrap over bcache end, so in worst case, single block physical read will be performed to fill the last block in bcache.

Booting from a virtual CD over IPMI:
0ms latency, before: 27 second, after: 7 seconds
60ms latency, before: over 12 minutes, after: under 5 minutes.

Submitted by:	Toomas Soome <tsoome@me.com>
Reviewed by:	delphij (previous version), emaste (previous version)
Relnotes:	yes
Differential Revision:	https://reviews.freebsd.org/D4713
2016-04-18 23:09:22 +00:00
bdrewery
4d90d5a447 Add more .NOMETA missed in r291320
Sponsored by:	EMC / Isilon Storage Division
2016-03-11 23:45:51 +00:00
sgalabov
9a94f84b41 Improve U-Boot API detection
Until now, ubldr has been trying to locate the U-Boot API using a hint
address (U-Boot's current stack pointer), aligning it to 1MiB and going
over a 3MiB (or 1MiB in case of MIPS) memory region searching for a
valid API signature.

This change introduces an alternative way of doing this, namely the
following:
- both U-Boot's bootelf and go commands actually pass argc and argv to
  the entry point (e.g., ubldr's start function, but they should also
  be passed over to main() transparently)
- so, instead of trying to go and look for a valid API signature, we
  look at the parameters passed to main()
- if there's an option '-a' with argument, which is a valid hexadecimal
  unsigned  long number (x), we try to verify whether we have a valid
  API signature at address x. If so - we use it. If not - we fallback
  to the original way of locating the API signature.

The U-Boot change, which causes the API structure address to be
exported as an environment variable, was committed to mainline U-Boot
as commit 22aa61f707574dd569296f521fcfc46a05f51c48

Reviewed by:	andrew, adrian
Approved by:	adrian (mentor)
Sponsored by:	Smartcom - Bulgaria AD
Differential Revision:	https://reviews.freebsd.org/D5492
2016-03-09 11:45:48 +00:00
sgalabov
ac10683bf2 These changes attempt to put things in order before the introduction of MIPS
ubldr.

The changes are mostly dealing with removing unnecessary casts from the U-Boot
API (we're passing only pointers, no obvious reason to cast them to uint32_t),
cleaning up some compiler warnings and using the proper printf format
specifiers in order to be able to compile cleanly for both 32-bit and 64-bit
MIPS targets.

Reviewed by:	imp
Approved by:	adrian (mentor)
Sponsored by:	Smartcom - Bulgaria AD
Differential Revision:	https://reviews.freebsd.org/D5312
2016-02-29 07:27:49 +00:00
sgalabov
4af438ea70 So far bsd.stand.mk wasn't included in the following files:
sys/boot/fdt/Makefile
sys/boot/uboot/fdt/Makefile
sys/boot/uboot/lib/Makefile

This causes compilation issues on MIPS due to trying to link PIC with non-PIC
code. This revision includes bsd.stand.mk in the above files.

Reviewed by:	imp
Approved by:	adrian (mentor)
Sponsored by:	Smartcom - Bulgaria AD
Differential Revision:	https://reviews.freebsd.org/D5311
2016-02-26 08:16:44 +00:00
ian
f52f523099 If the user has set a u-boot env var named rootpath, automatically
import it into the loader(8) env as dhcp.root-path, so that it overrides
any dhcp/bootp server-provided path.

Now if you have a dhcp server available you can easily net-boot a u-boot
system even if you don't control the dhcp server config, by setting just
two variables in the u-boot env:

  loaderdev=net
  rootpath=<nfsserverip>:<pathname>

Previously you had to either accept all the dhcp parameters from the
server without the ability to locally provide the rootpath, or you had
to forego dhcp and set more vars (ipaddr, netmask, serverip, rootpath).
2016-02-22 18:53:55 +00:00
ian
fdc00556f0 Go back to using uintptr_t, because code that actually compiles is
infinitely less buggy than code that is theoretically correct in some
alternate universe.

The uintfptr_t type is apparently a freebsd invention, and exists only when
compiling the kernel.  It's a little hard to say for sure, since it doesn't
seem to be documented anywhere except in email advice to unsuspecting and
overly-trusting souls, who then get to wear the pointy hat for blindly
following advice without investigating or testing it first.
2016-01-13 00:22:12 +00:00
ian
45b3c76b55 Cast using uintfptr_t and eliminate the cast to uint64_t which is uneeded
because rounding down cannot increase the number of bits needed to express
the result.

I had no idea there was such a thing as uintfptr_t.

Requested by: bde
2016-01-12 16:31:07 +00:00
ian
8181b203c9 Cast pointer through uintptr_t on the way to uint64_t to squelch a warning. 2016-01-02 22:55:59 +00:00
ian
68882f22b3 Use 64-bit math when finding a block of ram to hold the kernel. This fixes
a problem on 32-bit systems which have ram occupying the end of the physical
address space -- for example, a block of ram at 0x80000000 with a size of
0x80000000 was overflowing 32 bit math and ending up with a calculated size
of zero.

This is a fix for one of the two problems mentioned in the PR.  Something
similar will need to be done on the kernel side before the PR is closed.

PR:		201614
2016-01-02 18:16:24 +00:00
ian
db61583332 Fix the error checking for the ubenv command. This moves the check for an
empty ldvar (which amounts to the varname string starting with '=') into
the if block that manipulates ldvar, which avoids later referencing ldvar
when it was never initialized.

Submitted by:	Thomas Skibo
Pointy hat:	ian
2015-12-29 21:29:05 +00:00
ian
d831f84b44 Enhance the "ubenv import" command to allow importing a u-boot env var
directly into a loader (and thus kernel) env var, using the syntax

  ubenv import ldvarname=ubvarname

Without the varname= prefix it uses the historical behavior of importing
to the name uboot.ubvarname.
2015-12-14 22:00:46 +00:00
ngie
60eee5fc9f Remove stray unescaped % in Booting from ... informational message
PR: 204944
MFC after: 1 week
X-MFC with: r291164
Reported by: David Binderman <dcb314@hotmail.com>
Sponsored by: EMC / Isilon Storage Division
2015-12-05 23:59:30 +00:00
ian
ab03ed9af1 Print more detailed info about the disk and partition chosen for booting.
No behavioral changes, just cosmetics.

A partition number of zero is not a wildcard, it's the 'a' partition in
a BSD slice, so don't print it as "<auto>".  (Only slices are 1-based,
unit and partition numbers are 0-based and -1 is their wildcard marker.)

Also, after doing all the probing and choosing, print the final result as
"Booting from <disk spec>" where disk spec has all the wildcards resolved
and looks like familiar BSD slice-and-partition notation (disk0s3a, etc).
2015-11-22 20:38:50 +00:00
gonzo
c9ef6a18ea Make dtb file configurable via loader(8) variable. ubldr already checks
"fdt_file" and "fdtfile" U-Boot variables. Add one more check for
"fdt_file" loader(8) variable.

loader(8) variable takes precedence over u-boot env one
2015-08-15 21:47:07 +00:00
sobomax
200a3fb372 Provide bug4bug workaround for certain dumbiness of the u-boot's API_env_enum
function, which is expected to set returned env to NULL upon reaching the end
of the environment list but fails to do so in certain cases. The respective
u-boot code looks like the following (HEAD at the time of this commit):

--- api.c ---
 496 static int API_env_enum(va_list ap)
 ...
 510                 *next = last;
 511
 512                 for (i = 0; env_get_char(i) != '\0'; i = n + 1) {
 513                         for (n = i; env_get_char(n) != '\0'; ++n) {
 514                                 if (n >= CONFIG_ENV_SIZE) {
 515                                         /* XXX shouldn't we set *next = NULL?? */
 516                                         return 0;
 517                                 }
 518                         }
-------------

The net result is that any unfortunate user of the loader's ub_env_enum()
function hitting this condition would be trapped in the infinite loop, as
the main use pattern of ub_env_enum() is basically the following:

while ((env = ub_env_enum(env)) != NULL) { DO STUFF }

Which would stuck forever with the last element.
2015-06-19 22:24:58 +00:00
sobomax
7f024ecfc3 Fix bug in the ubldr introduced in the rev.283035. The new code
fails to properly consider memory regions when the loader is
located below of those regions or engulfs their lower limit. This
results in "not enough RAM to load kernel" panic, which is totally
bogus. On top of that, there are some variables that can be left
unitialized in those cases, which might cause it fail with memory
access violation instead of panic while trying to load kernel to
a wrong or non-existing address of memory.

Augment the code to properly deal with the loader being below or
at the lower bound of the memory region in question. Also, don't
leave ununitialized variables behind.

Reviewed by:	ian
2015-06-19 17:00:36 +00:00
gonzo
0df0890db9 Print error message if autoload fails due to missing DTB blob, otherwise
ubldr just falls back to loader prompt with no apparent reason
2015-05-26 20:32:14 +00:00
ian
bbcb77ec6f Add a routine to obtain netboot parameters from the U-Boot env vars. Call
it from the uboot net_init() implementation.  The routine uses the standard
U-Boot env vars plus a freebsd-specific variable named "rootpath" (the
corresponding u-boot variable for that would be "bootfile" except that it
refers to ubldr, so a new name was needed to communicate the path to ubldr).

This allows ubldr to load a kernel from nfs without requiring a dhcp or
bootp server to provide the server ip and rootpath parameters.
2015-05-18 16:12:41 +00:00
ian
164d3b3865 An ARM kernel can be loaded at any 2MB boundary, make ubldr aware of that.
Previously, ubldr would use the virtual addresses in the elf headers by
masking off the high bits and assuming the result was a physical address
where the kernel should be loaded.  That would sometimes discard
significant bits of the physical address, but the effects of that were
undone by archsw copy code that would find a large block of memory and
apply an offset to the source/dest copy addresses.  The result was that
things were loaded at a different physical address than requested by the
higher code layers, but that worked because other adjustments were applied
later (such as when jumping to the entry point).  Very confusing, and
somewhat fragile.

Now the archsw copy routines are just simple copies, and instead
archsw.arch_loadaddr is implemented to choose a load address.  The new
routine uses some of the code from the old offset-translation routine to
find the largest block of ram, but it excludes ubldr itself from that
range, and also excludes   If ubldr splits the largest block of ram in
two, the kernel is loaded into the bottom of whichever resulting block is
larger.

As part of eliminating ubldr itself from the ram ranges, export the heap
start/end addresses in a pair of new global variables.

This change means that the virtual addresses in the arm kernel elf headers
now have no meaning at all, except for the entry point address.  There is
an implicit assumption that the entry point is in the first text page, and
that the address in the the header can be turned into an offset by masking
it with PAGE_MASK.  In the future we can link all arm kernels at a virtual
address of 0xC0000000 with no need to use any low-order part of the
address to influence where in ram the kernel gets loaded.
2015-05-17 19:59:05 +00:00
ian
2908b1f743 Fix fdt_platform_fixups() mem region handling. It turns out u-boot puts
several types of data into the mem-info array (DRAM, SRAM, flash).  We
need to extract just the DRAM entries for translation into fdt memory
properties.

Also, increase the number of regions we can handle from 5 to 16.

Submitted by:	Michal Meloun
2015-03-17 21:15:24 +00:00
ian
c515629dd9 Allow whitspace to appear between device name and unit number in loaderdev.
This allows the same value to be used in u-boot commands and the loaderdev
env var that gets passed to ubldr, for example 'fatload mmc 1 ${bootfile}".
2014-12-21 17:10:24 +00:00
andrew
2b36711b78 Start to allow platforms other than U-Boot to use the FDT code in loader by
moving U-Boot specific code from libfdt.a to a new libuboot_fdt.a. This
needs to be a new library for linking to work correctly.

Differential Revision:	https://reviews.freebsd.org/D1054
Reviewed by:	ian, rpaulo (earlier version)
MFC after:	1 week
2014-11-01 17:12:44 +00:00
andrew
a15a6f7e40 Move the definitions of the fdt functions from a uboot header to a new fdt
header. There is nothing in the fdt spec that ties it to U-Boot.

While here sort and fix the signature of fdt_setup_fdtp.

MFC after:	1 week
2014-11-01 10:50:18 +00:00
ian
6a8688d5d7 Add a 'ubenv import' command to import environment variables from the
u-boot env into the loader(8) env (which also gets them into the kernel
env).  You can import selected variables or the whole environment.  Each
u-boot var=value becomes uboot.var=value in the loader env.  You can also
use 'ubenv show' to display uboot vars without importing them.
2014-09-08 19:19:10 +00:00
marcel
42335f4752 Give loaders more control over the Forth initialization process. In
particular, allow loaders to define the name of the RC script the
interpreter needs to use. Use this new-found control to have the
PXE loader (when compiled with TFTP support and not NFS support)
read from ${bootfile}.4th, where ${bootfile} is the name of the
file fetched by the PXE firmware.

The normal startup process involves reading the following files:
1.  /boot/boot.4th
2.  /boot/loader.rc or alternatively /boot/boot.conf

When these come from a FreeBSD-defined file system, this is all
good. But when we boot over the network, subdirectories and fixed
file names are often painful to administrators and there's really
no way for them to change the behaviour of the loader.

Obtained from:	Juniper Networks, Inc.
2014-07-27 16:12:51 +00:00
imp
2118f42afd Use src.opts.mk in preference to bsd.own.mk except where we need stuff
from the latter.
2014-05-06 04:22:01 +00:00
ian
dcb2ac3517 Cosmetic changes to printed output, mostly related to probing devices...
- Display slice and partition as <auto> instead of 0 or -1 when they're
   not set to specific values (the paritition=-1 was confusing folks).
 - When loaderdev isn't set in the u-boot environment, say so rather
   than displaying unknown device ''.
 - Print the loader(8) ident/version info earlier, so that all device-
   related info appears together afterwards.

The one change here that isn't purely cosmetic is to call setheap()
earlier.  The comment says "Initialise heap as early as possible", now
that's more accurate.  It shouldn't make any functional difference, but
may be safer if future changes lead to trying to allocate memory earlier.
2014-03-17 16:10:42 +00:00
ian
f5f6c3f801 Fix the paren nesting so that the network device is probed if the load
device type is either network or wildcard.
2014-03-17 13:54:53 +00:00
ian
7db44467a1 Fix an uninitialized variable error I perpetrated when splitting some
code into a separate function.  Pass the missing value from main() to
the probe_disks() function.
2014-03-14 00:49:02 +00:00
ian
b434f4f57d Enhance the mechanism that lets you configure the ubldr boot device by
setting the u-boot environment variable loaderdev=.  It used to accept only
'disk' or 'net'.  Now it allows specification of unit, slice, and partition
as well.  In addition to the generic 'disk' it also accepts specific
storage device types such as 'mmc' or 'sata'.

If there isn't a loaderdev env var, the historical behavior is maintained.
It will use the first storage device it finds, or a network device if
no working storage device exists.

99% of the work on this was done by Patrick Kelsey, but I made some
changes, so if anything goes wrong, blame me.

Submitted by:	Patrick Kelsey <kelsey@ieee.org>
2014-03-11 22:02:49 +00:00
royger
b13d7383ff howto_names: unify declaration
Approved by: gibbs
Sponsored by: Citrix Systems R&D

boot/i386/efi/bootinfo.c:
boot/i386/libi386/bootinfo.c:
boot/ia64/common/bootinfo.c:
boot/powerpc/ofw/metadata.c:
boot/powerpc/ps3/metadata.c:
boot/sparc64/loader/metadata.c:
boot/uboot/common/metadata.c:
boot/userboot/userboot/bootinfo.c:
i386/xen/xen_machdep.c:
 - Include sys/boot.h
 - Remove custom definition of howto_names.

sys/boot.h:
 - Define howto_names.

x86/xen/pv.c:
 - Include sys/boot.h
2014-03-11 10:13:06 +00:00
ian
934db1dbcf Include needed header. I don't know why clang didn't complain about this
but gcc sure did.
2014-03-02 17:19:19 +00:00
ian
e6899fc0bf If we can't find the u-boot api signature, exit with an error status that
includes "badab1"; u-boot displays the status in hex, so this may help
give some clue about why ubldr isn't working (more than -1 does anyway).
2014-03-01 19:25:23 +00:00
ian
3cccc93a26 Prevent fdt data loaded from a file from overwriting the kernel environment,
by having uboot_autoload() do the fdt setup (which may load a file) rather
than waiting until we're actually in the process of launching the kernel.

As part of making this happen...
 - Define LOADER_FDT_SUPPORT on the uboot/lib compile command line when
   MK_FDT is set.
 - Make fdt_setup_fdtb() public.
 - Declare public fdt_whatever() functions in a header instead of using
   scattered extern decls in .c files.
2014-03-01 19:02:00 +00:00
ian
fa9fabc566 Allow the ubldr boot device to be choosen by a u-boot environment variable.
If a "loaderdev=<device>" env variable is set and the named device
exists, it is used.  If the device doesn't exist, fall back to the
historic "probe" loop that prefers disk devices over network devices.

If the env var is not set, preserve the historic behavior of using the
first working disk device provided by u-boot, or a network device if no
functional disk device is found and a network device exists.

The old probe loop is reworked so that it checks all bootable devices
provided by u-boot rather than taking an early-out on the first device
found.  This results in the cosmetic change of listing all potential boot
devices for the user, but the behavior of which device it chooses is the
same as it has always been.
2014-02-22 17:51:10 +00:00
loos
b13dfd5919 Remove all the instances of '#undef DEBUG' from kernel.
Suggested by:	rpaulo
Approved by:	adrian (mentor)
2013-10-25 18:38:44 +00:00
kientzle
8321b23854 Print kernel args as late as possible before jumping into kernel. 2013-02-23 20:27:03 +00:00
kientzle
dad21c930a Clarify an error message. The addresses here are
really offsets within the primary mapped memory block
(which may not start at address zero).
2013-02-18 20:11:20 +00:00
ian
2d2ebd5bc0 Do metadata relocation fixup on all loaded modules, not just the kernel.
Approved by:	cognet (mentor)
2013-01-30 23:49:36 +00:00
gonzo
e9a6dd0099 - Implement "fdt mres" sub-command that prints reserved memory regions
- Add "fdt addr" subcommand that lets you specify preloaded blob address
- Do not pre-initialize blob for "fdt addr"
- Do not try to load dtb every time fdt subcommand is issued,
    do it only once
- Change the way DTB is passed to kernel. With introduction of "fdt addr"
    actual blob address can be not virtual but physical or reside in
    area higher then 64Mb. ubldr should create copy of it in kernel area
    and pass pointer to this newly allocated buffer which is guaranteed to work
    in kernel after switching on MMU.
- Convert memreserv FDT info to "memreserv" property of root node
    FDT uses /memreserve/ data to notify OS about reserved memory areas.
    Technically it's not real property, it's just data blob, sequence
    of <start, size> pairs where both start and size are 64-bit integers.
    It doesn't fit nicely with OF API we use in kernel, so in order to unify
    thing ubldr converts this data to "memreserve" property using the same
    format for addresses and sizes as /memory node.
2012-11-30 03:15:50 +00:00
kientzle
f9c87e23be Print kernel args when booting the kernel. 2012-11-25 18:22:53 +00:00
ae
2ad040bf3f Add the flags parameter to the disk_open() function and DISK_F_NOCACHE
flag, that disables the caching of partition tables metadata.
Use this flag for floppies in the libi386/biosdisk driver.
2012-10-21 12:14:58 +00:00
ae
75dfd50beb Almost each time when loader opens a file, this leads to calling
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.
2012-09-29 16:47:56 +00:00
ae
f7c40e7e08 Update according to the change of struct uboot_devdesc. 2012-09-09 11:37:17 +00:00