uEFI grub2 on Raspberry Pi
Graf, Alexander
Booting is hard. Booting in the ARM world is even harder. State of the art are a dozen different boot loaders that may or may not deserve that name. Each gets configured differently and each has its own pros and cons. As a distribution this is a nightmare. Configuring each and every one of them complicates code that really should be very simple. To solve the problem, we can just add another layer of abstraction (grub2) on top of another layer of abstraction (uEFI) on top of another layer of abstraction (u-boot). Follow me on a journey on how all those layers can make life easier for the distribution and how much fun uEFI really is. After this talk, you will know how ARM systems boot, what uEFI really means, how uEFI binaries interact with firmware and how we are going to move to uEFI based boot on openSUSE for ARM.
 Hello and welcome to my amazing talk about running every password you could possibly hear in a single device. EFI, Grub 2, Raspberry all at once. So, my, I'm Alexander Graf. This time for real. David was just faking to be me. I'm usually a KVM and QM developer. You might have seen me from things like running KVM, running KVM, doing KVM on power. Things that people usually seem to take us granted these days. But this time around I'm going to talk to you as a member of the Open CSARM team. So you saw on the headline the Raspberry Pi. That's what it looks like. You probably, most of you guys have seen one. I just took this image from our webpage. It also has a logo on it, which is cool. So why would you possibly want to buy a Raspberry Pi? That's very, very simple reasons. It's cheap as hell. It's available like nothing else. You can just go to a store, grab it, and it's on based. What more could you possibly ask for? But most of you guys probably want to run software on such a device, right? So you want to boot, which means you want to get into a system. Without booting on the Raspberry Pi, it's really, really simple. You take this board, then you take your SD card, and then you plug your SD card in, and then you take your power cable and plug your power cable in down there, and then it just boots. Unless you're the one creating the image that is supposed to make this thing boot, which is what we're here for, right? So let's take a look at the SD card. What does this thing actually look like? What do we have in there? That's the usual. We do have, the screen is really dark, we do have our root file system, we do have a swap partition. The usual stuff you would expect on a main device that you run your operating system from, but the Raspberry is special in one regard in that it also has a FAT partition. And that one's very, very mandatory on those devices because the FAT partition actually contains a few files that are incredibly necessary to boot such a device. The really, really most important one is boot code bin that just lies around on that FAT partition, that just tanks there. And it's so important because that's what is the initial boot code. That comes from the Raspberry Pi Foundation. It's actually GPU code, so the whole thing doesn't boot from the ARM systems, it boots from the GPU. This is GPU code that then goes in and reads the config text file, which is also on there to figure out what it should do, how it should look like, whether it should enable serial or it's what frequencies it should use, what monitor depth it should use. That's all written in config text with defaults, obviously. And we usually, if you have a Raspbian distribution, you also get a kernel on that FAT partition that you boot, which ever from the very first time we enabled the Raspberry Pi and an open suzer, we figured it was a really bad idea. So instead, we are using Uboot at that point. And Uboot then goes in and can actually break out of that FAT partition and go into your real root partition and read a script called boot script from there and load the kernel in a.d and device tree from your root partition, which means you can actually update files with normal RPMs. That was that different from how your PC boots. Very simple. Your PC boots first off by being a PC and not a Raspberry Pi. And then you have something, some storage where you put your firmware in. On the Raspberry Pi, everything's on the SD card. On a real PC, you have something sold onto your board where your EFI firmware usually lies. And that EFI firmware goes around and just looks at your hard disk, at your storage device, whatever they are, even a network, and just searches for something it should boot based on different algorithms. It finds something that it can execute and should execute in boot orders, which usually in our case, open suzer is Grap2, which then uses callbacks into EFI to proceed, load the kernel, run that kernel, and you're good. So you can see it's actually pretty similar to how the Raspberry Pi boots, just that you have a firmware piece of hardware rather than your SD card and you're not running off a GPU. But other than that, pretty similar. So what is this EFI thing really? The whole talk is about running EFI, right? So what is EFI and why are people so scared of it? I honestly don't know. Well, why they're scared, but I can tell you what it is. The really, really most important crucial core piece of EFI is something called the system table, which is just a pointer to a struct that has pointers to structs that have pointers to structs that have pointers to structs, and all of those contain either information or function callbacks. The most important one of them are the boot time services. That's basically a collection of around 50 function callbacks that you can call into to do different things during boot time. Grap2, for example, uses those. I just took a few most important ones out here. Obviously you want to load images, right? So the load image callback, if you have an image, memory, and you actually want to have it loaded into the system, you call the load image function with a binary that's EFI compatible. Anybody recognize what this might look like? You've seen that thing down there before? Yeah. It's a P executable. So basically the same thing that Windows uses. It's the same format. It's a pretty simple format, to be honest. A lot simpler than elf. So loading that into memory is not too hard. It's really just sections that you take and then put into RAM at different locations. And then you've got an entry point, jump into it, and that's all you need to do for loading. So loading an image is easy. The other really core piece of EFI is that it has a notion of objects. It doesn't call them objects, and it doesn't call classes, classes, but it is basically the same idea. So you have protocols, which are classes, and handles, which are your objects. And imagine you have a disk device, right? You've got a set of disks, your first set of disks in your system, and that one set of disks can implement a class called a block operation class. You never give names to anything in EFI. They're all based on IDs. You have really long, 128-bit long GU IDs, but this is basically just a class that says I can do block operations. And that consists of just a few function callbacks again, so all of these are structs, right? So this is a struct that basically tells you it's a struct. It's a struct inside a struct. And then in there you have function callbacks that you can call to read or write to such a device. It's very, very simple. And it can also have a second or third or fourth or how many ever you want different classes implemented by the same object. In the example of a set of disks, for example, you usually have a thing called a device path where you can find out where in your device tree this thing is. So this is like my disk is attached to a set of controller, which is attached to a PCI device, and then you can just walk through this path. So it's really just a simple means of providing access to objects. And objects can be arbitrarily enhanced too, so you can load another driver that then adds objects to your object list and exposes different devices basically with this. And the next really cool thing that EFI does, which is important for filmware, is it manages memory. You always want to know which memory in your memory space is already occupied and which isn't. So EFI maintains a memory map that you can always ask for, where it just says, all right, so at this address I have some space available, at that address everything's already occupied, at this address there's nothing there at all, at that address we got runtime services, I got to this later, and say down here is a lot of memory available again. If you allocate memory, what happens is that EFI basically just goes and says, oh, you want one megabyte allocation, all right, I'll swing down an existing available size and add one more blob for your one megabyte allocation, we turn this thing to you and that's it. It doesn't do anything beyond this. So if you don't free this, it will still be allocated by the time you exit your application, which by the way, grab two does. So memory allocation is really simple to you, you can always ask for your memory map, you can receive it whenever you like, it's always up to date, so you always know how much memory is still available for allocations. Console is obvious, it's just pointers to the console objects for standard in, standard out, and additional tables contain fancy things like your device tree or your ACPI tables, your DMI tables, everything that's just arbitrary data that you want to have somewhere in memory and know where it is, it's just put with IDs into those arbitrary tables. So it's just tuples of ID and pointer. Front-time services are a really, really cool thing in EFI. Imagine you boot your PC, you boot it up and you have a lot of RAM. And initially when you boot, of course, EFI is running there and EFI owns some of that RAM. Now EFI goes and loads grab, grab goes and extends itself, allocates a lot more memory, loads Linux into that space, Linux gets loaded into real memory, and then what? Well, then at this point, Linux actually is also an EFI binary that executes and talks to EFI and tells EFI, you know what, EFI, go away, I don't need you anymore. I'm done with booting, I don't need booting anymore. Please give me the machine, I want to have access to all of that memory without asking you for it. So it does that, but one thing that you can do with EFI is you can still preserve some of EFI in your memory space by having that blob be self-relocatable and Linux calls you with your new relocation addresses on it. So this blob is still available while Linux is running. So Linux can call into functions inside of that small space and then those EFI one-time services can still do operations on behalf of Linux. So this is code that actually is film work code that you just call into. And the most obvious examples for one-time services are get time, so you can ask EFI what time it is just to access the real-time clock. You can ask EFI to give you a variable or set a variable, you have some variable space in EFI and you can ask it to reset your system, for example. Please reboot now and you don't need to care about 50 different power management units or whatever you have out there, just reboot the system. So it's really a convenient hardware section layer for you. So how do we bridge UBoot and EFI? How do these interfaces even match? I mean, UBoot is a completely different world, isn't it? It's run for embedded, it doesn't have anything to do with a real cool service that do have EFI. Well, if we take a really deep look, memory management, yes, sure. We need to write new code to support all the memory management that EFI exposes in UBoot because UBoot doesn't have a notion or has a notion of memory allocations, but it's different from what EFI thinks it should be. But anything else, if you look at the network stack, well, there's a network stack in UBoot. So if we just write small web code, we can as well just access the UBoot web code, the UBoot web code from a random boot time service callback. Same goes for console, for disk. All the devices actually look almost the same on the interfaces if you really compare EFI interfaces and UBoot internal interfaces. So all we need to do to support calling into UBoot code from a boot time service function callback is to write a small wrapper that just converts function semantics for us. For one-time services, that's slightly more complicated because UBoot doesn't have any notion at all of one-time services. It only knows how to run at boot time and then tries to just completely disappear. However, it's not really hard to do either. We need to basically teach a function like the reset CPU function to be one-time service aware. That's a patch of about three to four lines at this point per function that we want to call. And at that point, we can just call a wrapper, run the CPU reset function, and you get fully working one-time services in UBoot. So I have enabled this for Raspberry Pi 3 or Raspberry Pi in general, actually, and the Layerscape 2085 systems. But adding new support is really a matter of a couple lines of code. So it's trivial. Get time. We don't implement it all. The reason is most boards that you have out there don't have a clock to ask. If you don't have a clock, you can't really return a working time. And same for variables. If we want to support variables, we would need to support storing variables somewhere and reading variables from somewhere that doesn't collide with what Linux actually uses at the point in time when Linux calls our one-time service code. We don't have those separate devices on most devices that we want to support with this. And for additional tables, very simple, we just put our device tree in there. We have a device tree. We can load the device tree. We put it in there. Done deal. And at that point, we actually have everything we need to execute an EFI binary, right? So if we take a look, this is just a boot log from a Zinc and P system. It just boots up into UBoot and then gets you to a shell. So what we need to do to boot an EFI binary on these with current UBoot. So if you just take UBoot 2016 or 5, for example, it's all implemented. What you need to do is load your GRUB binary, load your device tree, and call boot EFI. Done. Get a GRUB. As simple as that. So if you take a current UBoot, you can always just manually load an EFI binary, which could be GRUB, which could be Linux kernel itself. It's also EFI binary. Can be anything that you like. It could be the open BSD boot loader, whatever you prefer. But if we go back, actually, and take a look at this excerpt, one thing you might have realized while reading through all of these lines here is there's something down there that's called autoboot. So what is autoboot? Autoboot just means that UBoot goes in and executes a boot script that's predefined in the configuration. And on most systems these days, that's a distro script. It's just a set of templates that go through a list of different devices and searches for known good sources of booting from them. So really the distro script just goes in, searches your disk, and looks if it finds an EFI binary at the spec defined removable location path for EFI binaries. That's just part of the EFI spec. And searches if it can find the device tree. If it doesn't, it just doesn't load it. And then usually, of course, your EFI binary is grub 2. So you don't press any key at all, and it just automatically finds everything and you get grub. Which is pretty much how you want to boot these days. You don't want to mess with boot scripts, you don't want to mess with anything at all. You really just want to have things work out of the box. So are we standing? Pretty good. As you can see, everything is implemented. So we have EFI objects. We have console support. We have disk support. We can even do pixie boot support. I see pixie boot by now. Video support works. You can see graphical output. We can run grub 2. We can run linux. I have not tried to boot windows yet. There were patches on the mailing list to enable X8664 about two days after I posted my first patch set. So it really is not hard to enable a new architecture. But they haven't actually progressed since because the guy was doing something different since then. And I don't really care too much about booting windows right now. If you compare code sizes between enabling EFI support and not enabling EFI support, you can see that the difference is negligible. You increase your code size by somewhere between 10 and 20k. Which if your code is already 500 kilobytes big, 10 or 20k doesn't really account for anything at all. It's completely negligible. Which means that upstream we are now enabled by default. So if you just take Uboot and you do a dev config for a board, you get EFI support on today's Uboot. You don't have to mess with anything at all anymore. You don't have to mess with U images, with Z images, with anything. You just run grub and it works. Since I'm telling you that everything works, I should probably also show you that it works, which is more fun. So for the demo, I'm going to plug this Raspberry Pi 3 I got in here into the HDMI connector. And connect power. Let's hope this one works. All right, there you go. So this is Uboot. This is Grub 2 booting up with graphics and everything. All the bells and whistles you would usually know. If you have a USB keyboard attached, you can even use the USB keyboard to edit a command line, do whatever you like. You boot into Linux and there you go. You get a fully working distribution with just the way you would usually expect it to work with all the Yask boot loader things working, with all the Pearl boot loader updates working. Everything just works the way you would imagine it to have worked from the very first day. I'll just leave it at that one. So the next slide is really just to thank you and go out and try it for yourself. And do you have any questions? Saifah, please get a mic there right next to you. Yes. What's the idea behind slowing down the Raspberry Pi boot even more with more complicated stuff? I mean, the one thing, if this doesn't work, people will go Googling and ask why it doesn't work, everybody will tell them to go away. Just boot the Raspberry Pi like it's supposed to boot. It depends on what your goal is. Is your goal to support the Raspberry Pi? Boot the way the Raspberry Pi does it. If you want to really actually do it the Raspberry Pi way, use the downstream kernel, use whatever method you like, I don't care. If you want to boot the Raspberry Pi, like you boot any random normal system, if you want to actually go towards a maintainable future, you want to have that path. But then it needs to speed up a lot more because I mean, it's a lot slower than booting a normal boot. There was a 10 second timeout. Yes, it does boot slower, but that's all things that are going to go away. The big advantage of this, in particular for the Raspberry Pi is that you now have a boot menu to select different kernels. Because the way it worked before is that when we updated a kernel and the new kernel for some reason didn't work like some kernel head, and then you were kind of stuck and you now had to take the SD card and put it into different machines, tweak siblings and so on. And now with this couple seconds more in the boot process, you can just select a different kernel if the default selection doesn't work and you still have a working system. You can also add a command line on the fly from the boot loader. It just basically moves your Raspberry Pi from a device that you target to a device that you work on. That's basically the shift. It goes from this is something like an embedded device, like a mobile phone that I just want to cross compile things on my PC on and then push them onto the device over towards this is the device I'm actually working with and working on. You would never imagine to directly flash your kernel into your flash chip on your PC, would you? Well, maybe you would, but nobody else who is saying would. So would this also mean that if you have butterfs and the snapshots that it's all just working? Yep. But if it's snapshots, snapshot, wall-back booting, all of that just works out of the box. The other question I have is around Pixie Boot. So Pixie Boot is not implemented by the firmware in that case, so it's really done on the UFI side or? Okay. It's probably just a naming problem. EFI is the specification that tells you how to implement these interfaces. Uboot implements that specification and Tiano Core implements that specification. You can use both to boot your system and at that point, because you're booting your system from those pieces of software, they become your firmware. So on the Raspberry Pi, Uboot is my firmware. On your PC, a Tiano Core-based fork from your vendor is your firmware. It's just a naming thing. And that firmware implements EFI. Or actually, it implements UEFI because it's 2.0. But it will work. That's the important part. So again? Pixie Boot will just work. That's the important part. Yeah. The point about this is it won't be any different from a PC at that point. As soon as you have your Uboot on there, it will behave as a PC does or like the overdrives that we saw earlier do. Just at a much lower price point. More questions? Size of relief? All right. Great. Well, thanks a lot. Thank you.
 Hello and welcome to my amazing talk about running every password you could possibly  hear in a single device.  EFI, Grub 2, Raspberry all at once.  So, my, I'm Alexander Graf.  This time for real.  David was just faking to be me.  I'm usually a KVM and QM developer.  You might have seen me from things like running KVM, running KVM, doing KVM on power.  Things that people usually seem to take us granted these days.  But this time around I'm going to talk to you as a member of the Open CSARM team.  So you saw on the headline the Raspberry Pi.  That's what it looks like.  You probably, most of you guys have seen one.  I just took this image from our webpage.  It also has a logo on it, which is cool.  So why would you possibly want to buy a Raspberry Pi?  That's very, very simple reasons.  It's cheap as hell.  It's available like nothing else.  You can just go to a store, grab it, and it's on based.  What more could you possibly ask for?  But most of you guys probably want to run software on such a device, right?  So you want to boot, which means you want to get into a system.  Without booting on the Raspberry Pi, it's really, really simple.  You take this board, then you take your SD card, and then you plug your SD card in, and  then you take your power cable and plug your power cable in down there, and then it just  boots.  Unless you're the one creating the image that is supposed to make this thing boot, which  is what we're here for, right?  So let's take a look at the SD card.  What does this thing actually look like?  What do we have in there?  That's the usual.  We do have, the screen is really dark, we do have our root file system, we do have a  swap partition.  The usual stuff you would expect on a main device that you run your operating system  from, but the Raspberry is special in one regard in that it also has a FAT partition.  And that one's very, very mandatory on those devices because the FAT partition actually  contains a few files that are incredibly necessary to boot such a device.  The really, really most important one is boot code bin that just lies around on that FAT  partition, that just tanks there.  And it's so important because that's what is the initial boot code.  That comes from the Raspberry Pi Foundation.  It's actually GPU code, so the whole thing doesn't boot from the ARM systems, it boots  from the GPU.  This is GPU code that then goes in and reads the config text file, which is also on there  to figure out what it should do, how it should look like, whether it should enable serial  or it's what frequencies it should use, what monitor depth it should use.  That's all written in config text with defaults, obviously.  And we usually, if you have a Raspbian distribution, you also get a kernel on that FAT partition  that you boot, which ever from the very first time we enabled the Raspberry Pi and an open  suzer, we figured it was a really bad idea.  So instead, we are using Uboot at that point.  And Uboot then goes in and can actually break out of that FAT partition and go into your  real root partition and read a script called boot script from there and load the kernel  in a.d and device tree from your root partition, which means you can actually update files  with normal RPMs.  That was that different from how your PC boots.  Very simple.  Your PC boots first off by being a PC and not a Raspberry Pi.  And then you have something, some storage where you put your firmware in.  On the Raspberry Pi, everything's on the SD card.  On a real PC, you have something sold onto your board where your EFI firmware usually  lies.  And that EFI firmware goes around and just looks at your hard disk, at your storage device,  whatever they are, even a network, and just searches for something it should boot based  on different algorithms.  It finds something that it can execute and should execute in boot orders, which usually  in our case, open suzer is Grap2, which then uses callbacks into EFI to proceed, load the  kernel, run that kernel, and you're good.  So you can see it's actually pretty similar to how the Raspberry Pi boots, just that you  have a firmware piece of hardware rather than your SD card and you're not running off a  GPU.  But other than that, pretty similar.  So what is this EFI thing really?  The whole talk is about running EFI, right?  So what is EFI and why are people so scared of it?  I honestly don't know.  Well, why they're scared, but I can tell you what it is.  The really, really most important crucial core piece of EFI is something called the  system table, which is just a pointer to a struct that has pointers to structs that  have pointers to structs that have pointers to structs, and all of those contain either  information or function callbacks.  The most important one of them are the boot time services.  That's basically a collection of around 50 function callbacks that you can call into to  do different things during boot time.  Grap2, for example, uses those.  I just took a few most important ones out here.  Obviously you want to load images, right?  So the load image callback, if you have an image, memory, and you actually want to have  it loaded into the system, you call the load image function with a binary that's EFI compatible.  Anybody recognize what this might look like?  You've seen that thing down there before?  Yeah.  It's a P executable.  So basically the same thing that Windows uses.  It's the same format.  It's a pretty simple format, to be honest.  A lot simpler than elf.  So loading that into memory is not too hard.  It's really just sections that you take and then put into RAM at different locations.  And then you've got an entry point, jump into it, and that's all you need to do for loading.  So loading an image is easy.  The other really core piece of EFI is that it has a notion of objects.  It doesn't call them objects, and it doesn't call classes, classes, but it is basically  the same idea.  So you have protocols, which are classes, and handles, which are your objects.  And imagine you have a disk device, right?  You've got a set of disks, your first set of disks in your system, and that one set of  disks can implement a class called a block operation class.  You never give names to anything in EFI.  They're all based on IDs.  You have really long, 128-bit long GU IDs, but this is basically just a class that says  I can do block operations.  And that consists of just a few function callbacks again, so all of these are structs, right?  So this is a struct that basically tells you it's a struct.  It's a struct inside a struct.  And then in there you have function callbacks that you can call to read or write to such  a device.  It's very, very simple.  And it can also have a second or third or fourth or how many ever you want different  classes implemented by the same object.  In the example of a set of disks, for example, you usually have a thing called a device path  where you can find out where in your device tree this thing is.  So this is like my disk is attached to a set of controller, which is attached to a PCI  device, and then you can just walk through this path.  So it's really just a simple means of providing access to objects.  And objects can be arbitrarily enhanced too, so you can load another driver that then adds  objects to your object list and exposes different devices basically with this.  And the next really cool thing that EFI does, which is important for filmware, is it manages  memory.  You always want to know which memory in your memory space is already occupied and which  isn't.  So EFI maintains a memory map that you can always ask for, where it just says, all right,  so at this address I have some space available, at that address everything's already occupied,  at this address there's nothing there at all, at that address we got runtime services, I  got to this later, and say down here is a lot of memory available again.  If you allocate memory, what happens is that EFI basically just goes and says, oh, you  want one megabyte allocation, all right, I'll swing down an existing available size  and add one more blob for your one megabyte allocation, we turn this thing to you and  that's it.  It doesn't do anything beyond this.  So if you don't free this, it will still be allocated by the time you exit your application,  which by the way, grab two does.  So memory allocation is really simple to you, you can always ask for your memory map, you  can receive it whenever you like, it's always up to date, so you always know how much memory  is still available for allocations.  Console is obvious, it's just pointers to the console objects for standard in, standard  out, and additional tables contain fancy things like your device tree or your ACPI tables,  your DMI tables, everything that's just arbitrary data that you want to have somewhere in memory  and know where it is, it's just put with IDs into those arbitrary tables.  So it's just tuples of ID and pointer.  Front-time services are a really, really cool thing in EFI.  Imagine you boot your PC, you boot it up and you have a lot of RAM.  And initially when you boot, of course, EFI is running there and EFI owns some of that  RAM.  Now EFI goes and loads grab, grab goes and extends itself, allocates a lot more memory,  loads Linux into that space, Linux gets loaded into real memory, and then what?  Well, then at this point, Linux actually is also an EFI binary that executes and talks  to EFI and tells EFI, you know what, EFI, go away, I don't need you anymore.  I'm done with booting, I don't need booting anymore.  Please give me the machine, I want to have access to all of that memory without asking  you for it.  So it does that, but one thing that you can do with EFI is you can still preserve some  of EFI in your memory space by having that blob be self-relocatable and Linux calls you  with your new relocation addresses on it.  So this blob is still available while Linux is running.  So Linux can call into functions inside of that small space and then those EFI one-time  services can still do operations on behalf of Linux.  So this is code that actually is film work code that you just call into.  And the most obvious examples for one-time services are get time, so you can ask EFI  what time it is just to access the real-time clock.  You can ask EFI to give you a variable or set a variable, you have some variable space  in EFI and you can ask it to reset your system, for example.  Please reboot now and you don't need to care about 50 different power management units  or whatever you have out there, just reboot the system.  So it's really a convenient hardware section layer for you.  So how do we bridge UBoot and EFI?  How do these interfaces even match?  I mean, UBoot is a completely different world, isn't it?  It's run for embedded, it doesn't have anything to do with a real cool service that do have  EFI.  Well, if we take a really deep look, memory management, yes, sure.  We need to write new code to support all the memory management that EFI exposes in UBoot  because UBoot doesn't have a notion or has a notion of memory allocations, but it's different  from what EFI thinks it should be.  But anything else, if you look at the network stack, well, there's a network stack in UBoot.  So if we just write small web code, we can as well just access the UBoot web code, the  UBoot web code from a random boot time service callback.  Same goes for console, for disk.  All the devices actually look almost the same on the interfaces if you really compare EFI  interfaces and UBoot internal interfaces.  So all we need to do to support calling into UBoot code from a boot time service function  callback is to write a small wrapper that just converts function semantics for us.  For one-time services, that's slightly more complicated because UBoot doesn't have any  notion at all of one-time services.  It only knows how to run at boot time and then tries to just completely disappear.  However, it's not really hard to do either.  We need to basically teach a function like the reset CPU function to be one-time service  aware.  That's a patch of about three to four lines at this point per function that we want to  call.  And at that point, we can just call a wrapper, run the CPU reset function, and you get fully  working one-time services in UBoot.  So I have enabled this for Raspberry Pi 3 or Raspberry Pi in general, actually, and the  Layerscape 2085 systems.  But adding new support is really a matter of a couple lines of code.  So it's trivial.  Get time.  We don't implement it all.  The reason is most boards that you have out there don't have a clock to ask.  If you don't have a clock, you can't really return a working time.  And same for variables.  If we want to support variables, we would need to support storing variables somewhere  and reading variables from somewhere that doesn't collide with what Linux actually uses at  the point in time when Linux calls our one-time service code.  We don't have those separate devices on most devices that we want to support with this.  And for additional tables, very simple, we just put our device tree in there.  We have a device tree.  We can load the device tree.  We put it in there.  Done deal.  And at that point, we actually have everything we need to execute an EFI binary, right?  So if we take a look, this is just a boot log from a Zinc and P system.  It just boots up into UBoot and then gets you to a shell.  So what we need to do to boot an EFI binary on these with current UBoot.  So if you just take UBoot 2016 or 5, for example, it's all implemented.  What you need to do is load your GRUB binary, load your device tree, and call boot EFI.  Done.  Get a GRUB.  As simple as that.  So if you take a current UBoot, you can always just manually load an EFI binary, which could  be GRUB, which could be Linux kernel itself.  It's also EFI binary.  Can be anything that you like.  It could be the open BSD boot loader, whatever you prefer.  But if we go back, actually, and take a look at this excerpt, one thing you might have  realized while reading through all of these lines here is there's something down there  that's called autoboot.  So what is autoboot?  Autoboot just means that UBoot goes in and executes a boot script that's predefined in  the configuration.  And on most systems these days, that's a distro script.  It's just a set of templates that go through a list of different devices and searches for  known good sources of booting from them.  So really the distro script just goes in, searches your disk, and looks if it finds an  EFI binary at the spec defined removable location path for EFI binaries.  That's just part of the EFI spec.  And searches if it can find the device tree.  If it doesn't, it just doesn't load it.  And then usually, of course, your EFI binary is grub 2.  So you don't press any key at all, and it just automatically finds everything and you  get grub.  Which is pretty much how you want to boot these days.  You don't want to mess with boot scripts, you don't want to mess with anything at all.  You really just want to have things work out of the box.  So are we standing?  Pretty good.  As you can see, everything is implemented.  So we have EFI objects.  We have console support.  We have disk support.  We can even do pixie boot support.  I see pixie boot by now.  Video support works.  You can see graphical output.  We can run grub 2.  We can run linux.  I have not tried to boot windows yet.  There were patches on the mailing list to enable X8664 about two days after I posted my first  patch set.  So it really is not hard to enable a new architecture.  But they haven't actually progressed since because the guy was doing something different  since then.  And I don't really care too much about booting windows right now.  If you compare code sizes between enabling EFI support and not enabling EFI support,  you can see that the difference is negligible.  You increase your code size by somewhere between 10 and 20k.  Which if your code is already 500 kilobytes big, 10 or 20k doesn't really account for  anything at all.  It's completely negligible.  Which means that upstream we are now enabled by default.  So if you just take Uboot and you do a dev config for a board, you get EFI support on  today's Uboot.  You don't have to mess with anything at all anymore.  You don't have to mess with U images, with Z images, with anything.  You just run grub and it works.  Since I'm telling you that everything works, I should probably also show you that it works,  which is more fun.  So for the demo, I'm going to plug this Raspberry Pi 3 I got in here into the HDMI connector.  And connect power.  Let's hope this one works.  All right, there you go.  So this is Uboot.  This is Grub 2 booting up with graphics and everything.  All the bells and whistles you would usually know.  If you have a USB keyboard attached, you can even use the USB keyboard to edit a command  line, do whatever you like.  You boot into Linux and there you go.  You get a fully working distribution with just the way you would usually expect it to  work with all the Yask boot loader things working, with all the Pearl boot loader updates  working.  Everything just works the way you would imagine it to have worked from the very first day.  I'll just leave it at that one.  So the next slide is really just to thank you and go out and try it for yourself.  And do you have any questions?  Saifah, please get a mic there right next to you.  Yes.  What's the idea behind slowing down the Raspberry Pi boot even more with more complicated stuff?  I mean, the one thing, if this doesn't work, people will go Googling and ask why it doesn't  work, everybody will tell them to go away.  Just boot the Raspberry Pi like it's supposed to boot.  It depends on what your goal is.  Is your goal to support the Raspberry Pi?  Boot the way the Raspberry Pi does it.  If you want to really actually do it the Raspberry Pi way, use the downstream kernel, use whatever  method you like, I don't care.  If you want to boot the Raspberry Pi, like you boot any random normal system, if you  want to actually go towards a maintainable future, you want to have that path.  But then it needs to speed up a lot more because I mean, it's a lot slower than booting a normal  boot.  There was a 10 second timeout.  Yes, it does boot slower, but that's all things that are going to go away.  The big advantage of this, in particular for the Raspberry Pi is that you now have a boot  menu to select different kernels.  Because the way it worked before is that when we updated a kernel and the new kernel for  some reason didn't work like some kernel head, and then you were kind of stuck and you now  had to take the SD card and put it into different machines, tweak siblings and so on.  And now with this couple seconds more in the boot process, you can just select a different  kernel if the default selection doesn't work and you still have a working system.  You can also add a command line on the fly from the boot loader.  It just basically moves your Raspberry Pi from a device that you target to a device  that you work on.  That's basically the shift.  It goes from this is something like an embedded device, like a mobile phone that I just want  to cross compile things on my PC on and then push them onto the device over towards this  is the device I'm actually working with and working on.  You would never imagine to directly flash your kernel into your flash chip on your PC,  would you?  Well, maybe you would, but nobody else who is saying would.  So would this also mean that if you have butterfs and the snapshots that it's all just working?  Yep.  But if it's snapshots, snapshot, wall-back booting, all of that just works out of the  box.  The other question I have is around Pixie Boot.  So Pixie Boot is not implemented by the firmware in that case, so it's really done on the UFI  side or?  Okay.  It's probably just a naming problem.  EFI is the specification that tells you how to implement these interfaces.  Uboot implements that specification and Tiano Core implements that specification.  You can use both to boot your system and at that point, because you're booting your system  from those pieces of software, they become your firmware.  So on the Raspberry Pi, Uboot is my firmware.  On your PC, a Tiano Core-based fork from your vendor is your firmware.  It's just a naming thing.  And that firmware implements EFI.  Or actually, it implements UEFI because it's 2.0.  But it will work.  That's the important part.  So again?  Pixie Boot will just work.  That's the important part.  Yeah.  The point about this is it won't be any different from a PC at that point.  As soon as you have your Uboot on there, it will behave as a PC does or like the overdrives  that we saw earlier do.  Just at a much lower price point.  More questions?  Size of relief?  All right.  Great.  Well, thanks a lot.  Thank you.
Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_0_203.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_204_2159.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_2160_2735.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_2736_3359.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_3360_5687.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_5688_7343.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_7344_8159.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_8160_9551.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_9552_9899.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_9900_11843.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_11844_12263.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_12264_13775.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_13776_14627.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_14628_17459.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_17460_17579.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_17580_19343.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_19344_19427.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_19428_21515.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_21516_21563.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_21564_22103.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_22104_24899.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_24900_27803.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_27804_28139.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_28140_28355.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_28356_29963.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_29964_31163.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_31164_31499.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_31500_32579.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_32580_32927.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_32928_34727.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_34728_35915.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_35916_36023.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_36024_36143.png Alexander_Graf__uEFI_grub2_on_Raspberry_Pi_bNL1pd-rwCU_36144_36263.png
Hello and welcome to my amazing talk about running every password you could possibly hear in a single device. EFI, Grub 2, Raspberry all at once. So, my, I'm Alexander Graf. This time for real. David was just faking to be me. I'm usually a KVM and QM developer. You might have seen me from things like running KVM, running KVM, doing KVM on power. Things that people usually seem to take us granted these days. But this time around I'm going to talk to you as a member of the Open CSARM team. So you saw on the headline the Raspberry Pi. That's what it looks like. You probably, most of you guys have seen one. I just took this image from our webpage. It also has a logo on it, which is cool. So why would you possibly want to buy a Raspberry Pi? That's very, very simple reasons. It's cheap as hell. It's available like nothing else. You can just go to a store, grab it, and it's on based. What more could you possibly ask for? But most of you guys probably want to run software on such a device, right? So you want to boot, which means you want to get into a system. Without booting on the Raspberry Pi, it's really, really simple. You take this board, then you take your SD card, and then you plug your SD card in, and then you take your power cable and plug your power cable in down there, and then it just boots. Unless you're the one creating the image that is supposed to make this thing boot, which is what we're here for, right? So let's take a look at the SD card. What does this thing actually look like? What do we have in there? That's the usual. We do have, the screen is really dark, we do have our root file system, we do have a swap partition. The usual stuff you would expect on a main device that you run your operating system from, but the Raspberry is special in one regard in that it also has a FAT partition. And that one's very, very mandatory on those devices because the FAT partition actually contains a few files that are incredibly necessary to boot such a device. The really, really most important one is boot code bin that just lies around on that FAT partition, that just tanks there. And it's so important because that's what is the initial boot code. That comes from the Raspberry Pi Foundation. It's actually GPU code, so the whole thing doesn't boot from the ARM systems, it boots from the GPU. This is GPU code that then goes in and reads the config text file, which is also on there to figure out what it should do, how it should look like, whether it should enable serial or it's what frequencies it should use, what monitor depth it should use. That's all written in config text with defaults, obviously. And we usually, if you have a Raspbian distribution, you also get a kernel on that FAT partition that you boot, which ever from the very first time we enabled the Raspberry Pi and an open suzer, we figured it was a really bad idea. So instead, we are using Uboot at that point. And Uboot then goes in and can actually break out of that FAT partition and go into your real root partition and read a script called boot script from there and load the kernel in a.d and device tree from your root partition, which means you can actually update files with normal RPMs. That was that different from how your PC boots. Very simple. Your PC boots first off by being a PC and not a Raspberry Pi. And then you have something, some storage where you put your firmware in. On the Raspberry Pi, everything's on the SD card. On a real PC, you have something sold onto your board where your EFI firmware usually lies. And that EFI firmware goes around and just looks at your hard disk, at your storage device, whatever they are, even a network, and just searches for something it should boot based on different algorithms. It finds something that it can execute and should execute in boot orders, which usually in our case, open suzer is Grap2, which then uses callbacks into EFI to proceed, load the kernel, run that kernel, and you're good. So you can see it's actually pretty similar to how the Raspberry Pi boots, just that you have a firmware piece of hardware rather than your SD card and you're not running off a GPU. But other than that, pretty similar. So what is this EFI thing really? The whole talk is about running EFI, right? So what is EFI and why are people so scared of it? I honestly don't know. Well, why they're scared, but I can tell you what it is. The really, really most important crucial core piece of EFI is something called the system table, which is just a pointer to a struct that has pointers to structs that have pointers to structs that have pointers to structs, and all of those contain either information or function callbacks. The most important one of them are the boot time services. That's basically a collection of around 50 function callbacks that you can call into to do different things during boot time. Grap2, for example, uses those. I just took a few most important ones out here. Obviously you want to load images, right? So the load image callback, if you have an image, memory, and you actually want to have it loaded into the system, you call the load image function with a binary that's EFI compatible. Anybody recognize what this might look like? You've seen that thing down there before? Yeah. It's a P executable. So basically the same thing that Windows uses. It's the same format. It's a pretty simple format, to be honest. A lot simpler than elf. So loading that into memory is not too hard. It's really just sections that you take and then put into RAM at different locations. And then you've got an entry point, jump into it, and that's all you need to do for loading. So loading an image is easy. The other really core piece of EFI is that it has a notion of objects. It doesn't call them objects, and it doesn't call classes, classes, but it is basically the same idea. So you have protocols, which are classes, and handles, which are your objects. And imagine you have a disk device, right? You've got a set of disks, your first set of disks in your system, and that one set of disks can implement a class called a block operation class. You never give names to anything in EFI. They're all based on IDs. You have really long, 128-bit long GU IDs, but this is basically just a class that says I can do block operations. And that consists of just a few function callbacks again, so all of these are structs, right? So this is a struct that basically tells you it's a struct. It's a struct inside a struct. And then in there you have function callbacks that you can call to read or write to such a device. It's very, very simple. And it can also have a second or third or fourth or how many ever you want different classes implemented by the same object. In the example of a set of disks, for example, you usually have a thing called a device path where you can find out where in your device tree this thing is. So this is like my disk is attached to a set of controller, which is attached to a PCI device, and then you can just walk through this path. So it's really just a simple means of providing access to objects. And objects can be arbitrarily enhanced too, so you can load another driver that then adds objects to your object list and exposes different devices basically with this. And the next really cool thing that EFI does, which is important for filmware, is it manages memory. You always want to know which memory in your memory space is already occupied and which isn't. So EFI maintains a memory map that you can always ask for, where it just says, all right, so at this address I have some space available, at that address everything's already occupied, at this address there's nothing there at all, at that address we got runtime services, I got to this later, and say down here is a lot of memory available again. If you allocate memory, what happens is that EFI basically just goes and says, oh, you want one megabyte allocation, all right, I'll swing down an existing available size and add one more blob for your one megabyte allocation, we turn this thing to you and that's it. It doesn't do anything beyond this. So if you don't free this, it will still be allocated by the time you exit your application, which by the way, grab two does. So memory allocation is really simple to you, you can always ask for your memory map, you can receive it whenever you like, it's always up to date, so you always know how much memory is still available for allocations. Console is obvious, it's just pointers to the console objects for standard in, standard out, and additional tables contain fancy things like your device tree or your ACPI tables, your DMI tables, everything that's just arbitrary data that you want to have somewhere in memory and know where it is, it's just put with IDs into those arbitrary tables. So it's just tuples of ID and pointer. Front-time services are a really, really cool thing in EFI. Imagine you boot your PC, you boot it up and you have a lot of RAM. And initially when you boot, of course, EFI is running there and EFI owns some of that RAM. Now EFI goes and loads grab, grab goes and extends itself, allocates a lot more memory, loads Linux into that space, Linux gets loaded into real memory, and then what? Well, then at this point, Linux actually is also an EFI binary that executes and talks to EFI and tells EFI, you know what, EFI, go away, I don't need you anymore. I'm done with booting, I don't need booting anymore. Please give me the machine, I want to have access to all of that memory without asking you for it. So it does that, but one thing that you can do with EFI is you can still preserve some of EFI in your memory space by having that blob be self-relocatable and Linux calls you with your new relocation addresses on it. So this blob is still available while Linux is running. So Linux can call into functions inside of that small space and then those EFI one-time services can still do operations on behalf of Linux. So this is code that actually is film work code that you just call into. And the most obvious examples for one-time services are get time, so you can ask EFI what time it is just to access the real-time clock. You can ask EFI to give you a variable or set a variable, you have some variable space in EFI and you can ask it to reset your system, for example. Please reboot now and you don't need to care about 50 different power management units or whatever you have out there, just reboot the system. So it's really a convenient hardware section layer for you. So how do we bridge UBoot and EFI? How do these interfaces even match? I mean, UBoot is a completely different world, isn't it? It's run for embedded, it doesn't have anything to do with a real cool service that do have EFI. Well, if we take a really deep look, memory management, yes, sure. We need to write new code to support all the memory management that EFI exposes in UBoot because UBoot doesn't have a notion or has a notion of memory allocations, but it's different from what EFI thinks it should be. But anything else, if you look at the network stack, well, there's a network stack in UBoot. So if we just write small web code, we can as well just access the UBoot web code, the UBoot web code from a random boot time service callback. Same goes for console, for disk. All the devices actually look almost the same on the interfaces if you really compare EFI interfaces and UBoot internal interfaces. So all we need to do to support calling into UBoot code from a boot time service function callback is to write a small wrapper that just converts function semantics for us. For one-time services, that's slightly more complicated because UBoot doesn't have any notion at all of one-time services. It only knows how to run at boot time and then tries to just completely disappear. However, it's not really hard to do either. We need to basically teach a function like the reset CPU function to be one-time service aware. That's a patch of about three to four lines at this point per function that we want to call. And at that point, we can just call a wrapper, run the CPU reset function, and you get fully working one-time services in UBoot. So I have enabled this for Raspberry Pi 3 or Raspberry Pi in general, actually, and the Layerscape 2085 systems. But adding new support is really a matter of a couple lines of code. So it's trivial. Get time. We don't implement it all. The reason is most boards that you have out there don't have a clock to ask. If you don't have a clock, you can't really return a working time. And same for variables. If we want to support variables, we would need to support storing variables somewhere and reading variables from somewhere that doesn't collide with what Linux actually uses at the point in time when Linux calls our one-time service code. We don't have those separate devices on most devices that we want to support with this. And for additional tables, very simple, we just put our device tree in there. We have a device tree. We can load the device tree. We put it in there. Done deal. And at that point, we actually have everything we need to execute an EFI binary, right? So if we take a look, this is just a boot log from a Zinc and P system. It just boots up into UBoot and then gets you to a shell. So what we need to do to boot an EFI binary on these with current UBoot. So if you just take UBoot 2016 or 5, for example, it's all implemented. What you need to do is load your GRUB binary, load your device tree, and call boot EFI. Done. Get a GRUB. As simple as that. So if you take a current UBoot, you can always just manually load an EFI binary, which could be GRUB, which could be Linux kernel itself. It's also EFI binary. Can be anything that you like. It could be the open BSD boot loader, whatever you prefer. But if we go back, actually, and take a look at this excerpt, one thing you might have realized while reading through all of these lines here is there's something down there that's called autoboot. So what is autoboot? Autoboot just means that UBoot goes in and executes a boot script that's predefined in the configuration. And on most systems these days, that's a distro script. It's just a set of templates that go through a list of different devices and searches for known good sources of booting from them. So really the distro script just goes in, searches your disk, and looks if it finds an EFI binary at the spec defined removable location path for EFI binaries. That's just part of the EFI spec. And searches if it can find the device tree. If it doesn't, it just doesn't load it. And then usually, of course, your EFI binary is grub 2. So you don't press any key at all, and it just automatically finds everything and you get grub. Which is pretty much how you want to boot these days. You don't want to mess with boot scripts, you don't want to mess with anything at all. You really just want to have things work out of the box. So are we standing? Pretty good. As you can see, everything is implemented. So we have EFI objects. We have console support. We have disk support. We can even do pixie boot support. I see pixie boot by now. Video support works. You can see graphical output. We can run grub 2. We can run linux. I have not tried to boot windows yet. There were patches on the mailing list to enable X8664 about two days after I posted my first patch set. So it really is not hard to enable a new architecture. But they haven't actually progressed since because the guy was doing something different since then. And I don't really care too much about booting windows right now. If you compare code sizes between enabling EFI support and not enabling EFI support, you can see that the difference is negligible. You increase your code size by somewhere between 10 and 20k. Which if your code is already 500 kilobytes big, 10 or 20k doesn't really account for anything at all. It's completely negligible. Which means that upstream we are now enabled by default. So if you just take Uboot and you do a dev config for a board, you get EFI support on today's Uboot. You don't have to mess with anything at all anymore. You don't have to mess with U images, with Z images, with anything. You just run grub and it works. Since I'm telling you that everything works, I should probably also show you that it works, which is more fun. So for the demo, I'm going to plug this Raspberry Pi 3 I got in here into the HDMI connector. And connect power. Let's hope this one works. All right, there you go. So this is Uboot. This is Grub 2 booting up with graphics and everything. All the bells and whistles you would usually know. If you have a USB keyboard attached, you can even use the USB keyboard to edit a command line, do whatever you like. You boot into Linux and there you go. You get a fully working distribution with just the way you would usually expect it to work with all the Yask boot loader things working, with all the Pearl boot loader updates working. Everything just works the way you would imagine it to have worked from the very first day. I'll just leave it at that one. So the next slide is really just to thank you and go out and try it for yourself. And do you have any questions? Saifah, please get a mic there right next to you. Yes. What's the idea behind slowing down the Raspberry Pi boot even more with more complicated stuff? I mean, the one thing, if this doesn't work, people will go Googling and ask why it doesn't work, everybody will tell them to go away. Just boot the Raspberry Pi like it's supposed to boot. It depends on what your goal is. Is your goal to support the Raspberry Pi? Boot the way the Raspberry Pi does it. If you want to really actually do it the Raspberry Pi way, use the downstream kernel, use whatever method you like, I don't care. If you want to boot the Raspberry Pi, like you boot any random normal system, if you want to actually go towards a maintainable future, you want to have that path. But then it needs to speed up a lot more because I mean, it's a lot slower than booting a normal boot. There was a 10 second timeout. Yes, it does boot slower, but that's all things that are going to go away. The big advantage of this, in particular for the Raspberry Pi is that you now have a boot menu to select different kernels. Because the way it worked before is that when we updated a kernel and the new kernel for some reason didn't work like some kernel head, and then you were kind of stuck and you now had to take the SD card and put it into different machines, tweak siblings and so on. And now with this couple seconds more in the boot process, you can just select a different kernel if the default selection doesn't work and you still have a working system. You can also add a command line on the fly from the boot loader. It just basically moves your Raspberry Pi from a device that you target to a device that you work on. That's basically the shift. It goes from this is something like an embedded device, like a mobile phone that I just want to cross compile things on my PC on and then push them onto the device over towards this is the device I'm actually working with and working on. You would never imagine to directly flash your kernel into your flash chip on your PC, would you? Well, maybe you would, but nobody else who is saying would. So would this also mean that if you have butterfs and the snapshots that it's all just working? Yep. But if it's snapshots, snapshot, wall-back booting, all of that just works out of the box. The other question I have is around Pixie Boot. So Pixie Boot is not implemented by the firmware in that case, so it's really done on the UFI side or? Okay. It's probably just a naming problem. EFI is the specification that tells you how to implement these interfaces. Uboot implements that specification and Tiano Core implements that specification. You can use both to boot your system and at that point, because you're booting your system from those pieces of software, they become your firmware. So on the Raspberry Pi, Uboot is my firmware. On your PC, a Tiano Core-based fork from your vendor is your firmware. It's just a naming thing. And that firmware implements EFI. Or actually, it implements UEFI because it's 2.0. But it will work. That's the important part. So again? Pixie Boot will just work. That's the important part. Yeah. The point about this is it won't be any different from a PC at that point. As soon as you have your Uboot on there, it will behave as a PC does or like the overdrives that we saw earlier do. Just at a much lower price point. More questions? Size of relief? All right. Great. Well, thanks a lot. Thank you.
I'm going to talk to you as a member of the Open boot from the ARM systems, it boots from the GPU. This is GPU code that then goes in and reads the which means you can actually update files with should boot based on different algorithms. It Pi boots, just that you have a firmware piece of pointers to structs, and all of those contain most important one of them are the boot time don't free this, it will still be allocated by it's always up to date, so you always know how much memory is still available for allocations. mean, UBoot is a completely different world, have a notion or has a notion of memory for additional tables, very simple, we just put into UBoot and then gets you to a shell. So what patch set. So it really is not hard to enable a Raspberry Pi boot even more with more complicated in particular for the Raspberry Pi is that you