c - Writing my own init executable -
i wanted create own init , linux fun snowy weekend. know, kernel boots rootfs , gives flow /sbin/init after driver loading , disk mounting. downloaded ubuntu cloud image , tried direct kernel boot kvm follows:
kvm -m 1g -nographic -kernel vmlinuz-3.19.0-32-generic -initrd initrd.img-3.19.0-32-generic -append "console=ttys0 root=/dev/sda1 rw init=/myinit" -hda mydisk.img it works fine trusty-server-cloudimg-amd64-disk1.img (if don't mind hanging @ cloud-init), proceeded copy , delete content.
modprobe nbd qemu-nbd -c /dev/nbd0 mydisk.img fdisk -l /dev/nbd0 # confirm partition mount /dev/nbd0p1 disk/ # delete files myinit.c , myinit and here magical init:
int main(){ printf("welcome kernel\n"); printf("welcome kernel\n"); printf("welcome kernel\n"); while(1); } i compile gcc -static myinit.c -o myinit. kernel panic occurs because of init. verified renaming myinit myinit2 , kernel not find it, , did not crash. know writing init cannot simple above, steps required it? reading upstart source code
begin: mounting root file system ... begin: running /scripts/local-top ... done. begin: running /scripts/local-premount ... [ 1.460164] tsc: refined tsc clocksource calibration: 2394.558 mhz [ 1.866560] input: imexps/2 generic explorer mouse /devices/platform/i8042/serio1/input/input3 done. [ 6.251763] ext4-fs (sda1): recovery complete [ 6.253623] ext4-fs (sda1): mounted filesystem ordered data mode. opts: (null) begin: running /scripts/local-bottom ... done. done. begin: running /scripts/init-bottom ... mount: mounting /dev on /root/dev failed: no such file or directory done. mount: mounting /sys on /root/sys failed: no such file or directory mount: mounting /proc on /root/proc failed: no such file or directory [ 6.299404] kernel panic - not syncing: attempted kill init! exitcode=0x00000200 [ 6.299404] [ 6.300013] cpu: 0 pid: 1 comm: init not tainted 3.19.0-32-generic #37~14.04.1-ubuntu [ 6.300013] hardware name: qemu standard pc (i440fx + piix, 1996), bios bochs 01/01/2011 [ 6.300013] ffff88003c118700 ffff88003dee7e38 ffffffff817af41b 00000000000017d6 [ 6.300013] ffffffff81a90be8 ffff88003dee7eb8 ffffffff817a925b ffff88003dee8000 [ 6.300013] ffffffff00000010 ffff88003dee7ec8 ffff88003dee7e68 ffffffff81c5ee20 [ 6.300013] call trace: [ 6.300013] [<ffffffff817af41b>] dump_stack+0x45/0x57 [ 6.300013] [<ffffffff817a925b>] panic+0xc1/0x1f5 [ 6.300013] [<ffffffff81077b01>] do_exit+0xa11/0xb00 [ 6.300013] [<ffffffff811ec53c>] ? vfs_write+0x15c/0x1f0 [ 6.300013] [<ffffffff81077c7f>] do_group_exit+0x3f/0xa0 [ 6.300013] [<ffffffff81077cf4>] sys_exit_group+0x14/0x20 [ 6.300013] [<ffffffff817b6dcd>] system_call_fastpath+0x16/0x1b [ 6.300013] kernel offset: 0x0 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 6.300013] drm_kms_helper: panic occurred, switching text console [ 6.300013] ---[ end kernel panic - not syncing: attempted kill init! exitcode=0x00000200 [ 6.300013] i know myinit static:
# ldd disk/myinit not dynamic executable so should not depend else, guess. doing wrong , why kernel panicking? (kernel panicks without printfs too)
i reading sysvinit source (it should simpler upstart & systemd & openrc) long, main idea of init own processes , rests in while(1) loop too.
your stdin, stdout , stderr might not connected when init starts. it's common see sequence similar following @ start of init program:
int onefd = open("/dev/console", o_rdonly, 0); dup2(onefd, 0); // stdin int twofd = open("/dev/console", o_rdwr, 0); dup2(twofd, 1); // stdout dup2(twofd, 2); // stderr if (onefd > 2) close(onefd); if (twofd > 2) close(twofd); this ensures stdin, stdout , stderr connected system console.
Comments
Post a Comment