1 /*- 2 * Copyright (c) 2022, Netflix, Inc. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 /* 8 * Mini-init(8) so we can run as init/pid 1 in a LinuxBoot environment. 9 */ 10 11 #include "stand.h" 12 #include "host_syscall.h" 13 #include "kboot.h" 14 15 /* 16 * Create a 'standard' early boot environment. Cribbed from the things that 17 * sysvinit, u-root, and initramfs-tools do. This is a minimal environment 18 * for modern Linux systems, though the /tmp, /run and /var stuff can likely 19 * be done inside the initrd image itself (as can creating the mount points 20 * for /proc, /dev and /sys). 21 * 22 * Note: We ignore errors here. There's no stderr to report them to yet. These 23 * operations generally can't fail, but if they do, we may not have the ability 24 * to report them later. 25 */ 26 static void 27 init_fs_env(void) 28 { 29 /* 30 * Create directories for mandatory filesystems and mount them. 31 */ 32 host_mkdir("/proc", 0555); 33 host_mount("proc", "/proc", "proc", MS_RELATIME, ""); 34 host_mkdir("/sys", 0555); 35 host_mount("sysfs", "/sys", "sysfs", MS_RELATIME, ""); 36 host_mkdir("/dev", 0755); 37 host_mount("devtmpfs", "/dev", "devtmpfs", MS_RELATIME, 38 "mode=0755,nr_inodes=0"); 39 40 /* 41 * Create compat links: /dev/fd lives in /proc, and needs some help to 42 * get setup. 43 */ 44 host_symlink("/proc/self/fd", "/dev/fd"); 45 host_symlink("fd/0", "/dev/stdin"); 46 host_symlink("fd/1", "/dev/stdout"); 47 host_symlink("fd/2", "/dev/stderr"); 48 49 50 /* 51 * Unsure if we need this, but create a sane /tmp just in case that's useful. 52 * and point /run over to it. 53 */ 54 host_mkdir("/tmp", 01777); 55 host_mount("tmpfs", "/tmp", "tmpfs", MS_RELATIME, "size=10%,mode=1777"); 56 host_symlink("/tmp", "/run"); 57 58 /* 59 * Unsure the loader needs /var and /var/log, but they are easy to 60 * create. 61 */ 62 host_mkdir("/var", 0555); 63 host_mkdir("/var/lock", 0555); 64 host_symlink("/tmp", "/var/tmp"); 65 } 66 67 static void 68 init_tty(void) 69 { 70 int fd; 71 72 /* 73 * sysvinit asks the linux kernel to convert the CTRL-ALT-DEL to a SIGINT, 74 * but we skip that. 75 */ 76 77 /* 78 * Setup /dev/console as stdin/out/err 79 */ 80 host_close(0); 81 host_close(1); 82 host_close(2); 83 fd = host_open("/dev/console", HOST_O_RDWR | HOST_O_NOCTTY, 0); 84 host_dup(fd); 85 host_dup(fd); 86 #if 0 87 /* 88 * I think we may need to put it in 'raw' mode, but maybe not. Linux 89 * sysvinit sets it into 'sane' mode with several tweaks. Not enabled at 90 * the moment since host console initialization seems sufficient. 91 */ 92 struct host_termios tty; 93 94 host_cfmakeraw(&tty); 95 host_tcsetattr(fd, HOST_TCANOW, &tty); 96 host_tcflush(fd, HOST_TCIOFLUSH) 97 #endif 98 } 99 100 static void 101 init_sig(void) 102 { 103 /* 104 * since we're running as init, we need to catch some signals 105 */ 106 107 /* 108 * setup signals here 109 * 110 * sysvinit catches a lot of signals, but the boot loader needn't catch 111 * so many since we don't do as much as it does. If we need to, put the 112 * signal catching / ignoring code here. If we implement a 'shell' 113 * function to spawn a sub-shell, we'll likely need to do a lot more. 114 */ 115 } 116 117 void 118 do_init(void) 119 { 120 /* 121 * Only pid 1 is init 122 */ 123 if (host_getpid() != 1) 124 return; 125 126 init_fs_env(); 127 init_tty(); 128 init_sig(); 129 } 130