aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/earlyinit/main.go58
1 files changed, 58 insertions, 0 deletions
diff --git a/cmd/earlyinit/main.go b/cmd/earlyinit/main.go
new file mode 100644
index 00000000..53017835
--- /dev/null
+++ b/cmd/earlyinit/main.go
@@ -0,0 +1,58 @@
+package main
+
+import (
+ "log"
+ "os"
+ "runtime"
+ . "syscall"
+)
+
+func main() {
+ runtime.LockOSThread()
+ log.SetFlags(0)
+ log.SetPrefix("earlyinit: ")
+
+ if err := Mount(
+ "devtmpfs",
+ "/dev/",
+ "devtmpfs",
+ MS_NOSUID|MS_NOEXEC,
+ "",
+ ); err != nil {
+ log.Fatalf("cannot mount devtmpfs: %v", err)
+ }
+
+ // The kernel might be unable to set up the console. When that happens,
+ // printk is called with "Warning: unable to open an initial console."
+ // and the init runs with no files. The checkfds runtime function
+ // populates 0-2 by opening /dev/null for them.
+ //
+ // This check replaces 1 and 2 with /dev/kmsg to improve the chance
+ // of output being visible to the user.
+ if fi, err := os.Stdout.Stat(); err == nil {
+ if stat, ok := fi.Sys().(*Stat_t); ok {
+ if stat.Rdev == 0x103 {
+ var fd int
+ if fd, err = Open(
+ "/dev/kmsg",
+ O_WRONLY|O_CLOEXEC,
+ 0,
+ ); err != nil {
+ log.Fatalf("cannot open kmsg: %v", err)
+ }
+
+ if err = Dup3(fd, Stdout, 0); err != nil {
+ log.Fatalf("cannot open stdout: %v", err)
+ }
+ if err = Dup3(fd, Stderr, 0); err != nil {
+ log.Fatalf("cannot open stderr: %v", err)
+ }
+
+ if err = Close(fd); err != nil {
+ log.Printf("cannot close kmsg: %v", err)
+ }
+ }
+ }
+ }
+
+}