Minimal initrd CPIO hello world program step-by-step
Compile a hello world without any dependencies that ends in an infinite loop. init.S
:
.global _start
_start:
mov $1, %rax
mov $1, %rdi
mov $message, %rsi
mov $message_len, %rdx
syscall
jmp .
message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
.equ message_len, . - message
We cannot use sys_exit
, or else the kernel panics.
Then:
mkdir d
as --64 -o init.o init.S
ld -o init d/init.o
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
This creates a filesystem with our hello world at /init
, which is the first userland program that the kernel will run. We could also have added more files to d/
and they would be accessible from the /init
program when the kernel runs.
Then cd
into the Linux kernel tree, build is as usual, and run it in QEMU:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"
And you should see a line:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
on the emulator screen! Note that it is not the last line, so you have to look a bit further up.
You can also use C programs if you link them statically:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
with:
gcc -static init.c -o init
You can run on real hardware with a USB on /dev/sdX
and:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
Great source on this subject: http://landley.net/writing/rootfs-howto.html It also explains how to use gen_initramfs_list.sh
, which is a script from the Linux kernel source tree to help automate the process.
Next step: setup BusyBox so you can interact with the system: https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902
Tested on Ubuntu 16.10, QEMU 2.6.1.
http://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else – Ciro Santilli 新疆改造中心法轮功六四事件 – 2015-10-25T20:05:35.367
It won't be able to grab 100% of the CPU seeing as your OS still needs some resources. – n0pe – 2011-08-08T17:44:00.943
@MaxMackie Obviously, but I would like the OS to only take over on behalf of the application (for networking purposes for instance). – dschatz – 2011-08-08T17:45:14.030
1You realize that even with a desktop environment loaded, but sitting there idle, it isn't using any cpu time right? And the ram it is using is subject to being swapped out if other applications demand it. – psusi – 2011-08-08T18:28:42.697
@dschatz It would help if you include more details in your question. Like telling us more about what application you want to run, how you want it to perform and what kind of hardware you're using. – N.N. – 2011-08-08T21:17:34.100
If possible, I would like to know why do you want this. From what I understand, you want to remove everything from the OS (console included) just to run your app. The performance gains will be marginal so what is the point of having all that work? – nmat – 2011-08-08T21:22:05.283