you . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . trusted firmware and then that in hand starts up your opti and finally it goes to the main new boot image which finally loads your Linux kernel. This is a very typical boot flow. This is what you see commonly but it's talking about one core right. When you think about it you're talking about one core but that's not the case with chips today. So what if you have multi core systems. So an example would be the Texas Instruments K3 architecture of devices and here you we have two cores running. So you have your 32 bit R5 core and your 64 bit A72 core. Now in this case we need two sets of SPLs right to get it going. So your as you can see I've inserted two SPLs in the boot flow and your R5 SPL will run first. Do the initial stuff and then it'll jump to ATF again to opti and then your Uboot SPL for your A72 core comes up and then finally you boot to Linux. So this is how it looks like. Now in this presentation in the interest of time I'll be talking about the A72 bootloader mainly not the R5. So yeah that's what I'll be talking about. So what do we need for the A72 bootloader? You'll need your ATF, you'll need your opti binary and you'll need DM firmware. DM is device management firmware. It's kind of like a TI version of ARM-SEP and then you'll have your SPL binary and then you'll find your device tree blob right. So let's say I want to make this position agnostic my final bootloader. So I can just append or prepend the fit header at the top so that the entire image is basically position agnostic. So that's what I've done over here and what about security? You obviously need security. So you have your X509 certificate appended to the top of each of your binary blobs. So basically it's signed all of the blobs inside are signed and this is what our final A72 bootloader binary looks like. So as you can see it's not very simple. I mean you can run it through a simple shell script and get your final output but it wouldn't be, it's not really the standard right. This is how we used to go about generating our final binary. So you can see I have U-boot. You basically give all the inputs. You give your opti or device manager firmware, your ATF and U-boot has custom scripts, a bunch of long shell scripts that used to you know tie up everything, sign everything, stitch it up into a final image. So this is what we used to go through. But in cases of higher security devices you'll need to have a core Secdev K3 which is an external TI maintained repository. And this is how we used to sign the images a few months back. Obviously there's a lot of issues with doing this. One is maintaining and scaling. It's a non-standard flow. It's for example let's say we already have more than four bootflows at present and extending it to all the bootflows you know where the binary will have to change. It gets difficult. Packaging gets difficult. And this is not the standard. It's not distro friendly. And there's no unit level testing. They're just shell scripts. You don't really, if it works it works. There's no test coverage there right. So these are the issues with the custom scripts. And this is a small snippet of the shell script that we used to use. So you can see unless I showed you the final image what it used to look like. I don't think you can gather much from this script. And you can see the highlighted ones are pointing to external scripts. So you have scripts within scripts and it's just a mess to get to know what your final image looks like. So yeah. Thank you. So just a little talk about Binman why I started writing this tool a while ago now. Packaging is actually much harder than we think. And you can see an example of that there. Some other things that go on. There are SOC specific tools that need to run. And as mentioned before there's different phases of the boot. And the image needs to contain code for all of those. It's also nice to be able to see what's actually in the image. And so this this bin man tool lets you look at an image and list it out. So the image is described as data. So rather than shell scripts or code or whatever you describe the structure of the image in a simple data format. This image has U boot and it has SPL. It has a size of one megabyte and it has some pad bytes. So that's basically how you start. Binman normally runs as part of the U boot build. So it's the final step after all the inputs have been created. You run it runs build man sorry bin man and produces a final image. But the nice thing is you can then use all those inputs and run it again separately maybe in a signing server or in some other step in production. So bin man also deals with missing blobs. It deals with tools that need to run and so on. And it can produce an image even you know even telling you that this image won't work but at least you're able to validate that you could get that far. Bin man consists of it works with a list of entries. Entries have a different type that you've seen the U boot ones and the SPL ones but there's loads of other ones as well. And they just packed one after the other. They normally can't overlap but it is possible in extreme cases if you want to do that. Bin man is written in Python. There's an entry based class. You then have an entry blob subclass of that if you like. You can see that in the middle of the screen and you can sort of extend it from there. So a blob is just basically an entry that has a blob of data in it. But you can make arbitrarily complex things that involve you know producing signatures and that sort of thing and it's fairly easy to do that. To add an entry type you basically put a new Python file in the right directory and give it a give it a class name and off you go. You can I mentioned you can run command line tools. It's actually possible to list out the tools that are available. If you don't have one you can do bin man tool minus F to fetch it and it will go and build it from source or find it in the binary or whatever it has to do to get the tools. So you don't have to go and hunt around for three days trying to find vendor tools. The code has a lot of comments. It has 100 test coverage. So it's very very strongly designed to to be reliable. That's it from me. Yeah so now you've seen how what bin man is and the rest of the presentation is going to show you how we switched rather migrated from what it used to be with shell scripts to using bin man. So this is what the final flow looked like. There's no external repository. There's no custom scripts. It's just a bin man device tree file that we've plumbed in along with the other inputs. So this is what it finally looked like. So as you can see just like the image on the right which is our target image. So you have a fit node within which each of the individual binary blobs that have to go in. So your a t f your opti or dm all of them are kind of packed in nicely. And you can see that ti secure is an entry type that we've created to mimic not mimic actually generate the x509 certificate that has to go on top. So it's being passed the contents. So the binary that it has to sign which is in this case the a t f binary and the key with which it has to sign the binary. So it's all nicely packed in and now you have a somewhat visual representation of what's going on and you can manipulate it easier easily. And yeah since I didn't get space. So this is the remaining of the two blobs that have to go in. So you can see there's a few things that you can notice from here. So one is yeah there's a custom entry type that we've defined and along with which there are standard entry types that we've used. For example opti and a t f their arm standards. So you can have the standard entry types defined as well. And it's already there in the bin man folder. And at the same time let's say you want to reuse the same device tree for building many different boards. And let's say each of the board is using a different address to load your a t f. And that's also easy to plumb into the bin man flow because it evaluates config options. So according to your build your config will change and yeah. So to kind of finish off we'll just quickly go through what the python class looks like for TI secure for the x509 certificate. So you have a special method of python in the beginning. So that's just there. And this would do the reading of the node. So you can use your FBT tools to go and grab the properties that you've mentioned in your device tree. And you can even add your own properties. That's also possible. So for example sha is the property that we are going and grabbing by default it's 512 if you haven't mentioned it. If you want to change the sha value you can give that property in the bin man node itself. And then this would be the method that you know is kind of important which is actually setting the contents of your entry. So in my case I've defined a get certificate function that actually goes and runs open SSL on the binary that you fetched and put that in the entry. So obtain contents is what is doing that. And in the case of for example you have a u boot SPL which contains the symbol to your u boot image that you want to jump to. So there's cases where you'll be writing symbols so your final image would change. So process contents runs after at the end of your build so that it'll go and update your binary essentially in your final image. And here's another last method that was used which open SSL is already a bin man tool. So it's already present there and like Simon mentioned all tools can be all CLI tools you can easily port to be run within bin man itself. So here you're just adding the open SSL tool since we'll be using it. Now we're kind of towards the end of the talk. Some of the developments that are ongoing is for example the bin man dt node is not part of the device tree specification as of now but Simon has been working on it and that's an ongoing work. Then the ability to pass custom firmware via the CLI argument. For example let's say I want to pass the dm firmware argument as an actual CLI argument instead of hard coding it in the bin man dtsi that's not supported as of now without making changes to the original u boot make file. So yeah that's also something that that is in the works and finally the x509 template that that is used to generate the final certificate that's in some ways kind of hard coded right now even though it's a very standard tool that should be generated on the fly. So that that is also something that's ongoing. Now there's a bunch of u boot boards that still use custom scripts today and they can all be ported towards using bin man which is the final aim of this presentation to get everyone to finally port and use bin man as the standard. So some of the references I've used mainly the u boot documentation Simon's talk at OSFC and my colleague Brian's bootloader presentation as well and you can also see the patch series that was used to port the entire k3 devices to using bin man. Yeah lastly I would like to credit the FOSTA organizers and Texas instruments and the u boot community that has actively been working on bin man. So yeah now we are open for questions. That's not really. So the question is how does bin man relate to make image the make image tool? The bin man calls the make image tool. Bin man can produce fit images as you probably saw you simply just write fit in there and you get one. So it's a lot more convenient. Make image has the SOC specific stuff. There's no plan to you know rip all that c code out and write in python and bin man. It's simply make images is sort of one of the tools if you like that bin man uses. It's actually already part of the r5 bootloader which is a little bit more complicated which is why we didn't cover that. The question was if you can kind of recursively sign the images so a signed image within a signed image and you can do that which is a part of the r5 bootloader. We'll be sharing the slides so you can have the r5 view as well so that it'll cover that. The images are actually hierarchical so if you want something you put it here if you want the data that comes that goes into that you put inside it and you can just keep going right. So that's one of the nice things I think it's the I can't remember what it's called Mesa or something that uses sign within signed and it's simply a case of putting it in the description. So I think you're talking about changing the key once the images. Yeah that is also possible. You want to take that? I don't know much more about that but yes you can. So the public key has to go in a prior stage but because you're producing a cohesive firmware image right where all the phases are essentially have to be there then yeah bin man can can stuff the key from one into you know that's used in the next phase into the prior stage firmware and that's obviously necessary. Yeah yeah. Yeah so if you look at the DM firmware right now that's an external blob. Oh the question is huh? So you have to mention the blobs that you so the question is whether we can include external binary blobs into the final image and whether we can use scripts to generate an image and then you know port that into the final bin man made image. So the first one is yeah you can reference external blobs like I've done here. So DM is a blob that's not in the flow so it'll go and pick that up as an external binary and in terms of scripts so UBOO does the first build and then basically you can mention the binaries that are dependent that that that have to be created before bin man can be run. So you can mention that so you can maybe run your script before that and get your binary ready and then bin man will just do the packing. So it'll only run once the input binaries are ready to go. So is this already upstream? Yeah this is already upstream. Yeah. Any other questions? Thank you very much. Thank you. you you you you you