Synced src
file
This commit is contained in:
parent
5fe0dadffc
commit
1b96586efd
@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
1. Preface
|
1. Preface
|
||||||
|
|
||||||
Please feel free to redistribute this document in any form you see fit. I only ask you to
|
Please feel free to redistribute this document in any form you see fit. However, I'd like to
|
||||||
respect my efforts and keep me as the original author. That's all I ask.
|
ask of you to respect my efforts and mention me as the original author - that's my only demand.
|
||||||
|
|
||||||
Note that the explanations regarding the script details are based on the "28-Jul-2014"
|
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
|
version of "Minimal Linux Live". Future versions of the scripts may already include some
|
||||||
@ -41,49 +41,49 @@
|
|||||||
|
|
||||||
2. Boot Process
|
2. Boot Process
|
||||||
|
|
||||||
The overall boot process is quite complex but we need to know these details since we are
|
The overall boot process is quite complex, but we need to know these details as we are
|
||||||
talking about operating systems and to be more precise - Linux based operating systems.
|
talking about operating systems and, precisely, Linux based operating systems.
|
||||||
|
|
||||||
You can find some general information here:
|
You can find some general information here:
|
||||||
|
|
||||||
http://en.wikipedia.org/wiki/Linux_startup_process
|
http://en.wikipedia.org/wiki/Linux_startup_process
|
||||||
|
|
||||||
When we talk about live Linux OS, the overall boot process is the following:
|
When it comes to 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
|
1) BIOS gives the execution control to the boot loader present on the boot media such
|
||||||
as CD, DVD, USB flash or something else.
|
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
|
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.
|
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
|
3) The boot media also contains a special configuration file, which points to the location
|
||||||
of the kernel/initramfs files.
|
of the kernel/initramfs files.
|
||||||
4) Now that Syslinux knows where the kernel file is, it loads it in the RAM and passes
|
4) Now that Syslinux knows where the kernel file is, it loads it in the RAM and passes
|
||||||
the execution control to it.
|
the execution control to it.
|
||||||
5) The kernel detects the available hardware, loads necessary drivers and then it passes
|
5) The kernel detects the available hardware, loads necessary drivers and then it passes
|
||||||
the execution control to the initramfs.
|
the execution control to the initramfs.
|
||||||
6) The initramfs file is an archive which is unpacked automatically by the kernel in the
|
6) The initramfs file is an archive, automatically unpacked by the kernel in the
|
||||||
RAM. The actual execution control is passed to the shell script file /init which must
|
RAM. The actual execution control is passed to the shell script file /init, which must
|
||||||
be present in the initramfs file.
|
be present in the initramfs file.
|
||||||
7) Since we are talking about minimal live CD, in theory /init is not supposed to do much.
|
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.
|
All we need from /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
|
In most live Linux distributions, the /init script is supposed to do much more than
|
||||||
but in our case for now it is enough to know that the point at which we take the control
|
this, but for the time being, it's enough to know that the point at which we take
|
||||||
is exactly the /init script.
|
control is exactly the /init script.
|
||||||
|
|
||||||
### ### ###
|
### ### ###
|
||||||
|
|
||||||
3. Inside The Shell Scripts
|
3. Inside The Shell Scripts
|
||||||
|
|
||||||
So far we learned that we need several pieces in order to build a live Linux OS:
|
So far, we have learnt that we need several pieces in order to build a live Linux OS:
|
||||||
|
|
||||||
1) boot loader - to make our media bootable.
|
1) boot loader - to make our media bootable.
|
||||||
2) kernel file - to take care of the initial system bootstrap process.
|
2) kernel file - to take care of the initial system bootstrap process.
|
||||||
3) initramfs file - to prepare the necessary environment for the user.
|
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
|
This document focuses on parts (2) and (3). The reason why 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
|
because the build process that we are going to rely on later, takes care of the boot loader
|
||||||
part automatically.
|
part automatically.
|
||||||
|
|
||||||
The ZIP which you have downloaded contains the following files:
|
The ZIP, which you have downloaded, contains the following files:
|
||||||
|
|
||||||
.config
|
.config
|
||||||
0_prepare.sh
|
0_prepare.sh
|
||||||
@ -96,19 +96,19 @@
|
|||||||
7_generate_iso.sh
|
7_generate_iso.sh
|
||||||
build_minimal_linux_live.sh
|
build_minimal_linux_live.sh
|
||||||
|
|
||||||
If you have followed the explanation posted on http://minimal.idzona.com then you already
|
If you have followed the explanation posted on http://minimal.idzona.com , then you should already
|
||||||
know that you need to execute the script "build_minimal_linux_live.sh". If you open this
|
know you need to execute the script "build_minimal_linux_live.sh". If you open this script
|
||||||
file with text editor you will find out that all this script does is to execute all other
|
with a text editor, you will find out that everything it does is to execute all other
|
||||||
scripts one by one.
|
scripts one by one.
|
||||||
|
|
||||||
From this point onwards, I encourage you to execute the script files one by one. We will
|
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
|
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
|
it only creates an empty folder named "work". We will store our temporary
|
||||||
work files there.
|
work files there.
|
||||||
|
|
||||||
OK, let's continue with the kernel. Somehow we need to end up with fully functional kernel which
|
OK, let's continue with the kernel. Somehow, we need to end up with a fully functional kernel, which
|
||||||
is able to do the system initialization for us. We need to download the kernel sources, compile
|
is able to perform the system initialization for us. We need to download the kernel sources,
|
||||||
these sources and finally pack the kernel.
|
compile them and finally pack the kernel.
|
||||||
|
|
||||||
The script "1_get_kernel.sh" downloads the kernel sources and unpacks them. Here is the full
|
The script "1_get_kernel.sh" downloads the kernel sources and unpacks them. Here is the full
|
||||||
source code of the script:
|
source code of the script:
|
||||||
@ -126,9 +126,9 @@
|
|||||||
tar -xvf $ARCHIVE_FILE -C kernel
|
tar -xvf $ARCHIVE_FILE -C kernel
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
First we read the ".config" file to find the URL for the kernel sources. The URL is stored in
|
Firstly, we have to read the ".config" file in order to find the URL for the kernel sources,
|
||||||
the variable "DOWNLOAD_URL". Then we get the actual name of the archive file and we store the
|
which is stored in the "DOWNLOAD_URL" variable. Then, we get the actual name of the archive
|
||||||
name in the variable "ARCHIVE_FILE".
|
file and we store it in the variable "ARCHIVE_FILE".
|
||||||
|
|
||||||
The important part of the script is the line where we get the kernel sources:
|
The important part of the script is the line where we get the kernel sources:
|
||||||
|
|
||||||
@ -138,7 +138,7 @@
|
|||||||
|
|
||||||
tar -xvf $ARCHIVE_FILE -C kernel
|
tar -xvf $ARCHIVE_FILE -C kernel
|
||||||
|
|
||||||
At this point we have downloaded and unpacked the kernel sources. So far so good. Now we need
|
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
|
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:
|
the full source code that we are going to analyse:
|
||||||
|
|
||||||
@ -152,7 +152,7 @@
|
|||||||
make vmlinux
|
make vmlinux
|
||||||
cd ../../..
|
cd ../../..
|
||||||
|
|
||||||
First we navigate to the kernel source folder. Then we execute the following commands:
|
First we navigate to the kernel source folder. Then, we execute the following commands:
|
||||||
|
|
||||||
make clean
|
make clean
|
||||||
|
|
||||||
@ -161,38 +161,38 @@
|
|||||||
|
|
||||||
make defconfig
|
make defconfig
|
||||||
|
|
||||||
The above command creates new ".config" file in the current folder which contains all default
|
The abovementioned command creates new ".config" file in the current folder, which contains all
|
||||||
configuration parameters that we need in order to build our new kernel. Note that the defaults
|
default configuration parameters needed to build our new kernel. Note that the defaults
|
||||||
will be either 32 or 64 bit specific, depending on your Linux environment.
|
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
|
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
|
The command searches for a specific line in the ".config" file, containing the string
|
||||||
"CONFIG_DEFAULT_HOSTNAME" and replaces the whole line with the following text:
|
"CONFIG_DEFAULT_HOSTNAME" and replaces this whole line with the following text:
|
||||||
|
|
||||||
CONFIG_DEFAULT_HOSTNAME="minimal-linux-live"
|
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
|
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
|
see the string "minimal-linux-live" in the output. All we did was to replace the default value
|
||||||
"(none)" with our custom value.
|
"(none)" with our custom value.
|
||||||
|
|
||||||
Now you have a sample command which you can use to search for specific configurations in the
|
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
|
file ".config" and replace these configurations with ones of your own. Obviously, you can skip
|
||||||
replacement and everything will work just fine. Like I said, the only difference will be that
|
this replacement - and everything will work just fine. Like I said, the only difference will be
|
||||||
the default host name will be "minimal-linux-live" instead of "(none)".
|
that the default host name will be set to "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
|
Now we come to the most important and also slowest part in the whole process: we need to
|
||||||
actually create the kernel.
|
actually create the kernel.
|
||||||
|
|
||||||
make vmlinux
|
make vmlinux
|
||||||
|
|
||||||
The above command will compile the Linux kernel. This takes a lot of time, so I guess it's
|
The abovementioned command will compile the Linux kernel. This usually takes quite a while, so I
|
||||||
high time for a short break. The final kernel file is located here:
|
guess it's high time for a short break. The final kernel file is located here:
|
||||||
|
|
||||||
arch/x86/boot/bzImage
|
arch/x86/boot/bzImage
|
||||||
|
|
||||||
OK, at this point we should have a kernel file compiled with default options, where we have
|
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
|
changed the default host name with some other value of our own. Now, we move to the next
|
||||||
part.
|
part.
|
||||||
|
|
||||||
The kernel itself is far from enough - we also need some kind of environment with basic
|
The kernel itself is far from enough - we also need some kind of environment with basic
|
||||||
@ -201,8 +201,8 @@
|
|||||||
|
|
||||||
1) We are going to download & compile BusyBox. This will give us the basic command line
|
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.
|
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
|
2) We will use BusyBox to provide us with some default directory/file structure, which
|
||||||
we will modify into our own initramfs file.
|
we are going to 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
|
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":
|
script file "3_get_busybox.sh":
|
||||||
@ -220,11 +220,11 @@
|
|||||||
tar -xvf $ARCHIVE_FILE -C busybox
|
tar -xvf $ARCHIVE_FILE -C busybox
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
The contents is almost identical to the one in "1_get_kernel.sh" which we have already
|
The contents are almost identical to the one in "1_get_kernel.sh", which we already
|
||||||
explained above. Long story short - we get the source archive with "wget" and then we
|
explained earlier. 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.
|
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
|
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:
|
script "4_build_busybox.sh" which we need to execute:
|
||||||
|
|
||||||
#/bin/sh
|
#/bin/sh
|
||||||
@ -239,48 +239,48 @@
|
|||||||
cd ../../..
|
cd ../../..
|
||||||
|
|
||||||
You have probably already noticed it - we are going to execute several "make" commands
|
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
|
and meanwhile, we will change one property in the ".config" file. Let's go
|
||||||
through all of these commands:
|
through all of these commands:
|
||||||
|
|
||||||
make clean
|
make clean
|
||||||
|
|
||||||
The above command ensures that we will get rid of all build artefacts, assuming this
|
The command above ensures that we will get rid of all build artefacts, assuming this
|
||||||
is not the first time we go through the BusyBox build process.
|
is not the first time we go through the BusyBox build process.
|
||||||
|
|
||||||
make defconfig
|
make defconfig
|
||||||
|
|
||||||
The above command creates new ".config" file which contains the defaults for proper
|
This command creates new ".config" file, which contains the defaults for proper
|
||||||
BusyBox build process. Again, nothing extraordinary here.
|
BusyBox build process. Again, nothing extraordinary here.
|
||||||
|
|
||||||
sed -i "s/.*CONFIG_STATIC.*/CONFIG_STATIC=y/" .config
|
sed -i "s/.*CONFIG_STATIC.*/CONFIG_STATIC=y/" .config
|
||||||
|
|
||||||
The above command is very important because we inform the build process to build
|
The command above is very important, because we inform the build process to build
|
||||||
static version of BusyBox, which means that the BusyBox executable file will not
|
a static version of BusyBox, meaning that the BusyBox executable file will not
|
||||||
be dependent on any external library. We cannot skip this, otherwise our OS will
|
be dependent on any external library. We cannot skip this step, otherwise our OS will
|
||||||
fail with "kernel panic" when we try to boot.
|
fail with "kernel panic" when we try to boot.
|
||||||
|
|
||||||
make busybox
|
make busybox
|
||||||
|
|
||||||
The above command compiles BusyBox. Nothing interesting here. The build should be
|
The command above compiles BusyBox. Nothing interesting here. The build should be
|
||||||
significantly faster compared to the kernel build.
|
significantly faster compared to the kernel build.
|
||||||
|
|
||||||
make install
|
make install
|
||||||
|
|
||||||
The above command creates new "_install" folder and installs BusyBox in it. We
|
The command above creates new "_install" folder and installs BusyBox in it. We
|
||||||
will use this folder as a base for our new initramfs file.
|
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
|
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
|
one of them, but it's no big deal) and we should also have BusyBox compiled with
|
||||||
static option enabled and all other default settings.
|
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
|
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 are these:
|
will pack into a file. The steps that we are going to follow are these:
|
||||||
|
|
||||||
1) Use the already created "_install" folder as base for initramfs.
|
1) Use the already created "_install" folder as base for initramfs.
|
||||||
2) Create some new folders in the initramfs folder.
|
2) Create some new folders in the initramfs folder.
|
||||||
3) Create some configuration files 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
|
Now we come to the script "5_generate_rootfs.sh" which is responsible for generating
|
||||||
proper initramfs folder with all necessary files and sub-folders in it.
|
proper initramfs folder with all necessary files and sub-folders in it.
|
||||||
|
|
||||||
#/bin/sh
|
#/bin/sh
|
||||||
@ -325,7 +325,7 @@
|
|||||||
cp ../../.config src
|
cp ../../.config src
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
As you see, this script is much longer than the others. Let's take a look at the
|
As you can see, this script is much longer than the others. Let's take a look at the
|
||||||
important parts one by one.
|
important parts one by one.
|
||||||
|
|
||||||
cd work
|
cd work
|
||||||
@ -335,8 +335,8 @@
|
|||||||
cp -R _install ../../rootfs
|
cp -R _install ../../rootfs
|
||||||
cd ../../rootfs
|
cd ../../rootfs
|
||||||
|
|
||||||
The above code snippet removes the old initramfs folder called "rootfs" and then
|
The code snippet above removes the old initramfs folder called "rootfs", then
|
||||||
copies the "_install" folder (the one created by BusyBox) with new name "rootfs".
|
copies the "_install" folder (the one created by BusyBox) with a new name - "rootfs".
|
||||||
This folder is going to be our new initramfs focal point.
|
This folder is going to be our new initramfs focal point.
|
||||||
|
|
||||||
rm -f linuxrc
|
rm -f linuxrc
|
||||||
@ -356,7 +356,7 @@
|
|||||||
mkdir sys
|
mkdir sys
|
||||||
mkdir tmp
|
mkdir tmp
|
||||||
|
|
||||||
The above code snippet creates some basic folders which we are going to use later.
|
The code snippet above creates some basic folders which we are going to use later.
|
||||||
|
|
||||||
cd etc
|
cd etc
|
||||||
touch welcome.txt
|
touch welcome.txt
|
||||||
@ -369,7 +369,7 @@
|
|||||||
echo >> welcome.txt
|
echo >> welcome.txt
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
The above code snippet creates the file "/etc/welcome.txt" and fills it with the message
|
The code snippet above creates the file "/etc/welcome.txt" and fills it with the message
|
||||||
which will be displayed every time we boot up the system.
|
which will be displayed every time we boot up the system.
|
||||||
|
|
||||||
touch init
|
touch init
|
||||||
@ -385,13 +385,13 @@
|
|||||||
echo 'done' >> init
|
echo 'done' >> init
|
||||||
echo >> init
|
echo >> init
|
||||||
|
|
||||||
The above code snippet creates the file "/init" which is going to be invoked by our kernel
|
The code snippet above 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
|
when we boot up the system. In fact, we create new shell script file. This is what our new
|
||||||
"/init" script does:
|
"/init" script does:
|
||||||
|
|
||||||
dmesg -n 1 - We hide all kernel messages. We don't want them in our
|
dmesg -n 1 - We hide all kernel messages. We don't want them in our
|
||||||
console. Only kernel panic messages will be displayed.
|
console. Only kernel panic messages will be displayed.
|
||||||
mount -t devtmpfs none /dev - With this command we politely ask the kernel to
|
mount -t devtmpfs none /dev - With this command, we politely ask the kernel to
|
||||||
populate the /dev folder with all necessary system
|
populate the /dev folder with all necessary system
|
||||||
devices like "console", "tty", etc. We also have nice
|
devices like "console", "tty", etc. We also have nice
|
||||||
names for the hardware devices like "sr0", "sda", etc.
|
names for the hardware devices like "sr0", "sda", etc.
|
||||||
@ -402,22 +402,22 @@
|
|||||||
setsid cttyhack /bin/sh we rest assured that when we execute the "exit"
|
setsid cttyhack /bin/sh we rest assured that when we execute the "exit"
|
||||||
done command new shell will be started automatically.
|
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.
|
As you can see, what the "/init" script file does isn't too much, however, it's really essential.
|
||||||
We have only one more bit of code relevant to the "/init" file:
|
We have only one more bit of code relevant to the "/init" file:
|
||||||
|
|
||||||
chmod +x init
|
chmod +x init
|
||||||
|
|
||||||
The above command ensures that our "/init" script is executable.
|
The command above ensures that our "/init" script is executable.
|
||||||
|
|
||||||
cp ../../*.sh src
|
cp ../../*.sh src
|
||||||
cp ../../.config src
|
cp ../../.config src
|
||||||
|
|
||||||
The last thing we do is to copy all "Minimal Linux Live" shell scripts (including the
|
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
|
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
|
simply ensures that the live Linux ISO file, which we are going to create later, contains
|
||||||
the build sources, just for reference.
|
the build sources, just for reference.
|
||||||
|
|
||||||
OK, at this point we have "rootfs" folder which contains all necessary files and
|
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
|
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":
|
into an actual initramfs file. Let's take a look at "6_pack_rootfs.sh":
|
||||||
|
|
||||||
@ -429,13 +429,13 @@
|
|||||||
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
|
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
The above script removes the already existing initramfs file called "rootfs.cpio.gz"
|
The abovementioned 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
|
then creates a new file called "rootfs.cpio.gz" based on the contents of the
|
||||||
"rootfs" folder.
|
"rootfs" folder.
|
||||||
|
|
||||||
We are almost finished. At this point we have already compiled the Linux kernel and we
|
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.
|
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
|
The last thing to do is to generate a bootable ISO file. Let's take a look at the last
|
||||||
script "7_generate_iso.sh":
|
script "7_generate_iso.sh":
|
||||||
|
|
||||||
#/bin/sh
|
#/bin/sh
|
||||||
@ -447,18 +447,18 @@
|
|||||||
cp arch/x86/boot/image.iso ../../../minimal_linux_live.iso
|
cp arch/x86/boot/image.iso ../../../minimal_linux_live.iso
|
||||||
cd ../../..
|
cd ../../..
|
||||||
|
|
||||||
As usual, we first remove the already generated ISO file, assuming this is not the first
|
As usual, firstly we 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
|
time we go through this process. Then we navigate to the kernel's source folder and
|
||||||
we execute the following command:
|
we execute the following command:
|
||||||
|
|
||||||
make isoimage FDINITRD=../../rootfs.cpio.gz
|
make isoimage FDINITRD=../../rootfs.cpio.gz
|
||||||
|
|
||||||
The above command generates bootable ISO based on the already compiled Linux kernel and
|
This 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.
|
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.
|
The generated ISO file is then copied to the folder where we are executing our scripts.
|
||||||
|
|
||||||
UPDATE (02-Oct-2016): The "make isoimage" command relies on Syslinux older than 5.0.
|
UPDATE (02-Oct-2016): The "make isoimage" command relies on Syslinux older than 5.0.
|
||||||
The issue is that Syslinux versions after 5.0 require ldlinux.c32 which is not handled
|
The issue: Syslinux versions after 5.0 require ldlinux.c32 which is not handled
|
||||||
correctly by the kernel's Makefile. You need to appply a patch to the Makefile in order
|
correctly by the kernel's Makefile. You need to appply a patch to the Makefile in order
|
||||||
to make it work correctly. I find it easier to edit the Makefile and apply the patch
|
to make it work correctly. I find it easier to edit the Makefile and apply the patch
|
||||||
changes manually:
|
changes manually:
|
||||||
@ -476,7 +476,7 @@
|
|||||||
fi ; \ # old line
|
fi ; \ # old line
|
||||||
|
|
||||||
Another possible solution is to manually generate the ISO image by executing the
|
Another possible solution is to manually generate the ISO image by executing the
|
||||||
command "genisoimage" with the appropriate arguaments. You can take a look at the
|
command "genisoimage" with the appropriate arguments. You can take a look at the
|
||||||
project "Minimal Linux Script" which follows the "genisoimage" approach:
|
project "Minimal Linux Script" which follows the "genisoimage" approach:
|
||||||
|
|
||||||
http://github.com/ivandavidov/minimal-linux-script
|
http://github.com/ivandavidov/minimal-linux-script
|
||||||
@ -496,27 +496,27 @@
|
|||||||
while it is still running. You can examine the final result for yourself and modify
|
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.
|
the "5_generate_rootfs.sh" script according to your needs.
|
||||||
|
|
||||||
OK, let's go with the "root" account!
|
OK, let's try with the "root" account!
|
||||||
|
|
||||||
touch /etc/group
|
touch /etc/group
|
||||||
|
|
||||||
The above command will create empty file "/etc/group" where we store the information
|
The command above will create empty file "/etc/group" where we store the information
|
||||||
for all groups.
|
for all groups.
|
||||||
|
|
||||||
addgroup -g 0 root
|
addgroup -g 0 root
|
||||||
|
|
||||||
The above command will create a group "root" with group identification number "0".
|
This one 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
|
It is important to provide 0 (zero) as group identifier (gid) because this is the
|
||||||
expected gid for "root".
|
expected gid for "root".
|
||||||
|
|
||||||
touch /etc/passwd
|
touch /etc/passwd
|
||||||
|
|
||||||
The above command will create empty file "/etc/passwd" where we store the login
|
This command will create empty file "/etc/passwd" where we store the login
|
||||||
information for our users.
|
information for our users.
|
||||||
|
|
||||||
adduser -h /root -G root -u 0 root
|
adduser -h /root -G root -u 0 root
|
||||||
|
|
||||||
The above command will create user "root" with home folder "/root", assign the new
|
This 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
|
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
|
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.
|
whatever password you want when asked. Try to remember it.
|
||||||
@ -533,18 +533,18 @@
|
|||||||
|
|
||||||
chmod 1777 /tmp
|
chmod 1777 /tmp
|
||||||
|
|
||||||
The reason I haven't included this in the /init script is because in this particular
|
I haven't included this in the /init script, as in this particular situation
|
||||||
situation it doesn't really matter. By default we get uid=0 shell console and we have
|
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
|
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
|
users to the system (not just the "root" user), you may also include the above command
|
||||||
in the /init script file.
|
in the /init script file.
|
||||||
|
|
||||||
--- --- ---
|
--- --- ---
|
||||||
|
|
||||||
Probably the easiest update you can do is to re-compile the kernel with other than
|
Probably the easiest update you can do is to re-compile the kernel with other options
|
||||||
default options. This is how we do it for the kernel. First of all we need to know
|
instead of the default ones. This is how we do it for the kernel. First of all we need
|
||||||
what possible options we have. Navigate to the kernel's source folder and execute the
|
to know what possible options we have. Navigate to the kernel's source folder and execute
|
||||||
following command:
|
the following command:
|
||||||
|
|
||||||
make help
|
make help
|
||||||
|
|
||||||
@ -553,22 +553,22 @@
|
|||||||
make menuconfig
|
make menuconfig
|
||||||
|
|
||||||
You might need to resolve one more dependency ("ncurses") if you want the above command
|
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
|
to work. Once this is done, 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
|
provided menu is quite complex, but we are not in a hurry. Take your time and enable or
|
||||||
disable any options you want. Don't forget to save your configuration. Now all we need
|
disable any options you want. Don't forget to save your configuration. Now all we need
|
||||||
is to compile the new kernel.
|
is to compile the new kernel.
|
||||||
|
|
||||||
make vmlinux
|
make vmlinux
|
||||||
|
|
||||||
Depending on your configuration this time the build might take longer. Obviously if
|
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
|
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 script "2_build_kernel.sh" because it will override your new configuration with
|
||||||
the default configuration.
|
the default one.
|
||||||
|
|
||||||
--- --- ---
|
--- --- ---
|
||||||
|
|
||||||
Even though we haven't discussed this topic, you might have already noticed that the
|
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
|
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
|
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
|
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:
|
URLs in the ".config" file. Here is the content of the default ".config" file:
|
||||||
@ -585,7 +585,7 @@
|
|||||||
#
|
#
|
||||||
BUSYBOX_SOURCE_URL=http://busybox.net/downloads/busybox-1.22.1.tar.bz2
|
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"
|
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.
|
and "3_get_busybox.sh" or execute the relevant commands from these scripts manually.
|
||||||
|
|
||||||
--- --- ---
|
--- --- ---
|
||||||
@ -649,84 +649,84 @@
|
|||||||
cp ../../.config src
|
cp ../../.config src
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
The above script creates very minimal /init which executes /sbin/init. Then the
|
This 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
|
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
|
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
|
the initial "mount" stuff. We also have 4 terminals (that you can switch between
|
||||||
with "Alt + F1" to "Alt + F4") and the contents of the file /etc/welcome.txt is
|
with "Alt + F1" to "Alt + F4") and the contents of the file /etc/welcome.txt are
|
||||||
displayed before we access the shell for each of these terminals.
|
displayed before we access the shell for each of these terminals.
|
||||||
|
|
||||||
You can find more information about the supported /etc/inittab commands here:
|
You can find more information about the supported /etc/inittab commands here:
|
||||||
|
|
||||||
http://git.busybox.net/busybox/tree/examples/inittab
|
http://git.busybox.net/busybox/tree/examples/inittab
|
||||||
|
|
||||||
Note that the above details are specific for BusyBox. Usually the "init" process
|
Note that the details above are specific to BusyBox. Usually, the "init" process
|
||||||
supports runlevels but that's not the case with BusyBox.
|
supports runlevels, but that's not the case here.
|
||||||
|
|
||||||
--- --- ---
|
--- --- ---
|
||||||
|
|
||||||
Most probably you use normal user (i.e. not "root") when you execute the scripts.
|
You are most probably using a normal user (i.e. not "root") when you execute the
|
||||||
One side effect is that the generated initrtamfs will keep the original ownership
|
scripts. One side effect of this is, the generated initrtamfs will keep the original
|
||||||
of all files and folders. However, this leads to some interesting discrepancies
|
ownership of all files and folders. However, this leads to some interesting
|
||||||
when you run the system. Some of the files/folders will have "root" ownership
|
discrepancies when you run the system. Some of the files/folders will have "root"
|
||||||
(uid=0, gid=0) but most of the files/folders will have the same uid/gid as the
|
ownership (uid=0, gid=0), but most of the files/folders will have the same uid/gid
|
||||||
user which you used in order to build the system. This has no implications at all
|
as the user which you used in order to build the system. This has no implications
|
||||||
since we have unrestricted shell console but if you'd like to "fix" this you will
|
at all since we have unrestricted shell console but if you'd like to "fix" this,
|
||||||
have to either execute "5_generate_rootfs.sh" as "root" or manually change the
|
you will have to either execute "5_generate_rootfs.sh" as "root" or manually
|
||||||
ownership of the initramfs folder (i.e. "work/rootfs") before you execute the
|
change the ownership of the initramfs folder (i.e. "work/rootfs") before you
|
||||||
script "6_pack_rootfs.sh" with this command:
|
execute the script "6_pack_rootfs.sh" with this command:
|
||||||
|
|
||||||
chown -R root:root work/rootfs
|
chown -R root:root work/rootfs
|
||||||
|
|
||||||
Note that the above command requires "root" permissions, so there is no way to
|
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.
|
escape from the abovementioned discrepancies unless you have "root" access.
|
||||||
|
|
||||||
Also note that you may need to take care of the permissions for the script files
|
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
|
in the "work/rootfs/src" folder. To do so, either delete the "src" folder before you
|
||||||
"6_pack_rootfs.sh" or make sure that all files have global "read" permissions.
|
run "6_pack_rootfs.sh" or make sure that all files have global "read" permissions.
|
||||||
|
|
||||||
### ### ###
|
### ### ###
|
||||||
|
|
||||||
5. Next Steps
|
5. Next Steps
|
||||||
|
|
||||||
OK, now we know how to build and run a basic Linux system. But that's not enough.
|
OK, now we know how to build and run a basic Linux system. But that's not enough.
|
||||||
Now we want to build more complex system, probably one which supports "pacman",
|
Now we would like to build a more complex system, probably one which supports "pacman",
|
||||||
"apt-get", or any other package manager.
|
"apt-get", or any other package manager.
|
||||||
|
|
||||||
Building such system requires a lot more work. A lot more! I mean it!
|
Building such a system requires a lot more work. A lot more! I mean it!
|
||||||
|
|
||||||
For starters, "Minimal Linux Live" lives entirely in the "initramfs" space. Simply
|
For starters, "Minimal Linux Live" lives entirely in the "initramfs" space. Simply
|
||||||
said - this is the RAM space. We never really get out of there. Basically this is
|
said - this is the RAM space. We never really get out of there. Basically this is
|
||||||
what you need if you want more functional live Linux system:
|
what you need if you want a more functional live Linux system:
|
||||||
|
|
||||||
1) Compressed file system (SquashFS)- this is where all the real stuff will be.
|
1) Compressed file system (SquashFS)- where all the real stuff would be.
|
||||||
|
|
||||||
2) GNU Coreutils - these are the real shell command line utilities (ls, cd, etc.).
|
2) GNU Coreutils - these are the real shell command line utilities (ls, cd, etc.).
|
||||||
You need them because later we are going to "escape" from "initramfs" and use
|
You need them as later on, we would "escape" from "initramfs" and use the
|
||||||
the actual file system available in the compressed file. Alternatively, you can
|
actual file system available in the compressed file. Alternatively, you can
|
||||||
overlay the whole "BusyBox" environment on top of the compressed file system but
|
overlay the whole "BusyBox" environment on top of the compressed file system but
|
||||||
that's not really professional approach.
|
that's not really a professional approach.
|
||||||
|
|
||||||
3) You need to "switch_root" to the actual file system (the compressed one) which
|
3) You need to "switch_root" to the actual file system (the compressed one) which
|
||||||
you first need to locate, then mount and finally make it "writable" by overlaying
|
you first need to locate, then mount and finally make it "writable" by overlaying
|
||||||
virtual RAM files/folders via UnionFS/AuFS (or something similar) if the bootable
|
virtual RAM files/folders via UnionFS/AuFS (or something similar) in case the bootable
|
||||||
media is not already writable. Remember that you are mounting compressed FS, which
|
media is not already writable. Remember that you are mounting compressed FS, which
|
||||||
means that if you make any changes on files located in the original FS, they will
|
means that if you make any changes on files located in the original FS, they will
|
||||||
not be persisted between reboots. Probably you want to handle this edge case.
|
not be persisted between reboots. Probably, you would like to handle this edge case.
|
||||||
|
|
||||||
4) You need to prepare in advance the stuff that you want to be present in the
|
4) You need to prepare the stuff that you want to be present in the compressed file
|
||||||
compressed file system. Assuming that we are building a useful live Linux OS, the
|
system in advance. Assuming that we are building a useful live Linux OS, the
|
||||||
absolute minimum is "GNU Coreutils", network management utilities and probably
|
absolute minimum is "GNU Coreutils", network management utilities and probably
|
||||||
some kind of package manager, e.g. "pacman" or "apt-get". Don't forget that most
|
some kind of package manager, e.g. "pacman" or "apt-get". Don't forget that most
|
||||||
of this additional stuff most probably relies on different kernel options that
|
of this additional stuff very likely relies on different kernel options that
|
||||||
also need to be enabled/configured in advance.
|
also need to be enabled/configured beforehand.
|
||||||
|
|
||||||
5) You need to rewrite /init and make it execute all necessary steps to fulfil point 3
|
5) You need to rewrite /init and make it execute all necessary steps to fulfil point 3
|
||||||
from the above. Different live Linux systems use different approaches here.
|
from the above. Different live Linux systems use different approaches here.
|
||||||
|
|
||||||
All of the above is definitely *not* minimal but it's definitely doable if you put some
|
All of the above is definitely *not* minimal but it's definitely doable if you put some
|
||||||
additional efforts. It will take time but as a result you will have fully functional live
|
additional effort. It will take time, but as a result you would have a fully functional live
|
||||||
Linux OS which you have created entirely by yourself.
|
Linux OS, which you would have created entirely by yourself.
|
||||||
|
|
||||||
### ### ###
|
### ### ###
|
||||||
|
|
||||||
@ -736,7 +736,7 @@
|
|||||||
about very minimal live Linux OS here. If you want to create something bigger, I
|
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).
|
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
|
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
|
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
|
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
|
the actual file structure of the initial root file system and examine the /init
|
||||||
|
Loading…
x
Reference in New Issue
Block a user