boot/loader: How to boot Linux and nothing else
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 490 | |
Author | ||
License | CC Attribution 2.0 Belgium: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/47269 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
BootingComputer fontProcess (computing)FirmwareMereologyBootingComputing platformDynamic random-access memoryPeripheralCodeGastropod shellSystem programmingStack (abstract data type)Booting2 (number)Software developerKernel (computing)CodeBootingBefehlsprozessor1 (number)Standard deviationArmSystem on a chipPhysical systemComputing platformAdditionStructural loadTask (computing)State of matterFirmwareSoftwareTouchscreenComputer fileMultimediaComputer configurationPresentation of a groupAreaCartesian coordinate systemProcess (computing)Range (statistics)Arithmetic meanComputer hardwareVideo game consoleConnectivity (graph theory)Computing platformSurjective functionWeb pageProduct (business)Computer animation
06:47
System on a chipSource codeFunctional (mathematics)Computing platformPoint (geometry)Similarity (geometry)Office suiteCodeSoftware bugArmNumber
08:27
Kernel (computing)Computing platformLevel (video gaming)Computer-generated imageryBootingRootArmVideo game consoleBitKernel (computing)Source codeWhiteboardLevel (video gaming)MultiplicationBootingFunctional (mathematics)File archiverSoftwareTask (computing)Single-precision floating-point formatComputing platformArmLimit (category theory)Sign (mathematics)BefehlsprozessorState of matterAsynchronous Transfer ModeBootingBinary codeNP-hardMedical imagingStructural loadCodeCuboidMereologySpacetimeScripting languageConfiguration spaceFlow separationIntegrated development environmentComputing platformNetwork topologySet (mathematics)Computer animation
15:53
Computer-generated imageryBootingRootArmCodeKernel (computing)MereologyComputing platformFile systemComputing platformData managementDevice driverBootingLocal area networkKernel (computing)Heat transferKey (cryptography)Revision controlCodeNetwork topologyBootingComputer fileSoftwareMultiplication signSound effectLimit (category theory)ArmInformation securityShape (magazine)AreaIntegrated development environmentConnectivity (graph theory)Power (physics)CryptographyProjective planeLibrary (computing)Repository (publishing)Binary codeSoftware maintenanceWhiteboardFlash memoryCommunications protocolClient (computing)Functional (mathematics)Source codeComputer animation
23:18
Computing platformCodeComputer fileKernel (computing)Source codeComputer animation
23:37
Network topologyKernel (computing)Electronic mailing listSingle-precision floating-point formatMultiplication signBootingSource codeCodeComputer animation
24:48
Point cloudFacebookOpen sourceComputer animation
Transcript: English(auto-generated)
00:05
Hello, everyone. It's nice to see all of you here. Some of you were on the previous talk, and those of you who were then will probably better understand what I will say.
00:20
My name is Wukas. I work at Samsung R&D Institute Poland. Today I would like to share with you an idea we've got in my team. We decided to replace a bootloader on one of our development platforms with Linux kernel and a handful of user land tools. This by no means is something new.
00:43
We did it because others did it before us. And here on FOSDEM, I have already seen at least two talks about it. But we've got our approach, which I would like to share with you. We think there are several good reasons to do that,
01:01
one of them as being a little bit lazy, as probably some of you here too, and liking others to help us do our job. We want to avoid double effort that is required to bring up a new platform,
01:21
because code for both Linux kernel and the bootloader needs to be developed to get a functional platform. And we think there is no need to create code for both Linux and bootloader.
01:41
Because the talk is rather short, and I really don't want to miss the ending, I will do my best to tell you everything I've got, and then I will answer your questions. This presentation has got two parts, unlike what's on the screen.
02:01
The first describes more or less the current state of publicly available bootloaders on ARM Cortex-A CPUs. Angelo said a lot more about that. The second is about our work, how we think it is possible to improve the situation.
02:22
For those who are unfamiliar with the topic, on ARM, there is no standard firmware like BIOS or UEFI on x86. That is why it is a bootloader's job to configure most important hardware components.
02:43
Let me ask, how many of you have touched a bootloader code or an architecture-dependent Linux code that runs before start kernel function? OK, we are on the same page. That's nice.
03:01
Maybe some of you are more clever than I am. In this presentation, I assume the booting process comprises the following stages. The firmware is a piece of, this is what others call the RBL, Angelo called it RBL.
03:22
This is a piece of immutable code that comes with a CPU. It cannot be changed by any means. Then there is a bootloader, a.k.a. SPL, divided into several stages. And then, of course, there is an OS,
03:41
the code that implements the application. The device was designed for, like desktop, environmental, multimedia system, or choose yours. An additional task bootloaders sometimes perform
04:00
is an OS update, especially when the OS is broken. This means bootloader should be very robust, as it may be the only way to unbrick a device. We concluded that the available bootloaders for ARM have so significant drawbacks, and we
04:23
need to improve upon that. Following the experience of the Linux boot project, we decided to use Linux as a bootloader. These are the three most common bootloaders
04:40
I could find for ARM. Each of them support different architectures, too. There is a lot more proprietary, commercial, custom ones. Until now, in our work, we have used U-Boot on most development platforms and some custom bootloaders on products.
05:02
Every new platform needs a bootloader to be ported to it. You build a PCB, you smash an SOC onto it. To boot it, you need a bootloader. Just to repeat, I mean all the code that is loaded from ROM
05:24
that runs until Linux kicks in. So that's what I consider a bootloader. Porting a bootloader to a new platform requires writing platform setup code, which will configure the platform to be usable.
05:45
It turns on DRAM, some clocks, some voltages on board, some basic peripherals like console. Then there is a general purpose code,
06:01
which deals with loading OS kernel from a storage or from a network and starting it. In traditional bootloaders, the range of options here in this area is somewhat limited. On the other hand, for Linux,
06:22
there are tons of device drivers, dozens of file systems, and more than one network stack, too. And thanks to kexec, Linux can act as a bootloader and start completely new kernel. Load it from wherever you want
06:41
and start it as a new system. This is Odroid XU4. It is based on Exynos 5422 SOC, and it has been a reference platform for Tizen OS for the past couple of years,
07:01
and almost everyone in our office has one in their drawer. That's why we chose it for this proof of concept. It's well supported in the mainline Linux, and we knew that if it doesn't boot, then it is our fault we're doing something wrong.
07:23
It wasn't entirely true, but that's not the point. Now, we fixed probably two bugs somewhere in the compressor code that nobody looks into. It works, and we did something different,
07:41
and it appeared a fix was needed. There have been a number of similar attempts to push Linux as close to hardware as possible, mostly on x86 platforms, and as I learned today, on RISC-V too.
08:04
We work with ARM platform, and thus our approach is slightly different. Please do keep in mind also that this was kind of a side project, and we focused on getting the most important functionality available,
08:22
and we're not bothered by any convenience feature too much. Okay, the boot on Odroid looks as follows. There are three blobs provided by the vendor, which is hard kernel, and they are flashed with a special,
08:44
with appropriate script. They are flashed onto SD or EMMC card, so the board can boot. BL1 does the very basic platform setup, which is turning on DRAM and reads BL2.
09:03
BL2 loads TrustZone and an unsigned U-Boot image. TrustZone blob appears to be doing nothing because there are a lot of null bytes,
09:20
so we don't have source code for it. It doesn't do anything, I think. No, it doesn't behave wrong. We don't have any problems with it. Let's stay with that. All three blobs need, these three blobs need to be signed.
09:44
Hard kernel signs TrustZone handler and BL2 upon request on their forum, but this is a little bit cumbersome to change them, so we decided we will replace U-Boot, just U-Boot.
10:02
No, we didn't replace any of these. There is, however, as you might see, there is the name of the last, no, the BL2, suggests the largest hurdle we faced. That is one megabyte limit on the U-Boot image.
10:26
We had to fit within that limit. After a quick recap, we found these four tasks were essential to boot the board with Linux kernel as a bootloader.
10:44
Platform setup. As I said, this was rather quick. The BL1 and BL2 code does all of the setup, except for console. We did console with a small, I don't know, 50, 60 bytes shim. That's easy.
11:02
One megabyte is very, very little for a kernel. Device tree and the reasonable, whatever that means, user land. After disabling almost everything in kernel, what we could, our Z image took like 900,
11:23
50 kilobytes, so we were left with 50 or 60 kilobytes for the user land part. For the record, without such strict limit,
11:43
we would build a separate bootloading kernel anyway with different configuration than the one we used for the OS. So two kernels are always, we think, required. Maybe the first one could be not that much limited.
12:13
Linux, luckily K exec worked. However, we had recently some other boards
12:21
which had some problems with K exec. It appears to be the problem with drivers of some devices that don't shut down devices properly, and when a new kernel starts, drivers try to probe devices.
12:41
The devices are in states that cannot be handled at the probing stage by the drivers, so this will need investigation. Although we weren't much into providing user land tools,
13:03
just a few bits to load the kernel started, we found the U-root used in Linux boot, for example, to be a very nice piece of software for that. Much better than, in our opinion, much better than other such toolboxes.
13:22
Alas, it doesn't support K exec on ARM. We had to use K exec tools, but that's just a minor problem. Thanks to TMPFS, which, unlike old style RAM disk,
13:40
is able to expand in RAM as new data is saved, we could split our initramfs archive into two. The first stage comprises only a tiny init we call half-stage init, which mounts fat partition, unpacks stage two archive, or stage one full archive,
14:02
executes slash init that is expected to be in the archive, and replaces HS init. There is no limit for the stage two archive, except, of course, the size of RAM, size and speed of storage, and such things.
14:23
U-root, short for universal root, is a really nice piece of software I'd like to recommend you, if you build boot loading environments. It is a set of basic tools. There is a shell, a text editor, LS,
14:40
cat, and stuff that you find in all the boxes out there. But unlike other boxes, it is written in Go. It can be deployed in two modes, source and BusyBox mode. The former is need because the only binary
15:03
that is initramfs is Go compiler, and every tool that you use is compiled on demand. Unfortunately, it requires much more space
15:20
and rather strong CPU. On ARM, it was too slow to build the commands. The BusyBox mode is a single binary with multiple symlinks calling multiple functions. At the moment, what we've got,
15:41
we can configure the kernel to build an image for a selected board. In our case, it is XU4 to boot without U-boot and start another fully-fledged kernel. Although XU4 cannot act as a USB device,
16:04
to use Linux on other our boards, we need to develop a function FS-based tool to receive files, to receive and download to the Flash. We also need to make kexec tool in U-boot work on ARM.
16:26
Why, you may ask? From our perspective, there are following advantages to this approach. Less effort during platform bring up because we avoid code duplication.
16:41
This extends also to maintenance. You don't end up with, I don't know, for example, PMIC driver into repositories in Linux kernel where you need it for power management and in bootloader where you need it to bring up the platform.
17:06
Linux, more flexibility. Linux, both the kernel and the user land is much more capable and flexible than bootloaders available.
17:20
Two areas we consider crucial are network support and security. Although it is possible to boot over a network today, only TFTP is available for file transfer which is perfectly fine from a client perspective. However, without an authentication,
17:42
it is not a protocol I would deploy outside any local network. Support for crypto libraries is very new and quite limited as far as I can tell. And finally, from our experience,
18:01
the general purpose code like file systems, like network stack, like, I don't know, USB stack, not the driver for the hardware, but the rest of the stack is somewhat in better shape in the Linux kernel and is maintained more regular.
18:27
That is our experience. In summary, the key features of our approach of what we did, we are definitely arm-centric
18:42
because that's the platform we work with. We assume, however, that it applies directly to other platforms which don't employ standards-based firmware, like BIOS or UEFI. Our motivation to push Linux as close to the hardware
19:01
as possible is a little different than on x86. We're not concerned much about security, like management engine on x86 that affect platforms user, but rather we want to help vendors,
19:21
ourselves included, to minimize the effort, to prepare, to bring up the platform, to avoid the unnecessary effort to prepare two versions of device drivers and keep file systems up to date and so on and so on.
19:42
Our goal is to find a place and means in the Linux kernel source tree to keep platform board-dependent code which can do platform setup before the kernel starts and can be built together with the kernel
20:06
to form a single binary that the firmware, the ROM bootloader can load, alternatively signed as PL. Although this might look like we try to resurrect port files, we don't.
20:22
The platform-specific code that we need is not the same as the board files that were used before device tree became popular. The code needs to bring up only several components
20:43
which are not accessed, which are not controlled later on. With this in place, porting Linux would require less effort, less amount of work, and you get really, really powerful boot environment.
21:05
These are the guys that helped me a lot by either providing knowledge or allowing me to work on this as a side project and special thanks go to Mateusz who wrote
21:20
the small init, the HS init, and squeezed it really hard to fit in the limit. Okay, I managed somehow. Are there any questions?
22:01
I guess it's more, oh, it's loud. I guess it's more a comment than a question but I guess the question comes along. First off, I think it's an amazing idea to use Linux as your driver toolkit because then you only write your drivers once, right? Doing those in U-Boot and in Linux at the same time is a terrible idea either way simply because you always get this typical fork effect
22:23
where you have diverging drivers sooner or later. The biggest issue I see is your, how do I put this? The platform init code is something that the ARM world was really proud of to finally get rid of.
22:42
I don't see us reinventing that and reintroducing it in a 64-bit ARM world. It just is not going to happen. We need to find a different way to get this tiny platform init code in between your basically your BL2 and the actual Linux kernel. And this is where I really would like to brainstorm with you on cool ideas we can do.
23:01
I think we have a couple of things on the plate of what is possible to create a tiny shim that runs before Linux so that you don't have to put platform code into the Linux kernel itself and the tree itself. I'm very sorry, but there was something. Could you come and repeat me the question
23:25
without the mic? Without the mic. The platform init code you're putting into Linux kernel, right? Before the Linux kernel. So is it actually separate standalone code? It's a single file. But it's in Linux? In the source tree. Yes, I think we need to work on untangling this.
23:44
Okay, the question was is the shim we prepend to Linux kernel inside the kernel tree? Yes, we want to be inside the kernel tree. And I haven't mentioned that. I have posted RFC patches to the lists
24:01
and they are available for commenting. So it's not like we want to push something. We want to discuss it. Because Linux kernel, the source tree can become a single stop shop for vendors, for people. To boot, you know, code that boots.
24:21
That's, we're definitely open for discussion. All of you can leave somehow silent to let the speaker finish the talk.
24:42
Okay, it appears I finished. I think we're done with time time. Yeah. Thank you very much. So I thank you too.