Programa mínimo init hola mundo paso a paso
Compile un hola mundo sin dependencias que termine en un bucle infinito. 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
No podemos usar la llamada al sistema de salida, o el kernel entrará en pánico, la única forma de salir correctamente del init es apagar la máquina con el reboot
llamada al sistema.
Entonces:
mkdir d
as --64 -o init.o init.S # assemble
ld -o d/init init.o # link
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
Esto crea un sistema de archivos con nuestro hola mundo en /init
, que es el primer programa de usuario que ejecutará el kernel. También podríamos haber agregado más archivos a d/
y serían accesibles desde el /init
programa cuando se ejecuta el kernel.
Entonces cd
en el árbol del kernel de Linux, compilar como de costumbre y ejecutarlo en 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"
Y deberías ver una línea:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
en la pantalla del emulador! Tenga en cuenta que no es la última línea, por lo que debe buscar un poco más arriba.
También puede usar programas C si los vincula estáticamente:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
con:
gcc -static init.c -o init
La vinculación dinámica requeriría configurar un ejecutable del vinculador dinámico, los más comunes de los cuales son parte de las bibliotecas estándar de C como glibc.
Puede ejecutarse en hardware real con un USB en /dev/sdX
y:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
Gran fuente sobre este tema:Consejo técnico:Cómo usar initramfs | landley.net También explica cómo usar gen_initramfs_list.sh
, que es un script del árbol de fuentes del kernel de Linux para ayudar a automatizar el proceso.
Probado en Ubuntu 16.10, QEMU 2.6.1.
Siguientes pasos
Lo siguiente que debe hacer es configurar BusyBox.
BusyBox implementa utilidades básicas de POSIX-y CLI, incluido un shell POSIX-y, que le permite experimentar más fácilmente con el sistema de forma interactiva.
Personalmente, en este momento prefiero confiar solo en Buildroot, que es un increíble conjunto de secuencias de comandos que automatiza la creación de todo desde el código fuente y crea el sistema de archivos raíz.
He subido un ayudante altamente detallado y automatizado para eso en:https://github.com/cirosantilli/linux-kernel-module-cheat
Yo no empezaría a jugar con LFS, que es un camino de jardín que lleva a un bosque oscuro.
Comience con una distribución en la que tenga mucho control sobre la instalación inicial, como Arch, o una edición autónoma como el servidor Ubuntu. El objetivo de esto no es tanto ahorrar espacio como delimitar la complejidad de la configuración de inicio; a partir de una distribución sin cabeza, si la aplicación que desea ejecutar requiere una GUI, puede agregar lo que se requiere para eso sin tener que terminar con un inicio de sesión de GUI (también conocido como el administrador de pantalla o DM) iniciado por init, y un escritorio completo ambiente para acompañarlo.
Entonces querrá aprender cómo configurar el sistema init para sus propósitos; tenga en cuenta que no puede prescindir de init, y puede ser el mejor medio para lograr su objetivo. El sistema de inicio que se usa en la mayoría de las distribuciones de Linux ahora es systemd.
El punto aquí es minimizar lo que hace init en el arranque, y así es como puede crear un sistema que ejecutará una cantidad mínima de software para admitir la aplicación en la que desea enfocarse; así es esencialmente cómo se configura un servidor, Por cierto, es una tarea común (tenga en cuenta que no puede tener literalmente "solo un" proceso de usuario en ejecución, al menos no de manera útil).
Si la aplicación que desea ejecutar es un programa GUI (un buen ejemplo de por qué no puede ejecutar literalmente una sola aplicación, ya que las aplicaciones GUI requieren un servidor X), puede tener un ~/.xinitrc
que se parece a esto;
#!/bin/sh
myprogram
Cuando entonces startx
, su programa será lo único que se ejecutará y será imposible cambiar de escritorio o iniciar cualquier otra cosa, en parte porque no hay un administrador de ventanas o un entorno de escritorio (por lo tanto, tampoco habrá marco de ventana ni barra de título).
si tienes un poco de programación y quieres crearlo desde cero, puedes usar LFS, es decir, Linux from Scratch http://www.linuxfromscratch.org/
si desea personalizar ubutnu, puede usar ubunt-builder y si lo desea en base a rpm, puede usar SUsE-Studio, Suse studio le permitirá crear suse linux personalizado
Saludos