hello world my name is victor engelmann and in this video i'm going to show you how to build an extremely minimalistic linux distribution um a very small distribution it's only going to be i think 12 megabytes or so and yeah i've already created a video series on my channel about linux from scratch and i think that was a i don't remember exactly i think around 10 hours but yeah the thing about limits from scratch is that it's a complete linux distribution with networking and c compilers and tool chains and everything and yeah today we will build a much smaller system that is really only supposed to to give you a shell so you can navigate your file system and start programs and such and yet to to achieve that without all this overhead of a tool chain to create all the all the glue utils and stuff like that we will be using busy box so we will actually only build two packages so that's really really minimalistic and um yeah that then we will have a linux kernel on the one hand and yeah i mean linux systems generally require a kernel and a root partition you know where the kernel finds its instructions what to do on startup and yeah the programs and drivers to to load and yeah so that's what we will have to do we will have to build a kernel and create a root partition but that root partition is mostly only containing busy books okay so yeah what's a busybox maybe i should explain that well busybox is like a little program that can do a lot of stuff like so a program that can take something that's a normal instruction in a bash script like echo here and um yeah it can execute that okay so busy box is like a shell but yeah a normal shell um would um would start a separate program called echo for that okay but uh yeah busybox has all these commands built in so so you don't have to build all the stuff around these tools okay so yeah let's dive right in i will create two text files busy box x like you know this typical ending for for linux distributions everything has to end with an x and some temp sh okay because i want to do this step by step but in the end so in this temp file i will always do the next step but then i will put everything into this busybox sh so that we will in the end have one big script that does all the building in one go okay but let's start with a typical trebang okay now yeah as i said we will need a kernel and a root partition and on that root partition we basically just want to have busy books so what we will need to do is we will need to download yeah this kernel source code so we will go to kernel.org and here under a protocol http we can browse the the pub directory and in here we go to linux kernel and yeah i will go for a five point something kernel and here we have a long list of kernel releases okay 515.6 seems to be a very recent one let's see xc seems to be stronger compressed than gz so i will copy this link here okay and we need busy box so we go to busybox.net download source and here we also have a long list of releases and here 134.1 is the newest one these two here are signatures this is the one that the tar bz is the one that we need to download okay um yeah of course we can pull out this version here okay and put this in a variable now yeah here this v5 point x this five point something is the beginning of this kernel version so so we basically need to extract this major version here and yeah that's a typical use case for that so we take the the leading digits one to nine star and capture that in a capture group followed by something that isn't a number so if the number would happen to be 10 or so i don't want to capture only the one i want to capture the full everything until the first character that isn't a number okay okay and then after that anything can happen i don't care but i'm taking uh digits until we encounter the first non-digit here okay and that's what we enforce there okay and we map that to the first capture group so the stuff that we've captured here okay yeah maybe let's try this to make sure that it works and you see it indeed takes the first number okay so this seems to work and then we can replace this here with a kind of nature and now we can we can just change the version that we want to have up here and everything else should should just work without any further actions on our side okay so just changing the number up here is then supposed to uh just build to the same system with a different version of the kernel and also the busy box okay good um now i will create a directory src and we will see a change directory into that so that we download the stuff into that directory okay and then we will unpack the archives extract file and extract file busy box okay so i will group that so this is so stuff for the kernel and down here is the stuff for busy box okay so when we unpack this linux archive then we will get a directory called linux with the kernel version we can cd into that okay and yeah when we are in that directory we will then need to build the kernel and yeah i've already made a video about building the kernel so i'm not gonna go very deep into that here i'm just gonna say make dev config so we get the default configuration and then make with j8 but in case that fails i want to exit the script okay but start by by doing this downloading the kernel and compiling it okay so okay so we have temp dot sh and this was output into temp dot sh right yeah let's run this okay we're downloading the kernel source that's amazingly fast i think it's unpacking now now it's creating the default configuration and now it's compiling the kernel and here this can take a while okay it's finished building the linux kernel and at this point i will throw all the stuff over here into the other shell script because yeah the kernel is now done i will throw that out of this temp script and yeah now let's start building busybox there you have the same situation when you unpack it you get a directory with that same name and in that directory you can then build busybox and yeah busybox has a similar build system as a linux kernel so you can just say make devconfig also okay and yeah i will execute this now and then we will talk about this some more okay so now it has created this default configuration file okay so now we have this default configuration file but we now need to talk about busybox a bit more because yeah of course we want to build busy box but that's not so simple in in my case here and since we've already downloaded and extracted the source code i will throw this out here okay um [Music] yeah now we need to talk about how to build busy box because that's not as straightforward as i would like it to be at least not on manjaro you know i'm running a manjaro system here and um the problem is that our final system is not going to have an ldd i think so it's it's not going to have any facility to load dynamic link libraries dlls as they would be called in windows or shared objects as they are called in the unix world so because of that we need to tell busybox to create a static build so the libraries that you would normally have as separate files and that it would load on runtime they need to be put into the um into the the executable binary okay so so that they don't have to be loaded dynamically okay so we will need to do something called aesthetic build and um yeah you can just like in the in a linux build you can you can also do a make menu config okay and yeah there's this you get this menu very similar to the to the linux menu config and here in the settings a bit further down you can say build static binary okay um but i want this to be a script right so i want i don't want to go through this graphical menu here so what you can do instead is you can go into the file.config and in here you have a setting called config static which is not set um and we can set it to equals yes okay that would be one way to do it but that's still manual work and i want this to run through without any user interaction so what we can do now is again with that edit the file.config and replace any a line that contains config static so we take the entire line and replace it with config static equals yes okay good so this changes the configuration to a static build and now we would be able to run make again with j8 and if that fails exit okay but here we have another problem because again this is a manjaro system and manjaro is based on arc linux and yeah i've gone through a lot of online discussions about this topic a lot of people have problems with that and yeah the um the maintainers are not very helpful on it so they just say oh just use music and uh it's not really obvious what that means so i spent i don't know half and half a day yesterday uh figuring out how to how to just use music here um so um so what you need to do is um you need to install the packages musel and kernel dash headers music okay i've already installed them so nothing is going to happen here on my machine but yeah you need to install these packages i think on debian based systems this is probably not necessary you know this on debian based systems and i don't know fedora i think most other linux distributions will just succeed in building with make j8 but the problem on manjaro systems is that the library lib crypt is there's just no static version of that in a default installation of manjaro and i wasn't really able to build one easily so this whole approach with muser was just simpler so so that's what i then ended up doing and yeah now what is musel musel is an entirely separate tool chain so instead of gcc we will now compile with musel gcc okay so that will then build our busy box okay good yeah we already did this make dev config so i'm gonna comment this out for now yeah let's run this i don't know why it's asking me about static lip gcc i will just say yes because as i said we want to build a static build and this sounds like it's related so i will say yes i don't know why it's asking me this but okay okay now it's um done building this and interestingly it's it's saying here that uh lip crypt isn't even needed so i really don't know what uh all the fuss was about but okay ah i think i see why uh it's asked me about this uh the setting for static lip gcc it seems that my set script has also changed this variable possibly yeah maybe say something other than an underscore after that okay so this builds busy box okay now okay so now we have built the kernel we have built a busy box so now let's take these two things and put them together into a running into a working linux system okay so um so busy box is built so what we need to do now is we need to pull the the compiled kernel from the source directory okay this is a kernel and we will copy that into the root directory okay so now we have the kernel here and yeah the other thing that we need as i said is a root drive so and we will do that as a as an initial run drive so what i will do now is create a directory init rd change directory into it and yeah in there um we will create four directories bin dev proc and this these are really standard directories that you will find in almost all linux systems bin is where we will put our our busy box binary and do some magic with it yeah def is for the device files progress for the process files and this is for the interaction with uh with the kernel uh these are these typical virtual file systems that you will find on almost all linux systems these days okay good so we create these directories and then move into the directory bin okay and now we will build this bin directory how do we build that well first of all we will copy busybox here okay okay so in here in the source directory basic box there's this program busy box here and that's the compiled binary that we need to take and we put this now into this bin directory okay so now we have that and yeah one interesting thing that busybox does i need to explain that i think so as i've shown you busybox can do stuff like execute normal shell commands right but busybox is a bit smarter than that because you don't have to pass a program name as a parameter busybox will also examine its arc v0 which is its own file name okay so if you renamed busybox to echo for example it will it would always do echo and you can use that with a symbolic link to bin busy box and let's call it echo okay now we have a a program echo here that we can use echo hello world and internally that's busy box but busy box can see hey you've renamed me to echo so you want me to behave as echo okay good so and now we will use that to our advantage because yeah the next thing that busybox does is with a busybox dash dash list it gives you a list of all the things that it can pretend to be okay there's a lot of stuff here okay i've seen uh there's grep hd palm uh du der name a lot of programs that it can pretend to be and yeah this is what we will now do when we go to the directory bin in here we run busybox list okay and then iterate through all these programs that it can pretend to be okay and yeah set these symlinks for these programs to busybox so ln s bin busybox proc okay so at one point this list will contain for example echo then proc will be set to echo and then we create a symlink called echo to bin busybox you know the stuff that we have just done up here yeah basically what we did here right we created the sim link called echo to busybox and this is exactly what we are down what we are doing now here okay let's run this but now if we look into this init rd bin you see we have now all these programs and we could now tell them to and we could now use them as these programs although they are really just some links to busybox okay now after we've created this bin directory we are almost done we still need to tell the kernel what to do on startup and yeah we can do that um by creating a script called init for example there are other um legal names that you could use like s-bin init or linux rc would be legal but yeah i will create a file called init here put a shebang in there and yeah on when we boot what do we need to do we need to mount these virtual file systems that we've talked about in our dev processors okay here we mount this then we mount proc okay yeah the next line i don't think that's necessary but it was uh in the code that i've seen source control dash wtu kernel dot print k and this sets some settings which tell the kernel different lock levels okay two four one seven i don't care much about that once we've done this we are basically done booting so we could now do a clear to clear the screen and then then run bin sh okay so at this point we then get a shell okay and yeah then we can use the shell and we can uh then we can uh print the uh directory listing change directories stuff like that um yeah for my taste we don't really need this clear here so i will throw that out but anyhow now once we've done that [Applause] we need to set um i mean it's not necessary i think to give all files uh the permission 777 i mean that's read write execute bits for all users our system doesn't even have users i think so i don't think that really matters but i will do it anyhow and yeah once we've done this we are kind of done so we have all the files that we need and then we can take all these files by using find on the current directory that finds all files in the directory and pass them to cpio dash o is for creating a file with format new c and write that to the file init rd dot image okay yeah this looks good this output here with a number of blocks that's the output of cpio and yeah if that isn't zero or 1 or something like that it looks as if it has found a lot of things so yeah that looked like it's like it should work we'll move this over here now and let's see we now have a busy image there's the kernel and init rd image is our our root drive so what we can do now is we can now run q emu so virtual machine qemu with parameters kernel pc image and dash init rd init rd dot image okay let's try this so i made a typo and look at that it's booting okay so it's a bit complaining here but that's not really bad we still can now look at the directory listing change directory look at the directory listing echo hello world create a text file foo.txt cut it to the standard output edit it with v okay now i don't know how to uh exit it anyhow let's run it again one thing that i want to mention is that when you press ctrl d or type exit so you end the this shell linux doesn't expect your main program to end like that okay so you're getting a kernel panic here because uh attempted to kill in it yeah that's not supposed to happen so something that i would do is to put another line behind this bin sh power off dash f okay and yeah if you do that then um exiting the shell will then just terminate the the whole virtual machine okay or if you're running this on actual hardware then it will turn the hardware off okay good um and yeah that's basically all that we had to do you know we have a running uh busy box based system now and um i find that really awesome it's so little work i mean look at how little uh code this is it's 63 lines and a lot of uh empty lines in between and it's creating something that at least looks and feels like a linux system okay i will put that at the end also one more thing that i want to mention is when you run qmu like that you know you get this qemu window but yeah maybe you don't like that okay what you can do instead is you can say no graphic then you don't get this window but yeah if you don't get this window how do you know what the kernel is doing um and yeah what you can do is you can tell the kernel through a command line switch that you wanted to use as a serial interface as console okay and yeah the serial interface is taken by qemu and it's uh it communicates with uh standard and standard out so if you do it like this you don't get the window you see everything in your terminal directly okay here as you can see this was all the stuff that you've seen uh in the window before and now here bin sh is a bit complaining but uh but yeah here you now have bin dev proc root and this and the init program and yeah all the stuff that we did before you know so yeah that's i think that's pretty cool let me show you one more time when you run this and you know i i haven't updated the init rd so this line isn't in this init file okay so if i end this shell now i get the kernel panic again and yeah now this this shell window is now stuck and to un make it unstuck i would just kill all qemu dash system dash x86 64. bam and you see now it's gone and yeah this is how you can unfreeze your your qemu when it's running directly on your shell and it's run into a kernel panic or something okay yeah whatever i think this is really cool and um i like this a lot i think it gives you an even better insight into how linux works and how linux systems in general work so yeah if you like this video like it share it subscribe and see you next time