You are not logged in.
Pages: 1
Topic closed
Hi,
I want to build a image with a kernel and an initramfs (that I can boot from qemu) for learning purpose but I'm stuck, here's what I've done so far:
build the kernel, end up with a bzImage file (compressed kernel image) for x86_64
make a 50MB ext2 disk:
$ dd if=/dev/zero of=disk.raw bs=1M count=50
$ mkfs.ext2 -F disk.raw
make a tiny initrd with a "hello world" init program:
# hello world in asm with embed ELF header & using system calls
$ cat > hello.asm
BITS 32
org 0x08048000
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident
times 8 db 0
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf32_Phdr
dd 1 ; p_type
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd filesize ; p_filesz
dd filesize ; p_memsz
dd 5 ; p_flags
dd 0x1000 ; p_align
phdrsize equ $ - phdr
_start:
; write(1, "hello\n", 6)
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msglen
int 80h
; exit(0)
mov eax, 1
mov ebx, 0
int 80h
msg db "hello", 10
msglen equ $ - msg
filesize equ $ - $$
^D
$ nasm -f bin -o initrd/init hello.asm
# test it out
$ ./initrd/init
hello
# make the img
$ cd initrd && find . | cpio --quiet -H newc -o | gzip -9 -n > ../initrd.img && cd ..
copy everything on the disk
$ mkdir disk
$ mount disk.raw disk
$ mkdir disk/boot
$ cp initrd.img bzImage disk/boot
install syslinux
$ cat > disk/boot/syslinux.cfg
DEFAULT linux
LABEL linux
SAY Booting linux
LINUX /boot/bzImage
APPEND root=/dev/sda
INITRD /boot/initrd.img
^D
$ extlinux -i disk/boot
$ umount disk
install mbr
$ dd bs=440 count=1 conv=notrunc if=/usr/lib/syslinux/bios/mbr.bin of=disk.raw
But when I run the image in qemu
$ qemu-system-x86_64 disk.raw
I get the syslinux error: "Operating system load error" and it then tries to boot other devices (floppy, cd, net, ...).
You can get a script of the above command to test it out, along with the kernel here:
http://diobla.info/stuff/boot/mklinux
http://diobla.info/stuff/boot/bzImage (5MB)
Make a directory, cd in it, download the script and the kernel image then run script.
You need cpio, nasm, e2fsprogs, syslinux and finally qemu
The script must be run as root, be careful!
there's only a single filesystem without partition, is the root arg in the syslinux.cfg correct?
is syslinux.cfg the correct file? Could be syslinux.conf, extlinux.conf or extlinux.cfg but none of them seem work either.
Last edited by knarf (2014-02-20 17:42:27)
Offline
Ok so
I've switched to partitions instead of whole disk
fixed some bugs in the script: heredoc string (<<EOF style) are expanded if you don't quote the EOF token, leading to the asm source being wrong.
Mounting partitions is not as simple as mounting the whole disk fs. See https://wiki.archlinux.org/index.php/Qe … disk_image
The updated script is at the same url.
...and it works! The kernet boots, runs init which prints hello and exit, and the kernel crashes (which is normal since init is not supposed to exit).
I'm now trying to enable the framebuffer in order to get the /dev/fb0 device. I've enabled a bunch of CONFIG_FB_* stuff in the kernel config which lets me change the resolution and add a logo with the vga=<code> kernel parameter but no /dev/fb0 device!
knarf ~/prog/c/linux-3.7.2 > grep '^C.*_FB' .config
CONFIG_FB=y
CONFIG_FB_BOOT_VESA_SUPPORT=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_VGA16=y
CONFIG_FB_UVESA=y
CONFIG_FB_VESA=y
CONFIG_FB_EFI=y
CONFIG_FB_VIRTUAL=y
Last edited by knarf (2014-02-19 23:26:19)
Offline
To create the fb0 device you need to use the mknod system call. The framebuffer major device number is 29 and the minor one for fb0 is well 0.
Thus the call is:
mknod("/dev/fb0", S_IFCHR, makedev(29, 0))
I've compiled statically my init C code that draws a dumb xor-texture with musl-c and it works, here's the result
http://diobla.info/stuff/boot/draw.c
Last edited by knarf (2014-02-19 12:15:16)
Offline
@knarf thank you sharing your experience. I followed your instructions, built a kernel-2.6 bzImage and made an initrd with above hello.asm in /sbin/init. When I run it like qemu-system-x86_64 -kernel bzImage -initrd rootfs.cpio.gz -append "root=/dev/ram0" it prints hello then crashes which is ok. But when I replace hello.asm example with hello.c example it fails to load init. It simply hangs after freeing memory line.
I also tried another advanced initrd images which is built from busybox but it also fails to start init process. Why does it fail to start init? What am I missing? It is most probably related to kernel config. I also followed other kernel building for embedded systems to fit in a floppy but it didn't work. Perhaps I am missing some flags to run qemu-system-x86_64 ?
Offline
You have been warned about necrobumping before, kenn, please don't do it again.
https://wiki.archlinux.org/index.php/Fo … bumping.22
Closing.
Sakura:-
Mobo: MSI MAG X570S TORPEDO MAX // Processor: AMD Ryzen 9 5950X @4.9GHz // GFX: AMD Radeon RX 5700 XT // RAM: 32GB (4x 8GB) Corsair DDR4 (@ 3000MHz) // Storage: 1x 3TB HDD, 6x 1TB SSD, 2x 120GB SSD, 1x 275GB M2 SSD
Making lemonade from lemons since 2015.
Offline
Pages: 1
Topic closed