• Added the current version of the website located at http://minimal.linux-bg.org

This commit is contained in:
Ivan Davidov 2014-08-03 18:37:11 +03:00
parent d116c397c9
commit 91506680aa
3 changed files with 1077 additions and 0 deletions

260
www/index.html Normal file
View File

@ -0,0 +1,260 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="Minimal Linux Live" />
<meta name="keywords" content="minimal linux live tutorial kernel busybox cd usb iso image" />
<meta name="author" content="Ivan Davidov - davidov (dot) i [at] gmail {dot} com" />
<title>Minimal Linux Live</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<script language="JavaScript" type="text/javascript">
function menuSwap(itemIndex) {
for(var i = 1; i <= 5; i++) {
var strItem = "item" + i;
var objItem = document.getElementById(strItem);
objItem.style.display = (i == itemIndex) ? "block" : "none";
}
}
function logSwap(itemIndex, show) {
for(var i = 1; i <= 1; i++) {
var showObj = document.getElementById("show" + i);
var hideObj = document.getElementById("hide" + i);
var textObj = document.getElementById("text" + i);
if(i == itemIndex) {
if(show == true) {
showObj.style.display = "none";
hideObj.style.display = "block";
textObj.style.display = "block";
} else {
showObj.style.display = "block";
hideObj.style.display = "none";
textObj.style.display = "none";
}
} else if(show == true) {
showObj.style.display = "block";
hideObj.style.display = "none";
textObj.style.display = "none";
}
}
}
</script>
</head>
<body>
<div id="container">
<div id="header">
<a href="/">Minimal Linux Live</a>
</div>
<div id="menu">
<a href="#" onclick="javascript:menuSwap(1); return false;">Home</a> &nbsp;&nbsp;&nbsp;
<a href="#" onclick="javascript:menuSwap(2); return false;">Changes</a> &nbsp;&nbsp;&nbsp;
<a href="#" onclick="javascript:menuSwap(3); return false;">About</a> &nbsp;&nbsp;&nbsp;
<a href="#" onclick="javascript:menuSwap(4); return false;">Tutorial</a> &nbsp;&nbsp;&nbsp;
<a href="#" onclick="javascript:menuSwap(5); return false;">Download</a>
</div>
<div id="main">
<div id="item1" style="display:block;">
<div id="text">
<h2>Home Page</h2>
<p>
<b>Minimal Linux Live</b> is a set of Linux shell scripts which automatically build minimal Live
Linux OS based on <a target="_blank" href="http://kernel.org">Linux kernel</a>
and <a target="_blank" href="http://busybox.net">BusyBox</a>. All necessary source codes are automatically
downloaded and all build operations are fully encapsulated in the scripts.
</p>
<p>
If you want to build your own Minimal Linux Live ISO image file, all you need to do is the following:
</p>
<p>
<ul>
<li>
Get the latest scripts from the <a href="#" onclick="javascript:menuSwap(5); return false;">download</a> section.
</li>
<li>
Extract the scripts to some folder.
</li>
<li>
Make sure that all scripts are executable (chmod +x *.sh).
</li>
<li>
Depending on which Linux OS you are using, there might be one or more (or none, or even more) build dependencies that you
need to resolve before you start the build process. If you work with <a target="_blank" href="http://ubuntu.com">Ubuntu</a>,
the following commands should resolve all necessary build dependencies:
<ul>
<li>
sudo apt-get install wget
</li>
<li>
sudo apt-get install make
</li>
<li>
sudo apt-get install gcc
</li>
<li>
sudo apt-get install bc
</li>
<li>
sudo apt-get install syslinux
</li>
<li>
sudo apt-get install genisoimage
</li>
</ul>
<br />
</li>
<li>
Execute the script <b>build_minimal_linux_live.sh</b> and wait. If you have resolved all build dependencies, the whole
process should take less than 30 minutes on a modern computer. If the build fails for some reason, most probably there
are unresolved build dependencies. Several users reported that the <i>build-essential</i> package resolves all unexpected
build dependencies for Ubuntu. If you are using <a target="_blank" href="http://linuxmint.com">Linux Mint</a> try to
install the package <i>g++</i> and if you still have troubles then try the <i>build-essential</i> package. On
<a target="_blank" href="http://fedoraproject.org">Fedora</a> you might need the static 'glibc' package <i>glibc-static</i>.
<p />
Please have in mind that the build dependencies can vary a lot depending on the Linux OS which you use and the software
which you have already installed.
<p />
If you still have troubles then examine the failure message and google it. If you are unable to find solution, then you
can ask someone more experienced Linux guru (if you know any) or as alternative you can contact me. Please, make sure that
you have researched your problem in advance before you send me your question.
</li>
<li>
When the scripts finish their job you will find newly created <b>minimal_linux_live.iso</b> in the same folder where you
executed the scripts. You can burn the ISO image file on CD/DVD, install it on USB flash drive via
<a target="_blank" href="http://www.pendrivelinux.com">Universal USB Installer</a>,
or run it directly via PC emulator like <a target="_blank" href="http://virtualbox.org">VirtualBox</a>.
</li>
</ul>
</p>
<p>
The produced ISO image file contains Linux kernel compiled with default options, BusyBox compiled with default options and very simple
initramfs. This means that you don't get Windows support out of the box, nor you get any fancy desktop environment. All you
get is a simple shell console which supports all BusyBox applets and... well, that's all. This is why it's called "minimal".
</p>
<p>
The good news is that even though the OS is small and simple, the build scripts are also very small and very simple. You can
quite easily learn from the scripts and later modify them to include more stuff (I encourage you to do so). After you learn
the basics you will have all the necessary tools and skills to create your own fully functional Linux based operating system!
Entirely from scratch! Isn't it great?! :)
</p>
<p>
The <a href="#" onclick="javascript:menuSwap(4); return false;">tutorial</a> provides more details about the inner structure
of the scripts and the overall build process. I encourage you to go through this document when you have the time.
</p>
<p>
Below you can find several screenshots which show what the environment looks like when you boot your newly generated
Minimal Linux Live OS.
</p>
<p>
<img alt="Minimal Linux Live" id="screenshot1" width="100%" height="100%" border="0" src="./images/screen1.png" />
</p>
<p>
<img alt="Minimal Linux Live" id="screenshot2" width="100%" height="100%" border="0" src="./images/screen2.png" />
</p>
<p>
<img alt="Minimal Linux Live" id="screenshot3" width="100%" height="100%" border="0" src="./images/screen3.png" />
</p>
</div>
</div>
<div id="item2" style="display:none;">
<div id="text">
<h2>Change Log</h2>
<p>
<div id="show1" style="display:none;">
<b>28-Jul-2014</b>
<a href="#" onclick="javascript:logSwap(1, true); return false;">show</a>
</div>
<div id="hide1" style="display:block;">
<b>28-Jul-2014</b>
<a href="#" onclick="javascript:logSwap(1, false); return false;">hide</a>
</div>
<div id="text1" style="display:block;">
<br />
<b>Minimal Linux Live</b> is now based on <b>Linux kernel 3.15.6</b> and <b>BusyBox 1.22.1</b>.
</div>
</p>
</div>
</div>
<div id="item3" style="display:none;">
<div id="text">
<h2>About This Project</h2>
<p>
My name is <a target="_blank" href="http://linkedin.com/in/ivandavidov">Ivan Davidov</a> and I currently
live and work in
<a target="_blank" href="http://en.wikipedia.org/wiki/Sofia">Sofia</a>,
<a target="_blank" href="http://en.wikipedia.org/wiki/Bulgaria">Bulgaria</a>.
</p>
<p>
I am professional Java software engineer (yes, Java developers tend to know some Linux stuff) and I've
been trying to create my own Linux OS for a very long time. There are some good tutorials which you
can find online but almost none of them are simple to follow and almost none of them explain in details
what has been done and why it's done in this particular way. In most cases the tutorials are incomplete and
there is high chance that you end up with something broken.
</p>
<p>
Don't get me wrong, you can learn a lot from these tutorials, as I did. In fact the scripts which I created
(did you take a look at them?) are based on the same information resources which you might have already found.
The difference is that this site provides you not only with detailed tutorial, but also with fully functional
set of shell scripts which automatically build fully functional live Linux OS. And the tutorial explains it
all for you!
</p>
<p>
If you'd like to contact me, my e-mail is: <b>davidov [dot] i (at) gmail {dot} com</b>
</p>
<p>
My LinkedIn profile is here: <a target="_blank" href="http://linkedin.com/in/ivandavidov">http://linkedin.com/in/ivandavidov</a>
</p>
</div>
</div>
<div id="item4" style="display:none;">
<div id="text">
<h2>Minimal Linux Live Tutorial</h2>
<p>
Would you like to learn how to build your own minimal live Linux OS?
</p>
<p>
<a target="_blank" href="./the_dao_of_minimal_linux_live.txt">The Dao of Minimal Linux Live</a> explains in details
what steps are involved in creating simple live Linux OS entirely from scratch, the inner structure of the
build scripts (I assume you have already downloaded them) and provides you with more information on how to
improve/upgrade the generated OS with other generic stuff (e.g. users &amp; groups, /etc/inittab).
</p>
</div>
</div>
<div id="item5" style="display:none;">
<div id="text">
<h2>Download Section</h2>
<p>
The latest scripts (28-Jul-2014) can be downloaded as ZIP archive
<a href="./download/minimal_linux_live-28-Jul-2014_src.zip" title="Minimal Linux Live - shell scripts">here</a>.
</p>
<p>
Pre-built ISO image files generated with the latest scripts are available for
<a href="./download/minimal_linux_live-28-Jul-2014_x86.iso" title="Minimal Linux Live - ISO image file for x86 machines">x86</a>
and
<a href="./download/minimal_linux_live-28-Jul-2014_x64.iso" title="Minimal Linux Live - ISO image file for x64 machines">x64</a>
processors.
</p>
<p>
You can also <a target="_blank" href="./download">browse the download directory</a>.
</p>
</div>
</div>
<div class="clear"></div>
</div>
<div id="footer">
Copyright &copy;2014
<span class="separator">|</span>
<a href="/" title="Minimal Linux Live">Minimal Linux Live</a>
</div>
</div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-53254151-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>

