[U-Boot] Unified u-boot feature set for simpler distro support

Dennis Gilmore dennis at ausil.us
Mon Aug 5 21:50:59 CEST 2013


On Mon, 05 Aug 2013 12:39:03 -0600
Stephen Warren <swarren at wwwdotorg.org> wrote:

> On 08/03/2013 01:11 AM, Dennis Gilmore wrote:
> > Hi all,
> > 
> > I wanted to start a discussion on defining a unified feature set
> > that makes it simpler for the different distros to support ARM
> > systems using u-boot. I have based a lot of my thoughts on how
> > calxeda ship their systems configured as it works fairly well,
> > recently i sent in a patch implementing most of what I would like
> > to see for the wandboard[1]
> > 
> > right or wrong we want things to be simple for the user and to
> > largely look like a linux system on x86 would. The user and distro
> > should never need to worry about memory locations 
> 
> I agree. I'd certainly like to see various distros have regular
> "PC-style" installers for Tegra boards.
> 
> I have attempted to write the "bootcmd" in upstream U-Boot for Tegra
> devices in a way that helps this. More on that below.
> 
> > so this would mean similar partitioning. i.e. /boot on ext4 root and
> > swap  on lvm or as raw partitions. people should be able to have
> > just / on ext4 also. Down the road xfs /boot support would be a
> > nice to have.
> 
> That's only partially relevant for U-Boot. Two things U-Boot needs to
> support:
> 
> * Filesystem read for whatever filesystem /boot is part of (it could
> very well be the / filesystem too, but U-Boot doesn't care, except
> for / vs. /boot in path names). This is a matter of adding the right
> flags to each board's U-Boot config file.

right, but at the least it needs to be ext4 not all boards today read
ext4, btrfs may be something down the road also. u-boot doesnt need to
care too much. it just needs to look in / and /boot 

> * Some way of determining which partition it should load things from.
> 
> For this point, I'd suggest MBR's bootable flag, or GPT's similar
> flags. I always intended to implement a sub-command of U-Boot's
> "part" command that read the partition flags and picked the correct
> partition to use based on those flags...
> 
> The rest of the stuff (swap, LVM, ...) seems entirely related to the
> distro itself and/or whatever gets put into the initrd.
Mostly i was trying to show that where the other bits live doesn't
matter.

> > bootz and raw initrd support. not having to wrap kernels and initrds
> > really is a must. raw initrd support means that its much simpler
> > for a user to rebuild an initramfs if needed and bootz means we do
> > not need to worry about making sure that we specify the correct
> > addresses to load the kernel to when calling mkimage.
> 
> +1 from me.
> 
> > when it comes to memory addressing a distro and user shouldn't need
> > to know anything. Ideally u-boot will auto allocate addresses based
> > on the size of loaded objects. starting with a base address
> > internal to u-boot you load a kernel, when loading an initramfs
> > u-boot automatically calculates an address that ensures it does not
> > overlap with the kernel. same for a fdt if loaded. I say auto
> > calculated because what we think today will be enough room may not
> > be tomorrow, dynamically calculating gives the flexibility for
> > whatever may come.
> 
> The way I've approached this for Tegra is to have the default
> environment define certain standard environment variables that U-Boot
> scripts can use, without a care. For example, the kernel should be
> loaded at ${kernel_addr_r}, initrd at ${ramdisk_addr_r}, DTB at
> ${fdt_addr_r}, etc.
I really don't want to need to deal with variable names either. I
really want to just say load a kernel initramfs and here is some
arguments and have the rest just work.

> I chose the values of those variables in the Tegra environment to
> support reasonable max sizes. The kernel itself has a max size based
> on practicality and the ARM ISA and jump range. There's no reason the
> compressed kernel should be larger than the uncompressed kernel, etc.
another perfectly valid way to do it. a initramfs should be able to be
non existant or 200mb big and just work. I suggested dynamically
allocated solely because something we consider outrageous today may be
necessary tomorrow.

