 Hello, everyone. My name is Alejandro Hernandez. I am a software, embedded software developer at Xilinx. And I've been a Yachto developer for what year is this? 2018. So I first started working at Yachto at Intel in 2014. So it's four years now. And, well, I'm going to present this couple of slides about how to create your own tiny Linux based on pokey tiny. The title is a little different than why I initially submitted because I decided to put an actual example of what I did. So you guys can base it off on that. Yeah. I know it's after lunch, but bear with me for the next half an hour to 45 minutes. So first of all, the agenda is that we're going to talk about what is pokey tiny to explain a couple of things. I'm going to have to talk about a little bit about what it's a distro in Yachto terms. And after that, I'll talk about what's pokey tiny or what does it include, I guess, in this year, the latest changes. After that, I'm going to go through the process of creating the actual other distro based on that. So first is what I actually need on my new distro. In this case, Pelomix Tiny is my case study. And the actual process of creating a new distro and all that. So first of all, what is pokey tiny? How many of you know what is pokey tiny? Can you raise your hands? Okay. Not that many people. How many of you know what is pokey? Oh, good. We're good. All right. So pokey tiny is a distro that's based on pokey, which is the reference distro for Yachto. And it was first introduced actually here at ELCE, I think it was in Prague, I'm not sure, in 2011. I wasn't even here. So yeah. By Darren Hart. And his presentation is a little different than this one, because his effort was the initial effort to what became the actual distro later, right? At that point, well, the distro had a kernel, obviously. It used EG-Lib C. It used UDEV, and it provided login prompt after booting. His presentation focused more on explaining how to decrease size and boot time, like very specific things that you can do. A couple of things that he did was to remove or trim unnecessary components in user space. He basically did a switch from EG-Lib C to UC-Lib C. He switched to using BCBOX, removed UDEV. Regarding the kernel, he removed kernel drivers and modules. He dropped networking support. In his own words, he crippled BCBOX or the kernel. Like, for example, he didn't have printk, for example. So those are very specific things that you can do. And in this case, this presentation, I'm going to be focused more on how to create the distro and what you do to make it smaller after some point, it's up to you, basically. The reason for this is, well, nothing in life is free. I'm not going to come here and tell you how to solve all your problems, have this magical thing that boots really fast and has all the functionality, so it's not possible, okay? There's a trade-off between functionality and size and boot time, as well. So you have to lose some stuff to gain some other stuff. So time change between 2011 and 2018 has been seven years. I'm going to explain a couple of new things that we have in Pocky Tiny. We do the Pocky Tiny, its purpose, it is to decrease size and boot time whenever possible. And like I said, I'll focus on creating the actual tiny distro, not Pocky Tiny, the one based on it. Okay, so what is a distro? And this is not like a Linux distro. I'm talking about distro as in Yachto terms. How many of you know what is a distro? What is the variable? Because it's a variable on OECore. What does it actually do? How many of you know that? Okay. So distro is something you define, well, this is the actual definition from the mega manual. It says distro variable corresponds to a distribution configuration file whose root name is the same as the variable's argument and whose file name extension is comf. And that may seem convoluted, but it basically means that there's a file called whatever the name of the distro is within the layer. So in this case, there's two examples. There's a Pocky, and I put just two examples. There's one called Pocky and Pocky Tiny. They're both on the distro layer for meta Pocky. Okay. Here it's an actual example of what is on the Pocky Tiny configuration. And the first thing it does, it defines the new distro name, which is Pocky Tiny. Distro overrides. Oh, well, the first thing, sorry, the first thing that it does is it says require comf distro Pocky, which means that this, the Pocky Tiny is going to be based on Pocky. And we're just going to override a couple of things that we don't want, right? So, yeah. Then we redefine distro overrides in which we add, we already had Pocky. We add Pocky Tiny to it. We define the state library that we're going to be using for our distro. In this case, we're going to use muscle. The preferred provider for the kernel is going to be Linux Yachto Tiny, which is not the same as Linux Yachto. And the dev manager and the login manager are BCboxMdev and BCbox for the login manager. In MetraFS types, we also redefine, and we say we want CPIO, GC as a format. And I want to be clear that distro is not the same as image. So you can have several different combinations of those, and we're going to see an example of how they perform, I guess. So first of all, the basic, most basic thing, I guess, is when you start using Yachto, you're like, okay, I'm going to build an image. You build core image minimal, and the default distro is Pocky. So when you end up with this, you end up with Pocky plus core image minimal. A few of the data that we get is that the root of fast for this configuration specifically ends up being about four megabytes, the kernel is about seven megabytes, and the boot time is 9.1 seconds. This is done on QMU, by the way, just specifying. So this image, what does it contain? The base utils, which is what I'm naming many, many things that like LS, CP, everything like that, it's coming from BCbox in this case. The C library that's being used is Glib C. Remember, this is Pocky, this is not Pocky tiny, this is the base thing. It's Glib C by default. The dev manager, it is Udev, or EUdev in this case. And other things, like, such as like, as you log in, as LSBLK, U mount, make file system, all that stuff comes from the package utilinux. So we're going to, like, analyzing the size of the components, we can see, there's several ways of doing that, but in this case, I decided to show the, this is the log for when root of fast is actually created. So those are the packages that are built, and then they're basically installed. And it shows the sizes of some of the components, and I highlighted some of those in red, which are the biggest ones, the largest ones. The BCbox ends up being 252 kilobytes. EUdev, it's 249. Glib C ends up being 1.3 megabytes, and utilinux, as I said, it's 422 kilobytes, but as you can see, there's a bunch of other packages there. So those are the ones that composed most of the distribution itself, right? So we ended up with 4 megabytes at the end. And, yeah, boot time, I didn't put it here, but it's like about nine seconds, okay? So the first thing that you guys can do is, okay, I'm going to switch my distro. I'm still going to use core image minimal, but I'm going to switch my distro to pocky tiny, which is done easily by just setting the distro available. Distro equals pocky tiny. What happened here is that I ended up with a root of fs of 1 megabyte, the kernel ended up being 2.7 megabytes, and the boot time was reduced to 5.2 seconds, which is, you know, it's good. Base utils, again, it still comes from BCbox. The C library, now it's not Glib C, it is muscle. And this is also something that it's on the file here. It's the clar right there. DClib C equals muscle. So now I'm using muscle instead, which is smaller. The dev manager, for the dev manager, I'm using BCbox Mdev instead of Udev or Udev. And other stuff, instead of coming from YouTube Linux, I chose it to come from BCbox. This is basically the same file. I highlighted, again, some of the couple of things. BCbox is 293K. BCbox Mdev is 8.6K. And muscle, it's 250. So comparing each of those, you know, Glib C is 1.3 now, muscle is 250. Now, something interesting here is that BCbox is actually larger, right? It's 293K instead of 352. So we kind of lost 40 kilobytes. But the reason for this is that I chose to use BCbox for more things. BCbox is just an alternative, right? For many of the main things that we have. So instead of using Udev Linux, I saved up all those 422 kilobytes, and now I lost 40 on BCbox. So this is one of the most important things, I guess, regarding the distro.conf file that I show you. And the basic, basic thing, there's a very complex way in the way that distro right works. But the very simple thing is that it's going to let us use underscore pokey tiny or whatever distro right we set on our recipes, right? So, and then also, for example, another example is that we can override certain components configuration. For example, BCbox. So BCbox has its recipe in OECore, right? And it has its own DevConfigure there. But when you choose pokey tiny as your distro, that DevConfigure gets overridden by the one coming from the distro layer, which is coming from metapoky recipe score, BCbox, BCbox, and then pokey tiny, which is the actual override, and then DevConfig. This is just like a very simple example of how, what changes. So instead of, I mean, I added, or the BCbox DevConfig in pokey tiny adds fdisk swap on off or you mount, and it deletes ccat, bzcat, diff, awk, you know, several things are deleted that you don't need. You can basically override it and then say, make it either smaller or bigger, depending on what you want. Okay, so pokey tiny in 2018. Like I said, this was introduced back in 2011. And there's a couple of changes that we did last year. So one thing that we did is that we created an image that should, it's not the distro, but it should be used in conjunction with the distro. And some of the things that we wanted with this image is that we wanted to provide a tiny root of s, but to provide a little more functionality than the one that we had. We wanted to improve boot time. And we also wanted, or the way of doing that basically, what was booting to the RAM instead of an actual device. The way we did this is that, well, we changed the boot process a little bit. The boot process usually goes to the boot loader, and then it loads the kernel. Then what we did is that we load the tiny root of s, we loaded as a cpo file on an init ram disk. And then that tiny root of s, we created our own tiny init, which replaced the actual, the init process, process number, PID1. And with a very basic one that we created, just a script, what it does is it mounts virtual file systems, you know, proc, dev, everything like that. It starts udev, and it starts drop bear as well as other services that could be there, but we decided to put drop bear there because we wanted, as I say, functionality on this root of s. And after that, but before switching to root, it just drops to shell. The big difference here is that you already mounted the file systems. So if you just choose to drop to shell or choose your init process to be sh, you're basically just dropping to shell, but you don't have access to all the file systems. So you can run anything that needs access to proc, for example, just top or anything. You can. And in this case, with this tiny init, you're able to do that. So core image tiny in conjunction with pokey tiny gives us this. The core image tiny in the ramfs image gives us the root of s of 1.1 megabyte. This is the CPIO file that I mentioned. The kernel is 2.7 megabytes. And the reason for this, like it didn't change is because we use the same kernel that pokey tiny used. And the boot time was reduced to 0.93 seconds. So it's actually a lot better, right? We had, I think, 5.2 or something. We have 0.93 seconds. And I just specified right there that I put bcbox mdev as a dev manager instead of udev. Because if you use udev, it's going to take a little while longer. Not that much, but still. The main components for this are still bcbox for base utils. The C library is still muscle. The dev manager could be either udev or bcbox mdev. In this case, I just put bcbox. And other things also come from bcbox. We added drop burr. Like I said, this is not on the other image. And in this case, there's a difference. Because since we switch to just like the drop to shell, we don't have a login prompt, okay? Just like literally just boot there. And then you say you have shell access. This is the boot log of the core image tiny. And I highlighted a couple of things there. The first one is that I put trying to unpack the first image. And I highlighted that because that time it takes from 0.40 seconds to 0.61. It's literally just extracting it, right? So it depends. It's going to be affected by your how big is your CPIO file. A couple of things. You know, I highlighted the input because you might not need that. You can take that off, for example. This is where you start like checking what do I actually need? What can I take out to make this boot faster? And my base point, I guess, for when the kernel is done is when it says freeing unused kernel image memory. And that was in 0.93 seconds. And as you can see, I did get the shell prompt, I guess, after 0.93 seconds still. There's an error right there. It says in it, UDEV, ADM not found or the demon. And that is because I chose BCBoxMDev and that doesn't have that command. But the tiny in it does. So it's just fixable really easy. Or if you use UDEV, that's when it would get started, right? So pros and cons of this, it's a read only root of s. Whether you think it's a pro or a con, that's up to you. It does provide faster boot time for sure. And a couple like example applications could be network devices. You need something that boots really quickly and process things really fast. I don't think I put the memory access, use memory on this, but it's a lot less. Another thing would be to upgrade the system. So if you want to upgrade one of the low level components, you could have your own tiny distro that has enough DNF capabilities to just perform the upgrade or have several partitions, that's up to you. Basically anything that needs Linux and requires it to boot fast, but you still need that functionality there, right? This is just a comparison between what I just explained. It might be a little confusing, but there's three sections here. I'm going to call these sections and then each of these sections has three columns. The first section is the size of the root file system, the second section is the size of the kernel, and the third section is the boot time. And each color represents one of the combinations that I chose. So the first one would be pokey, the distro pokey with core image minimal. Second one would be pokey tiny with core image minimal. And the third one would be pokey tiny with the tiny image, okay? So at the beginning, as I said, we had the root of S size for the pokey and minimal was four megabytes, and it was reduced up to one megabyte, and then I don't know if you can see it, but it's a little larger, the one for tiny and tiny. The size of the kernel was reduced from, I don't remember, seven megabytes, I think, 2.5. And both images used the same kernel, so it's 2.5 for both. And then the boot time was reduced from nine seconds to .93 seconds, well, in two iterations, right? The first one is 5.2 or something. Okay, so that brings us to, that's just the reference distro, right? If you just, like, do whatever, that's just on core, you can test it, and that's what you get, basically. But now, what if you want to create your own distro, and you want it to be tiny? So this is the process of what I did to create my own. I should specify that Petal Linux is that, Petal Linux is both the tools that silence gives to the customers, to the vendors, and it's also, in Yachto terms, is the name of the distro which is used to create that tool. So throughout this presentation, I'm going to talk, when I say Petal Linux, I mean the actual distro, okay, not the tool. And in this case, I create another distro called Petal Linux Tiny. So the first thing, the Petal Linux distro in Yachto, this is what I got at the beginning, right? I was going to analyze it and I was like, okay, so we got two images, we got Petal Linux image minimal, we got Petal Linux image full. And basically, a couple of things that they provide, the minimal has Drop Bear, canUtils, PCIUtils, kernel modules, stuff like that. The Petal Linux image full, though, has a lot more stuff. Qt, OpenCV, Video for Linux, Gstreamer, Embra, Python, a lot more things, okay? They're both based on the core images. And this is what I initially got. This is on the emulator, by the way. So I initially got a root of FastFile system of 13 megabytes, the GC file. The kernel was 15 megabytes. And the boot time on the emulator was 42 seconds. And I was like, okay, this is not as minimal as I thought, but okay. And there's a reason for this, right? This is an actual product that we, customers needed to work for most applications. But yeah, if you do have an application where you need to boot really fast, there's things that you can do. The main components for this, like I said, this is based on minimal, from core. So it's going to be a lot similar. Or sorry, on Pocky. The base utils come from Busybox, C-Library comes from G-Lib C. The Dev Manager is easyUdev, and Util Linux provides us with other functionality. So one thing that you can do to analyze your boot time is that you can use Bootchart 2. This is just the commands, basically, what you need to analyze that. Image installer pen, Bootchart 2 comes from core, so it's not, there's nothing extra there. And on the kernel command line, there's a couple of things you need to add. You need callDVoc, printK, time equals Y, quiet, and then, there's two main things here. The main thing would be you're switching in it, just to test, okay? You're switching in it to Bootchart D, the demon coming from Bootchart. And that's because you want it to run as PID1. You want it to be the first thing that runs, so it starts getting data from everything as soon as possible. And this time, part of the work that Bootchart D does is that it gathers data, and then it switches to the actual init. So I chose my tiny init there as well. After booting, you do Bootchart D stop, which basically stops getting data. And that's because you want a better resolution. And on your host, at the end, you just call another script coming from the Bootchart 2 package called PIDBOOTCHARTGUI. And the BootchartTGC file is the one you got after calling BootchartD stop, okay? So the data is actually on that TGC file, and the PIDBOOTCHARTGUI is gonna create an image from that. And I was hoping you could see more than me, but apparently not. This is the Bootchart, this is what you end up after getting the data from Bootchart. As you can see, there's like 40 seconds or something, and you can see when all the components are getting started, and when they end, and when it switches, stuff like that, right, okay? So yeah, this is how you can analyze how to make it smaller. In my case, I was like, okay, where does user space start? So it starts about 20 seconds or something. This is all user space from here. So I have all these things that I can take out from user space to make it boot faster. And then from 20 seconds up to there, then I'll have to deal with the kernel. So yeah, the goals that I had was I want to reduce boot time for testing and release, and that's because when you're testing a new device on an emulator, and I'm not talking about QMU, that boot time goes up a lot. It comes in from 40 seconds, it goes up to minutes or more. So yeah, and then I want to reduce the kernel size as well. Basically, provide a more functional distro, right, but then poke tiny, but have stuff that we need, such as FPGA manager. Also, I wanted to decrease the file system size, and then we didn't want to boot to RAM. We wanted to boot from an actual device, mostly because it's read-only, that's why. So the first thing you need to do when you want to create your own distro is, okay, what components do I actually need? What do I want to put in my image or in my distro? I selected muscle as my C library, BC box for everything else, mostly. I did want to have Udev to manage my devices, and obviously, well, the Linux kernel that I chose, in this case, as you can see there, it's Linux X on an X, which is the vendor tree for silence, okay? So I did not change the kernel. This is the same kernel as the other, as a Pelonix image in distro. So yeah, that's pretty much what the distro looks like. As you can see, it's not much, but let's see how good it does. So yeah, choosing Pelonix tiny as a distro and creating a Pelonix image minimal got us up to 11 megabytes for root of s. The kernel was still 15 megabytes, and that makes sense, because I didn't change anything, right? I just chose the same kernel, and that's because I wanted... I don't know a lot of how this kernel is being used in all the devices, so I don't want to break functionality at this point. And the boot time was reduced to 24 seconds, which is actually pretty good already. Again, this is the emulator. It should be pretty a lot faster in your devices. Okay, so I was like, okay, I'm gonna do the same thing that I did for core image tiny on core, and I'm gonna create my own image, which is gonna help me out a lot with reducing the boot time after 20 seconds. All the user space stuff I can take out, or most of it. So yeah, I decided to create my own image, and the boot time was after that... Sorry, I think I skipped one. No. So after that, I ended up with the root of s of 1.5 megabytes. The kernel was still 15 megabytes. Again, I didn't change this, and the boot time was reduced to 18 seconds, which is half of what we actually had, or more than half, right? Less than half, sorry. So another thing that I was like, okay, what's next? What do I want to do? It's what I explained before. From this to overrides, you can override components, certain components, and what they use, right? So we should override Linux silencs, configuration, and bcbox. And the reason for this, specifically for the kernel, is like, don't do this. What you potentially, what you should do is actually base your kernel on Linux Yachto Tiny, and that's the reason for that, is that Linux Yachto Tiny uses the kernel meta, or Yachto kernel cache, and that it's a lot easier to configure than for different devices and everything. But in this case, I was like, okay, I'm testing this out, okay? I want to make this smaller and see how far it can get. So you can override the configuration. As an example of what I put on bcbox.devconfig, sorry, for pedaling tiny was pretty much the same, right? I added fdisk, swap on off, you mount, and I deleted some of the configurations that I didn't need. Again, as I mentioned this before, nothing in life is free, so you have to drop some stuff so you can boot faster. So I decided this is pretty much just random stuff that I put in there. It doesn't have to be like that for you. Basically, like I said, what you drop, it depends on your specific application. Some applications are going to need something. Some other applications are not going to need it. So this is where it gets tricky, because you have to be very careful what you actually want and what you don't want in there. So this is the couple things that I did on devconfig. I dropped all those things. So some of the IOS schedulers, in this case I didn't want IPv6 support, for example, or Bluetooth in this case, or support for other file systems, you know, it could be anything. Let's say you have a device and that device uses SPI, and then you have another device that uses I2C, and you don't need the same configuration in both. So this is a way to override that, but still it's better if you use the kernel cache. And, well, this is what ended up on the boot log after that. The first thing that I highlighted was that we still have functionality like FPGA manager, and it comes out after 2.22 seconds. So I'm showcasing that there is a way to have functionality that you need and still reduce the boot time. And the kernel stopped booting, or finished booting, I guess, after 2.96 seconds. And then, sorry, and then the actual shell prompt ended up being at like 3.76. This is not even the best that I got. Like, I booted so many times, I got like 3.4 or something. So, but this is just an example. And like I said, it depends on your application. So here I just started dropping things that in my case, I didn't need, but you might need it. You have to decide what to drop or what not to drop. So, yeah, using Palenix Tiny, the distro, with Palenix Image Tiny, the image, ends up being the root of fast, it's 1.2 megabytes, the GC file. The kernel was reduced from 15 megabytes to 5.4. And the boot time is something like 3.76 seconds, which is what, like, I don't know, from 42 to 3.66, you make the math. You do the math. So, yeah, this is the way of how you can create your own distro, and you can, depending on what you want, you can make it boot faster, you can make it have even, like, let's say it could go the other way, right? Instead of you want it more functionality, you add stuff on the dev config. You can do that as well. And this is the comparison between them. In this case, again, I have three sections, the root of fast size, the kernel size, and the boot time, but I have four columns because I did four iterations in this case. The first one was the Palenix distro with the minimal image. The second is the tiny distro with the minimal image, tiny plus tiny, and then tiny plus tiny 2 when I actually overread more stuff that I didn't need, right? So, yeah, the root of fast size started at 13 megabytes, went down to, I think, 11, and then went down to 1.5 and 1.2, I think. Size of kernel, 15 megabytes, and you can see how the first three iterations have the same kernel, okay? So, it's 15 megabytes on all of them, and once I overread that, overread that, I ended up with 5.4 megabytes, and boot time was reduced from 42 seconds to 24 to 18 to 3.0 something, okay? So, in less than four seconds, you have your device up and running. So, what is next for, like, what do you do next after this? You can explore user space component alternatives, sure, but I think BCBox does a pretty good job, to be quite honest. Like, there's S-Base, there's Toybox, but I don't, personally, I don't think there's much to do there, but you can customize a kernel with the Yachto kernel meta, and that makes it a lot easier for customers to have several devices, right? And then not all devices have the same functionality, so you can have different things, and depending, you can, there's many ways of doing this, you can have several distros, you can do it via the machine, depending on the machine that you're building for, or depending on the distro features, and the way that this works is that it starts building a configuration file depending on your needs. This was explained in a talk yesterday, actually, for the mainline kernel, but the Yachto uses this as well. It uses configuration fragments and SCC files to decide what to actually create, put in your final config file. So yeah, that's what, that's why it wouldn't be next, and I already had a question from someone who's like, yeah, I can't use this, why, why can't I? The reason is this, this is still not, if you go to the layers, this is still not there, and that's because we still have to decide, since we ship this in a way, we still have to decide what to actually put in there, so it works for most people, okay? But it can be customized for different applications. Well, thank you very much. Does anyone have a question regarding this talk? How did I do in time? No questions? All right. Well, thank you very much.