CPIO ที่เริ่มต้นน้อยที่สุดโปรแกรมสวัสดีชาวโลกทีละขั้นตอน

คอมไพล์สวัสดีชาวโลกโดยไม่ต้องพึ่งพาใด ๆ ที่สิ้นสุดในวงวนไม่สิ้นสุด 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
เราไม่สามารถใช้sys_exitหรืออื่น ๆ ที่ทำให้ตกใจเคอร์เนล
แล้ว:
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"
สิ่งนี้สร้างระบบไฟล์ด้วย hello world ของเรา/initซึ่งเป็นโปรแกรม userland แรกที่เคอร์เนลจะทำงาน เราสามารถเพิ่มไฟล์เพิ่มเติมd/และพวกเขาจะสามารถเข้าถึงได้จาก/initโปรแกรมเมื่อเคอร์เนลทำงาน
จากนั้นcdเข้าไปในเคอร์เนลลินุกซ์สร้างเป็นปกติและเรียกใช้ใน 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"
และคุณควรเห็นบรรทัด:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
บนหน้าจออีมูเลเตอร์! โปรดทราบว่ามันไม่ใช่บรรทัดสุดท้ายดังนั้นคุณต้องค้นหาต่อไปอีกเล็กน้อย
คุณยังสามารถใช้โปรแกรม C หากคุณเชื่อมโยงโปรแกรมเหล่านี้แบบคงที่:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
ด้วย:
gcc -static init.c -o init
คุณสามารถเรียกใช้บนฮาร์ดแวร์จริงด้วยการเปิด USB /dev/sdXและ:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
แหล่งที่มาดีเยี่ยมในเรื่องนี้: http://landley.net/writing/rootfs-howto.htmlนอกจากนี้ยังอธิบายถึงวิธีการใช้gen_initramfs_list.shซึ่งเป็นสคริปต์จากทรีของเคอร์เนล Linux เพื่อช่วยให้กระบวนการทำงานโดยอัตโนมัติ
ขั้นตอนถัดไป: ตั้งค่า BusyBox เพื่อให้คุณสามารถโต้ตอบกับระบบ: /unix/2692/what-is-the-smallest-possible-linux-implementation/203902#203902
ทดสอบกับ Ubuntu 16.10, QEMU 2.6.1