> > fdt will be automatically loaded and provided fedora ships dtbs
> > in /boot/dtb-<kernelver>/ I am not sure where other distros provide
> > them, however u-boot should automatically load dtb and provide
> > access to a fdt in a ${fdt_addr} variable that can be used by
> > pxe_cmd but still allows the user to specify their own in
> > extlinux.conf if desired. ideally the devicetree files need to be
> > decoupled from the kernel, along the lines of what is being
> > discussed in the kernel now[2]. Distros should agree on a single
> > location for the dtbs to be placed. /boot/dtb/ or /boot/dtbs/ are
> > probably good locations. u-boot can then look in the path with and
> > without /boot
> 
> The model I chose on Tegra is slightly different.
> 
> For credit, I was heavily inspired by the default bootcmd from
> downstream TrimSlice U-Boot and I think also the upstream Calxeda
> U-Boot.
> 
> Tegra's U-Boot searches all known boot devices for /boot/boot.scr (and
> some other filenames), sets up some variables to record where it was
> found, loads the file into RAM, and treats that as a U-Boot script.
> The boot script then determines everything else that happens at boot;
> loading the kernel/initrd/DTB, and booting it.
> 
> This lets boot.scr control e.g.:
While i think its a noble goal I really don't think that boot.scr is
really very suitable for distros. I do not know of a great  way to
setup menus its why i want to use the sysboot command provided by pxe
boot and load a extlinux style config file. uboot handles all the
details of the devices and memory locations behind the scenes. users
get confused anytime they need to run mkimage. I really want to take it
out of the equation.

> * Whether the distro wraps zImage into a uImage or not, since the
> distro-supplied script determines whether bootz or bootm is executed.
> 
> * Whether the distro has an initrd or not (I currently don't use one
> typically).
> 
> * The filename of the initrd and DTB, since the location/name/... of
> these is probably somewhat distro-specific.

I think that distros should be able to agree on a common location.
names are defined upstream. omap has a quite nice way to work out the
filename of the dtb you just need to know/workout where to load it.

> * Whatever extra kernel command-line parameters the distro cares to
> pass to the kernel, without having to add them to the U-Boot
> environment, but rather just to boot.scr, which is a much more
> accessible file in a regular file-system.
>
> In other words, I've tried to define a "boot interface" between U-Boot
> and the distro (which is to simply load/execute boot.scr, and provide
> some data to boot.scr in environment variables), rather than making
> U-Boot have complete knowledge of how to boot the distro.
> 
> Also, I have set up all boards so that they define standard U-Boot
> environment variables ${soc}, ${board} that define which HW the code
> is running on. This can be used to automatically construct the DTB
> filename, and hence makes boot.scr pretty much HW-agnostic.
> 
> An example boot.scr that I use is shown below, with some extra
> comments for the purposes of this email:
> 
> ==========
> # I anticipate replacing this hard-coded assignment with e.g.:
> # part find-bootable ${devtype} ${devnum} rootpart
> setenv rootpart 1
> 
> # Find partition UUID (not fs UUID) at run-time, so script adapts to
> # whatever is there without regenerating it
> part uuid ${devtype} ${devnum}:${rootpart} uuid
> 
> # Here is the use of ${uuid} from aboe
> # bootargs_extra allows the user to interrupt boot and add to the
> # kernel command-line
> setenv bootargs ... root=PARTUUID=${uuid} ${bootargs_extra}
> 
> # You could load a "uEnv.txt" here too, which could set some variables
> # that e.g. get added to bootargs etc., if you want plain-text disk-
> # based configuration of this boot script.
> 
> # Complete generic...
> load ${devtype} ${devnum}:${rootpart} ${kernel_addr_r} /boot/zImage
> 
> load ${devtype} ${devnum}:${rootpart}
> ${ramdisk_addr_r} /boot/initrd.gz # So that we don't need to
> regenerate script when initrd size changes
> ramdisk=${ramdisk_addr_r}:0x${filesize} # :-(
> setenv initrd_high 0xffffffff
> 
> load ${devtype} ${devnum}:${rootpart} ${fdt_addr_r} \
> 	/boot/${soc}-${board}.dtb
> 
> bootz ${kernel_addr_r} ${ramdisk} ${fdt_addr_r}
> ==========
While this is a step forward, its still much more than we need to do
if we enable pxe support and use sysboot to load a config file the
says load this kernel and initramfs and pass these bootargs. My
initial post had a fully working example.
 
