• Added the current version of the website located at http://minimal.linux-bg.org
This commit is contained in:
parent
d116c397c9
commit
91506680aa
260
www/index.html
Normal file
260
www/index.html
Normal 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>
|
||||
<a href="#" onclick="javascript:menuSwap(2); return false;">Changes</a>
|
||||
<a href="#" onclick="javascript:menuSwap(3); return false;">About</a>
|
||||
<a href="#" onclick="javascript:menuSwap(4); return false;">Tutorial</a>
|
||||
<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 & 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 ©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
139
www/style.css
Normal 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;
|
||||
}
|
678
www/the_dao_of_minimal_linux_live.txt
Normal file
678
www/the_dao_of_minimal_linux_live.txt
Normal 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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user