139
www/style.css Normal file
View File

@ -0,0 +1,139 @@
html {
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
body {
background: #f0f0f0;
margin: 0;
}
#container {
width: 780px;
margin: 0 auto;
}
#header {
padding: 5px 0px 0px 0px;
text-align: center;
background: #3b7687;
}
#header a {
color: #fefefe;
text-decoration: none;
font-size: 25px;
font-family: "Verdana";
}
#menu {
background-color: #3b7687;
padding: 5px 0px 5px 0px;
text-align: center;
}
#menu a {
color: #d5e6eb;
text-decoration: none;
font-size: 12px;
font-family: "Verdana";
}
#menu a:hover {
color: #ecf2f3;
}
#sidebar {
float: right;
width: 160px;
padding: 20px 10px 40px 10px;
margin: 0;
color: #444444;
text-align: left;
background: #e6e6e6;
}
#sidebar a {
text-decoration: none;
color: #262626;
font-family: "Verdana";
font-size: 12px;
}
#sidebar a:hover {
color: #666666;
}
h1 {
margin: 0px;
color: #869843;
font-size:24px;
font-family: "Verdana";
font-weight: normal;
}
h2 {
color: #3b7687;
font-size: 14px;
font-family: "Verdana";
margin: 0px;
}
ul {
margin: 10px 0px 0px 0px;
line-height: 16px;
}
#main {
background-color: #fefefe;
}
#text {
margin: 0px 0px 0px 0px;
padding: 20px 20px 20px 20px;
color: #444444;
font-family: "Verdana";
font-size: 12px;
line-height: 16px;
text-align: justify;
}
#text a {
color: #3b7687;
text-decoration: underline;
}
#text a:hover {
color: #444444;
}
#footer {
padding: 10px 0px 5px 0px;
background: #d6d6d6;
font-family: "Verdana";
color: #444444;
font-size: 11px;
text-align: center;
}
#footer a {
text-decoration: none;
color: #262626;
}
#footer a:hover {
color: #666666;
}
.separator {
font-size:11px;
color:#FFFFFF;
}
.center {
text-align: center;
}
.clear {
clear:both;
}