> For specifics in the code, see the definition of
> CONFIG_EXTRA_ENV_SETTINGS in U-Boot's
> include/configs/tegra-common-post.h, and work backwards from there.
> 
> Note that I'm also in the process of pushing a project to github that
> creates a few boot.scr that fit into this model. I've written the
> code, and hope to have IP approval to upload it very soon. Aside from
> the example above, it also supports netboot, initrd being optional,
> hard-coding various extra stuff into bootargs, etc.
> 
> You can also see some hard-coded boot scripts that I hope to get added
> to the Ubuntu installer image generator at:
> 
> https://code.launchpad.net/~srwarren/debian-installer/tegra/+merge/175967
> 
> (I'd love to have similar support added to other distros; I just had
> to pick one to work on first)
It is not likely to get into fedora's installer. we currently have
extlinux support which is really simple and arm-boot-config at:
https://git.fedorahosted.org/cgit/arm-boot-config.git
its a mostrosity of hush scripting to enable menus and configuration
options. but it does require board specific knowledge to enable support
for new systems. but i definetly want to enable people to use boot.scr
if they choose to

> > What this gets us in the end is that with a unified kernel, device
> > tree and u-boot implementing the system specific knowledge,
> > supporting new ARM systems is along the same lines as supporting
> > new x86 systems. Get the drivers and platform support in the
> > mainline kernel and as long as the Distro enables it it will just
> > work in the next OS release. The one part then that we as Distro's
> > need to do is to ensure we install u-boot into the disk correctly
> > for the board in question if it is a system that does not ship with
> > some kind of storage for u-boot. If it is a system with NOR, Nand,
> > SPI storage for u-boot it is then entirely in the vendors hand, and
> > assuming that they implement everything, all distros will be able
> > to simply support them. Giving users and vendors more choice in
> > what to run on their hardware.
> 
> At least for Tegra, the U-Boot binary won't (ever?) be part of the
> file-system, but is rather always somewhere dedicated (eMMC boot
> sectors rather than the main user area, SPI, or NAND for example). As
> such, the model I'd like to push for Tegra is that you use
> HW-specific tools to install U-Boot, then use a distro installer SD
> card, USB device, or even CD-/DVD-ROM image to install the distro,
> and that the distro doesn't have to know anything at all about the
> bootloader, except to install a hopefully entirely HW-agnostic
> boot.scr that I detailed above.

need to add pxe support in there. there is no reason we couldnt make
installer isos, we dont because we do not know of any hardware
supporting it. but a installer sdcard or usb stick are things we want
to support as well as network installing using pxe booting.
 
> I know that some other SoCs store U-Boot etc. on
> storage-partitions/filesystems instead. Perhaps distros should always
> assume that the "U-Boot partition" is sacred, and just large enough
> for the firmware, and put all their files on other partitions. The
> only difference between Tegra and OMAP then would be an extra
> partition, and hence the distro's / or /boot would be either
> partition 1 or 2:
> 
> Tegra:
> Boot flash: U-Boot
> storage partition 1: /       (boot.scr, DTB, zImage, etc.)
> 
> (p1 marked bootable)

> OMAP:
> storage partition 1: U-Boot
> storage partition 2: /       (boot.scr, DTB, zImage, etc.)
> 
> (p2 marked bootable)

for fedora 20 i plan to use raw MLO support for OMAP and have it load
the u-boot.img from the first bootable partition. SuSE are doing this
today but the patch they have enabling it needs some work to support all
the different ways things are setup today. for fedora 19 we used a 20mb
vfat partiton that contains MLO u-boot.img and a uEnv.txt loading a
boot.scr from /boot/ on the 3rd partition
partition 1: 20mb for u-boot mounted at /boot/uboot
partition 2: 512mb swap
partition 3: / 

but overall i like the idea,

> > I may not be entirely clear here and there may be things I am
> > missing, I feel it is a good place to start the discussion.
> 
> I like where I think you're going!
> 

Thank you, I am open to feedback and options to achieve our goals that
will help all distros and not break things for use cases that are not
our primary interest.

Dennis


More information about the U-Boot mailing list