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