 Good afternoon. Welcome to my talk about the UAV subsystem in U-boot. My name is Heinrich Schuchert. My name is Heinrich Schuchert and I'm working in my paid life as a software consultant in the ERP and in the supply chain area. But I've been contributing to U-boot since 2017 and I've been since the beginning of last year's maintainer of the UAV subsystem in U-boot. And now you may wonder why I got there and this is what I will start my talk with and then I want to dive into the internals of UAV so that you understand how UAV really helped me to solve my problems in booting from the network. So let's get started. So why do I want to boot from network? So I had a few little boards of the Raspberry size, not Raspberry itself and the fastest connector on these boards was really the ethernet port. They didn't have SATA, they didn't have PCIe and of course you could plug in a USB 2 converter to a SATA drive but a SATA drive still cost me more than the board itself and so I thought network booting would be the natural choice to carry on. And network booting exists in U-boot. So you can set up a boot P or DHCP server that will provide the address of a script then the script can be downloaded by TFDP and then you can boot from an NFS server but unfortunately as U-boot only supports UDP this server has to be set up that is running by UDP. There's no authentication at all and I thought oh gosh that's not what I want. And then I knew of course what we were using in our company and typically in a server environment you are running iSCSI or you are running using fiber channel or whatever. So iSCSI is not like some were serving singular files but it's really providing a block device. So it's like just a virtual hard disk that you have where you can put your own partition table on and create your partitions and then you will have your boot partition and your home partition and your root partition and it offers really authentication. So the server and the client can mutually authenticate each other. It's the chat protocol that's being used. So there's some common secrets those two parties have to use some challenge so that it's always the same being transferred. So yes you cannot not have replay attacks and if you need more security you could separate of course your storage array network from the rest of the network via VLAN or use IPsec for encryption. So this is what I wanted to do with my board which was running Uboot. And Uboot is one of the most common firmwares for those little boards for booting. So I looked at the specifications started implementing a bit in iSCSI and so it's tedious and hasn't anybody done it before? Why should I do it myself? That's when I came upon a software called iPixie where the main developer is Michael Brown and it's just like a Swiss Army knife. It has influenced lots of different protocols. The origin of it was just a replacement ROM for your network card for doing pixie booting. But now it can support booting from HTTPS server from iSCSI that's what I'm interested in. It can boot via fiber channel over Ethernet or ATTA over Ethernet. It has its own scripting language and it can be built as an UAV payload. And that's when I thought okay on my workstation at home I'm having UAV booting my X. Sixth computer. So does this also exist for Uboot? And in 2016 Alexander Graf at that time working for SUSE and now it's at Amazon. He was really starting to implement the UAV standard inside Uboot. So the driving side for his company SUSE at that time was that they wanted to boot all devices the same way. They said if you boot a server by Grubb and then Grubb loads a Linux kernel we want to do the same on a Raspberry 2. And that's why SUSE was interested in getting UAV into Uboot which was running on those small boards. And I said oh that looks complete. So if I pixie I can compile it as an UAV binary, run it with Uboot and great. That's what happened. I just got a return code a bit cryptic but if you convert it to hexadecimal and look it up you'll see it's error code 9 out of resources because there was only one event possible. That was really the reason. I said okay maybe now everything is there let's try compiling a hello world. Just writing hello world on the console and then do a return statement. And it crashed again. Because Alexander assumed that every executable would exit via the exit API call. And that's when I really thought okay that seems to be really something that has been started but needs some support and that's when I got into this. So I started sending in the first patches mid of 2017 when there was really it could barely boot Grubb and via Grubb you could really boot into Linux it was working but nothing else. And in 2018 with the May edition of Uboot I could finally really run a pixie and boot from my ISCSI server. And of course the voyage was not finished there so it was still not really conformant with all the details of the AFI spec. And finally last year we got it to a point that we could run the AFI shell that is a shell like the DOS shell really primitive but you can run different binaries you can set variables you can have a small editor even in there and this is the basis that you need to run the self-certification test that life and art had been talking about. And so I have written about 60% of the AFI code but they were in total 40 contributors contributing to this to get to running. And now you may ask yourself where is really your AFI sitting because when some people talk about your AFI in the x86 world they are just talking about as if it were the whole bias the whole firmware is a UAV no UAV is simply standard it's defining an API the question is where is it used so what I have put here on the board is just the boot process this trusted firmware as it's running on 64-bit CPUs so where does it start really the CPU has a little ROM which knows the first part of the untrusted firmware which then boots the BL2 trusted boot firmware which then runs through the next part loading BL31 which is the exception level 3 runtime in this runtime you find things like the power state coordination interface which is responsible for resetting a board so they provide already an API which then can be called by UBoot for resetting a board it can but not always does also boot in the secure world an extra operating system where you can run for instance OPTI this will come in handy if you really want to have secure boot because we could use it for storing variables that is something that Leon now is currently thinking about and yes of course the BL31 also loads BL33 which in our case is UBoot but there are of course other implementations like tianocall, eDK2 like we heard in the last call and now UBoot or eDK2 they are offering this API which is defined in the UEFI spec on 2500 pages and now this spec defines different API calls we will look into and these can be used by Ipixi to communicate with UBoot or eDK2 and they can also be used in Linux for the same sort of communication so when we now start a UEFI binary what is the first thing that it sees it simply gets a pointer it gets a pointer to the system table and the system table contains different services that are available and by these services it can also discover some protocols which offer additional APIs and you have two major parts in there and the system table, the one thing is boot services this is what is available until really the operating system is running and when it's running only the runtime services are left over for instance those services that are necessary for rebooting or setting boot variables and there are also configuration tables passed we heard Art that he said currently we are passing the device tree can't we get rid of passing the device tree in here as a configuration table so servers use instead API and also we have an SM BIOS table passed and if you look at the protocols they are really providing things like network access, they are providing access to block devices so if you now look into what are the atoms really of UEFI there are two object types there are one thing that is handled this is just a pointer on which protocols are installed and there are events that are triggered by time and then called back into the binary also can be triggered by a call of one of the services if you think about what is the lifetime of such an object, of such an handle it's created when the first protocol is installed and it's deleted when the last protocol is removed when we look into drivers what will be coming interesting in a second is a driver is simply a handle which has a specific protocol installed on it so it's a piece of software when it's installed the handle is created the AP driver binding protocol is installed and here you see what really protocol means the protocol is just a structure a pointer to a structure and it's a GUID which identifies this protocol and in the protocol interface for instance of the AP driver binding protocol you find there are three functions in it supported, start, stop and there are three data fields which version the handle of the image that was loaded to get the driver running and the driver binding handle and on the other side of course there are the devices also in the specification sometimes called controller and this is a handle which has an AP device pass protocol and which you could use just to get an overview of what devices really exist I've just printed out what I had on my laptop where you for instance see there's a PCI route on the PCI route there is some NVME drive and on the NVME drive there is a partition existing and the same thing also for the on the SATA side this for example is just of such devices that exist there and now how are drivers and devices attached to each other in the boot services there's a call called connect controller and this one calls the supported function of the protocol finds out that there's a match then the start method it's called of the driver binding protocol and then the driver is really started it installs its own protocols on the controller for instance if you have a hard drive and the hard drive asks okay who can serve me then maybe the controller will install a fat file system on it and it also may create child controls or extra handles it may break and if you now look into how this is put into the picture with iPixie on the right side I simply have some parts of U-boot there's a network driver for the network driver inside U-boot there's a simple network protocol exposed and there's also some driver existing AP block device which exposes the driver binding protocol for block devices and now when iPixie is loaded and running then iPixie installs a TCP IP driver this is necessary because U-boot doesn't only knows UDP it installs an iSCSI driver and uses this iSCSI driver to connect to the server and installs on the drive that is connected to a block IO protocol and then calls connect controller and this connect controller then reaches out to the block device driver in U-boot which then uses the fat driver that exists and the logic for identifying partitions to expose a simple file protocol and this simple file protocol then can be used by iPixie to actually load GRUB or directly load Linux and essentially GRUB then will do just the same thing GRUB when it tries to load something it will call the simple file protocol which internally calls the fat driver and knows ok i'm connected to that handle with the block IO protocol which links back to the iSCSI driver the iSCSI driver by the TCP IP driver calls the simple network protocol driver and then loads the different blocks of Linux and of the initial RAM image this is how these all go together in short movies oops, we'll get it so that's where it's actually starting to boot so here first of all U-boot tries to find its own devices like USB devices it finds its SD card and then the script is running which simply loads iSCSI and known as iPixie iPixie loads GRUB and then GRUB just continues as we know it to load the Linux kernel for me the take away really was by providing a common API we really can run standard software on U-boot before that we could only run maybe on the PC but it has no way if the BIOS or which was running channel core or whatever and now suddenly we can run things like GRUB iPixie when we think about what was problematic in doing all this one thing really that was nasty about U-boot is that it's running single-threaded it has no network interrupts and so for implementing events in lots of different places one really had to call back into some routines that would handle event queues he was waiting for an event and call those functions so that was one part of the nastiness in it another thing is U-boot is more than 10 years old and of course it comes with its own history and the model how drivers are implemented in U-boot is currently changing it's trying to get more modular this new model based on device trees installed inside U-boot but it's not used everywhere and this really stops us from getting a very tight integration between the AP code inside U-boot with the drivers it really sits more on top of it it's being really well integrated and that's something we will have to work on once we get the driver model really firmly established when we look into what are the development targets for UAV inside U-boot it's not the idea to implement all those 2500 pages and then come up with a binary which is several megabytes long the target of U-boot has always been should boot on a very small board and this is why we will only implement a subset of UAV there has been an effort led by ARM to define a restricted subset which is called the embedded base boot requirement specification which is available on github which requires that you have all the boot service in place you have the runtime service in place and there's one chapter which defines some other required elements that you should have and we really want to stay small so I often get complaints the UAV part is already growing too much currently it's something like 70 kilobytes in the firmware and nobody will be happy if it gets much bigger so what have we achieved last year now we have all those all boot service in place we have, as I said we were able to run the UAV shell which allowed us to do self-confirmity test and this is conformity testing using the SCT we were able to fix a lot of differences to the specification especially conformance issue where we're not checking the incorrect variables being passed and we can run the AFI shell on ARM on x86 we can run the SCT and now let's finish off with what is work in progress we have just merged a work by Christian to Caltea so that we can have a verified boot which is based on fit images there's Ninaro there's Takahiro Akashi working on UAV secure boot what we already have merged is support for hardware the number generators and so I'm confident that we are improving bit by bit thanks a lot for your attention and it's up to your questions yes please the question was IPXI located personally always loaded from the AP partition so I have an AP partition and I have the device tree and IPXI on my SD card and everything else grab the kernel and the RAM disk is then loaded via SCT it's essentially what is in the EVBR so the question was which parts will be implemented and that's why I mentioned the EVBR and we have implemented some extra things that were necessary to run the shell to run the conformity test because they require some protocols that are not in the EVBR yes please the question was can we really run extra drivers we have everything in place but I have not seen any implementation using this so currently in U-Boots there are drivers for all sorts of storage devices for a network and for USB and at least a network and the storage devices we are exposing via UAV protocols without any extra driver having to be installed but if you say there is some sort of special device which you want to expose then you could load a driver that you have written yourself yes this is in place yes please the question was how configurable is the UAV subsystem if you look into the configuration of U-Boots it's like configuring a Linux kernel we are using just the same key config system and some parts are optional that you can leave out or you can completely eliminate the UAV subsystem if the board is really too small there are some boards that only have place for firmware and you cannot have the UAV subsystem but if you have 600 or 700 kilobytes it will well fit in thanks a lot for your attention