View File

@ -0,0 +1,678 @@

The Dao of Minimal Linux Live (31-Jul-2014)
Author: Ivan Davidov
Website: http://minimal.linux-bg.org
Email: davidov (dot) i {at} gmail [dot] com
Redistributed by: <put your name and contact details somewhere here>
### ### ###
Contents
1. Preface
2. Boot Process
3. Inside The Shell Scripts
4. Possible Improvements
5. Epilogue
### ### ###
1. Preface
Please feel free to redistribute this document in any form you see fit. I only ask you to
respect my efforts and keep me as the original author. That's all I ask.
Note that the explanations regarding the script details are based on the "28-Jul-2014"
version of "Minimal Linux Live". Future versions of the scripts may already include some
of the stuff discussed in the section "Possible Improvements".
### ### ###
2. Boot Process
The overall boot process is quite complex but we need to know these details since we are
talking about operating systems and to be more precise - Linux based operating systems.
You can find some general information here:
http://en.wikipedia.org/wiki/Linux_startup_process
When we talk about live Linux OS, the overall boot process is the following:
1) BIOS gives the execution control to the boot loader present on the boot media such
as CD, DVD, USB flash or something else.
2) In most cases the boot loader is based on Syslinux. On our boot media we should have
two special files - the kernel file and the initramfs file.
3) The boot media also contains a special configuration file which points to the location
of the kernel/initramfs files.
4) Now that Syslinux knows where the kernel file is, it loads it in the RAM and passes
the execution control to it.
5) The kernel detects the available hardware, loads necessary drivers and then it passes
the execution control to the initramfs.
6) The initramfs file is an archive which is unpacked automatically by the kernel in the
RAM. The actual execution control is passed to the shell script file /init which must
be present in the initramfs file.
7) Since we are talking about minimal live CD, in theory /init is not supposed to do much.
All we need form /init is to prepare the environment and provide the user with shell.
In most live Linux distributions the /init script is supposed to do much more work
but in our case for now it is enough to know that the point at which we take the control
is exactly the /init script.
### ### ###
3. Inside The Shell Scripts
So far we learned that we need several pieces in order to build a live Linux OS:
1) boot loader - to make our media bootable.
2) kernel file - to take care of the initial system bootstrap process.
3) initramfs file - to prepare the necessary environment for the user.
This document focuses on parts (2) and (3). The reason we won't discuss (1) in details is
because the build process that we are going to rely on later, takes care of the boot loader
part automatically.
The ZIP which you have downloaded contains the following files:
.config
0_prepare.sh
1_get_kernel.sh
2_build_kernel.sh
3_get_busybox.sh
4_build_busybox.sh
5_generate_rootfs.sh
6_pack_rootfs.sh
7_generate_iso.sh
build_minimal_linux_live.sh
If you have followed the explanation posted on http://minimal.linux-bg.org then you already
know that you need to execute the script "build_minimal_linux_live.sh". If you open this
file with text editor you will find out that all this script does is to execute all other
scripts one by one.
From this point onwards, I encourage you to execute the script files one by one. We will
start with "0_prepare.sh". If you take a look at the script's contents, you will find out that
all the script does is to create an empty folder named "work". We will store our temporary
work files there.
OK, let's continue with the kernel. Somehow we need to end up with fully functional kernel which
is able to do the system initialization for us. We need to download the kernel sources, compile
these sources and finally pack the kernel.
The script "1_get_kernel.sh" downloads the kernel sources and unpacks them. Here is the full
source code of the script:
#/bin/sh
DOWNLOAD_URL=$(grep -i KERNEL_SOURCE_URL .config | cut -f2 -d'=')
ARCHIVE_FILE=${DOWNLOAD_URL##*/}
cd work
rm -f $ARCHIVE_FILE
wget $DOWNLOAD_URL
rm -rf kernel
mkdir kernel
tar -xvf $ARCHIVE_FILE -C kernel
cd ..
First we read the ".config" file to find the URL for the kernel sources. The URL is stored in
the variable "DOWNLOAD_URL". Then we get the actual name of the archive file and we store the
name in the variable "ARCHIVE_FILE".
The important part of the script is the line where we get the kernel sources:
wget $DOWNLOAD_URL
The next important part of the script is the line where we unpack the kernel sources:
tar -xvf $ARCHIVE_FILE -C kernel
At this point we have downloaded and unpacked the kernel sources. So far so good. Now we need
to compile them. We move to the next script in the chain called "2_build_kernel.sh". Here is
the full source code that we are going to analyse:
#/bin/sh
cd work/kernel
cd $(ls -d *)
make clean
make defconfig
sed -i "s/.*CONFIG_DEFAULT_HOSTNAME.*/CONFIG_DEFAULT_HOSTNAME=\"minimal-linux-live\"/" .config
make vmlinux
cd ../../..
First we navigate to the kernel source folder. Then we execute the following commands:
make clean
The above command cleans the output from our previous kernel builds. Obviously, if this is the
first time we go through the build process, we have nothing to clean.
make defconfig
The above command creates new ".config" file in the current folder which contains all default
configuration parameters that we need in order to build our new kernel. Note that the defaults
will be either 32 or 64 bit specific, depending on your Linux environment.
sed -i "s/.*CONFIG_DEFAULT_HOSTNAME.*/CONFIG_DEFAULT_HOSTNAME=\"minimal-linux-live\"/" .config
The above command searches for a specific line in the ".config" file which contains the string
"CONFIG_DEFAULT_HOSTNAME" and replaces the whole line with the following text:
CONFIG_DEFAULT_HOSTNAME="minimal-linux-live"
Later, when you boot up your live Linux OS you can execute the command "uname -a" and you will
see the string "minimal-linux-live" in the output. All we did was to replace the default value
"(none)" with our custom value.
Now you have a sample command which you can use to search for specific configurations in the
file ".config" and replace these configurations with your own. Obviously, you can skip this
replacement and everything will work just fine. Like I said, the only difference will be that
the default host name will be "minimal-linux-live" instead of "(none)".
Now we come to the most important and also the slowest part in the whole process. We need to
actually create the kernel.
make vmlinux
The above command will compile the Linux kernel. This takes a lot of time, so I guess it's
high time for a short break. The final kernel file is located here:
arch/x86/boot/bzImage
OK, at this point we should have a kernel file compiled with default options, where we have
changed the default host name with some other value of our own. Now we move to the next
part.
The kernel itself is far from enough - we also need some kind of environment with basic
command line tools like ls, cat, mkdir, etc. This environment is called "initramfs" which
stands for "initial RAM file system". This is what we are going to do:
1) We are going to download & compile BusyBox. This will give us the basic command line
tools that we need for normal work in console mode.
2) We will use BusyBox to provide us with some default directory/file structure which
we will modify into our own initramfs file.
One by one - we need to download and unpack the BusyBox sources. Let's take a look at the
script file "3_get_busybox.sh":
#/bin/sh
DOWNLOAD_URL=$(grep -i BUSYBOX_SOURCE_URL .config | cut -f2 -d'=')
ARCHIVE_FILE=${DOWNLOAD_URL##*/}
cd work
rm -f $ARCHIVE_FILE
wget $DOWNLOAD_URL
rm -rf busybox
mkdir busybox
tar -xvf $ARCHIVE_FILE -C busybox
cd ..
The contents is almost identical to the one in "1_get_kernel.sh" which we have already
explained above. Long story short - we get the source archive with "wget" and then we
unpack the sources with "tar". That's it. Nothing complex at all.
Now that we have BusyBox sources we need to compile them. Let's take a look at the next
script "4_build_busybox.sh" which we need to execute:
#/bin/sh
cd work/busybox
cd $(ls -d *)
make clean
make defconfig
sed -i "s/.*CONFIG_STATIC.*/CONFIG_STATIC=y/" .config
make busybox
make install
cd ../../..
You have probably already noticed it - we are going to execute several "make" commands
and meanwhile we are going to change one property in the ".config" file. Let's go
through all of these commands:
make clean
The above command ensures that we will get rid of all build artefacts, assuming this
is not the first time we go through the BusyBox build process.
make defconfig
The above command creates new ".config" file which contains the defaults for proper
BusyBox build process. Again, nothing extraordinary here.
sed -i "s/.*CONFIG_STATIC.*/CONFIG_STATIC=y/" .config
The above command is very important because we inform the build process to build
static version of BusyBox, which means that the BusyBox executable file will not
be dependent on any external library. We cannot skip this, otherwise our OS will
fail with "kernel panic" when we try to boot.
make busybox
The above command compiles BusyBox. Nothing interesting here. The build should be
significantly faster compared to the kernel build.
make install
The above command creates new "_install" folder and installs BusyBox in it. We
will use this folder as a base for our new initramfs file.
At this point we should have kernel compiled with default settings (yes, we changed
one setting but it's not a big deal) and we should also have BusyBox compiled with
static option enabled and all other default settings.
Now we come to the part where we create our own initramfs folder which later on we
will pack into a file. The steps that we are going to follow is this:
1) Use the already created "_install" folder as base for initramfs.
2) Create some new folders in the initramfs folder.
3) Create some configuration files in the initramfs folder.
Now we come to the script "5_generate_rootfs.sh" which is responsible to generate
proper initramfs folder with all necessary files and sub-folders in it.
#/bin/sh
cd work
rm -rf rootfs
cd busybox
cd $(ls -d *)
cp -R _install ../../rootfs
cd ../../rootfs
rm -f linuxrc
mkdir dev
mkdir etc
mkdir proc
mkdir src
mkdir sys
mkdir tmp
cd etc
touch welcome.txt
echo >> welcome.txt
echo ' #####################################' >> welcome.txt
echo ' # #' >> welcome.txt
echo ' # Welcome to "Minimal Linux Live" #' >> welcome.txt
echo ' # #' >> welcome.txt
echo ' #####################################' >> welcome.txt
echo >> welcome.txt
cd ..
touch init
echo '#!/bin/sh' >> init
echo 'dmesg -n 1' >> init
echo 'mount -t devtmpfs none /dev' >> init
echo 'mount -t proc none /proc' >> init
echo 'mount -t sysfs none /sys' >> init
echo 'cat /etc/welcome.txt' >> init
echo 'while true' >> init
echo 'do' >> init
echo ' setsid cttyhack /bin/sh' >> init
echo 'done' >> init
echo >> init
chmod +x init
cp ../../*.sh src
cp ../../.config src
cd ../..
As you see, this script is much longer than the others. Let's take a look at the
important parts one by one.
cd work
rm -rf rootfs
cd busybox
cd $(ls -d *)
cp -R _install ../../rootfs
cd ../../rootfs
The above code snippet removes the old initramfs folder called "rootfs" and then
copies the "_install" folder (the one created by BusyBox) with new name "rootfs".
This folder is going to be our new initramfs focal point.
rm -f linuxrc
The folder "rootfs" contains file "linuxrc" which we don't need since we are going
to use initramfs boot scheme. Take a look at the following Wikipedia article for
more details:
http://en.wikipedia.org/wiki/Initrd
OK, lets go on.
mkdir dev
mkdir etc
mkdir proc
mkdir src
mkdir sys
mkdir tmp
The above code snippet creates some basic folders which we are going to use later.
cd etc
touch welcome.txt
echo >> welcome.txt
echo ' #####################################' >> welcome.txt
echo ' # #' >> welcome.txt
echo ' # Welcome to "Minimal Linux Live" #' >> welcome.txt
echo ' # #' >> welcome.txt
echo ' #####################################' >> welcome.txt
echo >> welcome.txt
cd ..
The above code snippet creates the file "/etc/welcome.txt" and fills it with the message
which will be displayed every time we boot up the system.
touch init
echo '#!/bin/sh' >> init
echo 'dmesg -n 1' >> init
echo 'mount -t devtmpfs none /dev' >> init
echo 'mount -t proc none /proc' >> init
echo 'mount -t sysfs none /sys' >> init
echo 'cat /etc/welcome.txt' >> init
echo 'while true' >> init
echo 'do' >> init
echo ' setsid cttyhack /bin/sh' >> init
echo 'done' >> init
echo >> init
The above code snippet creates the file "/init" which is going to be invoked by our kernel
when we boot up the system. In fact we create new shell script file. This is what our new
"/init" script does:
dmesg -n 1 - We hide all kernel messages. We don't want them in our
console. Only kernel panic messages will be displayed.
mount -t devtmpfs none /dev - With this command we politely ask the kernel to
populate the /dev folder with all necessary system
devices like "console", "tty", etc. We also have nice
names for the hardware devices like "sr0", "sda", etc.
mount -t proc none /proc - The kernel populates the /proc folder.
mount -t sysfs none /sys - The kernel populates the /sys folder.
cat /etc/welcome.txt - Now we display the welcome message.
while true - This code snippet starts shell on "tty" device and
setsid cttyhack /bin/sh we rest assured that when we execute the "exit"
done command new shell will be started automatically.
As you see, the "/init" script file doesn't do much but what it does is really essential.
We have only one more bit of code relevant to the "/init" file:
chmod +x init
The above command ensures that our "/init" script is executable.
cp ../../*.sh src
cp ../../.config src
The last thing we do is to copy all "Minimal Linux Live" shell scripts (including the
configuration file) in the "/src" folder. The scripts won't do anything there. This step
simply ensures that the live Linux ISO file which we are going to create later contains
the build sources, just for reference.
OK, at this point we have "rootfs" folder which contains all necessary files and
configurations for our initramfs file. The next step is to pack the "rootfs" folder
into an actual initramfs file. Let's take a look at "6_pack_rootfs.sh":
#!/bin/sh
cd work
rm -f rootfs.cpio.gz
cd rootfs
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
cd ../..
The above script removes the already existing initramfs file called "rootfs.cpio.gz"
and then creates a new file called "rootfs.cpio.gz" based on the contents of the
"rootfs" folder.
We are almost finished. At this point we have already compiled the Linux kernel and we
have also created initramfs file based on BusyBox and our own set of configurations.
The last thing to do is to generate bootable ISO file. Let's take a look at the last
script "7_generate_iso.sh":
#/bin/sh
rm -f minimal_linux_live.iso
cd work/kernel
cd $(ls -d *)
make isoimage FDINITRD=../../rootfs.cpio.gz
cp arch/x86/boot/image.iso ../../../minimal_linux_live.iso
cd ../../..
As usual, we first remove the already generated ISO file, assuming this is not the first
time we go through this process. Then we navigate to the kernel's source folder and
we execute the following command:
make isoimage FDINITRD=../../rootfs.cpio.gz
The above command generates bootable ISO based on the already compiled Linux kernel and
it uses the initramfs file which we pass to the "make" command as additional parameter.
The generated ISO file is then copied to the folder where we are executing our scripts.
### ### ###
4. Possible Improvements
Now that you have played around with your shiny new live Linux OS, you have probably
noticed that you are logged in automatically and you have no restrictions. However,
it only looks like you are automatically logged in. Yes, you get shell console and
this console allows you to perform "root" operations, but this doesn't mean that you
are logged in as "root" or any other user. In fact there are no users and groups in
the system.
I'll show you the proper way to add some users and groups from within your system
while it is still running. You can examine the final result for yourself and modify
the "5_generate_rootfs.sh" script according to your needs.
OK, let's go with the "root" account!
touch /etc/group
The above command will create empty file "/etc/group" where we store the information
for all groups.
addgroup -g 0 root
The above command will create a group "root" with group identification number "0".
It is important to provide 0 (zero) as group identifier (gid) because this is the
expected gid for "root".
touch /etc/passwd
The above command will create empty file "/etc/passwd" where we store the login
information for our users.
adduser -h /root -G root -u 0 root
The above command will create user "root" with home folder "/root", assign the new
user to the "root" group and set user identifier (uid) "0". It is important to
provide 0 (zero) as uid because this is the expected uid for the "root" user. Add
whatever password you want when asked. Try to remember it.
login
The above command will initiate the login process. Now you should be able to log in
as "root" with the password which you have provided.
--- --- ---
Another possible improvement is to set appropriate "global" rights (including the 't'
sticky flag) for the /tmp folder. You can do that by executing the following command:
chmod 1777 /tmp
The reason I haven't included this in the /init script is because in this particular
situation it doesn't really matter. By default we get uid=0 shell console and we have
full and unrestricted access to the /tmp folder. However, if you decide to add more
users to the system (not just the "root" user), you may also include the above command
in the /init script file.
--- --- ---
Probably the easiest update you can do is to re-compile the kernel with other than
default options. This is how we do it for the kernel. First of all we need to know
what possible options we have. Navigate to the kernel's source folder and execute the
following command:
make help
We have several options for interactive ".config" generation. Let's go with this one:
make menuconfig
You might need to resolve one more dependency ("ncurses") if you want the above command
to work. Once you do that you can choose any kernel configuration options you like. The
provided menu is quite complex but we are not in hurry. Take your time and enable or
disable any options you want. Don't forget to save your configuration. Now all we need
is to compile the new kernel.
make vmlinux
Depending on your configuration this time the build might take longer. Obviously if
you decide to go through manual kernel ".config" configuration you can no longer use
the script "2_build_kernel.sh" because it will override your new configuration with
the default configuration.
--- --- ---
Even though we haven't discussed this topic, you might have already noticed that the
file ".config" which comes along with the other build scripts contains the URL
locations for the kernel sources and the BusyBox sources. You can easily build live
Linux OS based on different kernel/BusyBox versions if you provide different
URLs in the ".config" file. Here is the content of the default ".config" file:
# You can find the latest Linux kernel source bundles here:
#
# http://kernel.org
#
KERNEL_SOURCE_URL=https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.15.6.tar.xz
# You can find the latest BusyBox source bundles here:
#
# http://busybox.net
#
BUSYBOX_SOURCE_URL=http://busybox.net/downloads/busybox-1.22.1.tar.bz2
Of course, once you do that you also need to go through the scripts "1_get_kernel.sh"
and "3_get_busybox.sh" or execute the relevant commands from these scripts manually.
--- --- ---
Another very interesting improvement is to execute /sbin/init and rely on further
configuration provided in /etc/inittab. Here is the modified version of the shell
script "5_generate_rootfs.sh":
#/bin/sh
cd work
rm -rf rootfs
cd busybox
cd $(ls -d *)
cp -R _install ../../rootfs
cd ../../rootfs
rm -f linuxrc
mkdir dev
mkdir etc
mkdir proc
mkdir src
mkdir sys
mkdir tmp
cd etc
touch bootscript.sh
echo '#!/bin/sh' >> bootscript.sh
echo 'dmesg -n 1' >> bootscript.sh
echo 'mount -t devtmpfs none /dev' >> bootscript.sh
echo 'mount -t proc none /proc' >> bootscript.sh
echo 'mount -t sysfs none /sys' >> bootscript.sh
echo >> bootscript.sh
chmod +x bootscript.sh
touch welcome.txt
echo >> welcome.txt
echo ' #####################################' >> welcome.txt
echo ' # #' >> welcome.txt
echo ' # Welcome to "Minimal Linux Live" #' >> welcome.txt
echo ' # #' >> welcome.txt
echo ' #####################################' >> welcome.txt
echo >> welcome.txt
touch inittab
echo '::sysinit:/etc/bootscript.sh' >> inittab
echo '::restart:/sbin/init' >> inittab
echo '::ctrlaltdel:/sbin/reboot' >> inittab
echo '::once:cat /etc/welcome.txt' >> inittab
echo '::respawn:/bin/cttyhack /bin/sh' >> inittab
echo 'tty2::once:cat /etc/welcome.txt' >> inittab
echo 'tty2::respawn:/bin/sh' >> inittab
echo 'tty3::once:cat /etc/welcome.txt' >> inittab
echo 'tty3::respawn:/bin/sh' >> inittab
echo 'tty4::once:cat /etc/welcome.txt' >> inittab
echo 'tty4::respawn:/bin/sh' >> inittab
echo >> inittab
cd ..
touch init
echo '#!/bin/sh' >> init
echo 'exec /sbin/init' >> init
echo >> init
chmod +x init
cp ../../*.sh src
cp ../../.config src
cd ../..
The above script creates very minimal /init which executes /sbin/init. Then the
new init process (that is /sbin/init with PID 1) reads the file /etc/inittab and
executes all commands provided there. The script /etc/bootscript.sh takes care of
the initial "mount" stuff. We also have 4 terminals (you can switch between them
with "Alt + F1" to "Alt + F4") and the contents of the file /etc/welcome.txt is
displayed before we access the shell for each of these terminals.
You can find more information about the supported /etc/inittab commands here:
http://git.busybox.net/busybox/tree/examples/inittab
Note that the above details are specific for BusyBox. Usually the "init" process
supports runlevels but that's not the case with BusyBox.
--- --- ---
Most probably you use normal user (i.e. not "root") when you execute the scripts.
One side effect is that the generated initrtamfs will keep the original ownership
of all files and folders. However, this leads to some interesting discrepancies
when you run the system. Some of the files/folders will have "root" ownership
(uid=0, gid=0) but most of the files/folders will have the same uid/gid as the
user which you used in order to build the system. This has no implications at all
since we have unrestricted shell console but if you'd like to "fix" this you will
have to either execute "5_generate_rootfs.sh" as "root" or manually change the
ownership of the initramfs folder (i.e. "work/rootfs") before you execute the
script "6_pack_rootfs.sh" with this command:
chown -R root:root work/rootfs
Note that the above command requires "root" permissions, so there is no way to
escape from the above described discrepancies if you don't have "root" access.
Also note that you may need to take care of the permissions for the script files
in the "work/rootfs/src" folder. Either delete the "src" folder before you run
"6_pack_rootfs.sh" or make sure that all files have global "read" permissions.
### ### ###
5. Epilogue
That's all folks! I hope you find this tutorial useful. And remember, we are talking
about very minimal live Linux OS here. If you want to create something bigger, I
suggest you take a look at "Linux From Scratch" (google it, you'll find it).
At some point you may also find it useful to play around with other live Linux
distributions. Don't forget that the initramfs file is compressed and in order to
get to the actual /init script you will need to uncompress it. Then you can see
the actual file structure of the initial root file system and examine the /init
script file. This will give you more insight on the boot process for the
particular live Linux distributions that you are learning from.
One interesting live Linux distribution is "Slax". Just download it and take a
look at the /init script file (remember, you can uncompress the initramfs file).
There is also a very good document which explains the internal root file system
and the OS boot process for Slax:
http://slax.org/en/documentation.php#internals
The above URL may have changed but it is valid at the time I write this document.