From 3becd7f27c6702fea6a719460f1a2ab2f029cd6f Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Fri, 27 Jul 2018 13:40:38 -0700 Subject: [PATCH] QEMU: allow us to run from QEMU for testing This introduces a new KERNEL command line switch, nichromeroot if nichromeroot is in the command line, the uinit command will look for the parameter, e.g. nichromeroot=/dev/sda will cause uinit to grab the cpio from /dev/sda (not a typo! by using /dev/sda, not /dev/sda2, we don't have to mess with partitions in the qemu hard drive) This makes a certain amount of testing possible. We now run Xorg instead of Xfbdev and that works better. However we need to test on a Chromebook. This requires #845 from u-root. It will finally be possible to test NiChrome in qemu, unlike ChromeOS. This is tested and actually seems to work. QRUN is a sample QEMU usage. I replicate it here for history. First, we can do this: go run usb/*.go -dev=/tmp/t usb will create two files, /tmp/t2 and /tmp/t3. t3 is the cpio image. Then we can run qemu qemu-system-x86_64 \ -m 2048M \ -kernel linux-stable/arch/x86/boot/bzImage \ -s \ -monitor /dev/null \ -serial stdio \ -append 'nichromeroot=/dev/sda' \ -drive id=disk,file=/tmp/t3,if=none \ -device ich9-ahci,id=ahci \ -device ide-drive,drive=disk,bus=ahci.0 and /tmp/t3 is used as the disk. Note the nichromeroot switch. Signed-off-by: Ronald G. Minnich --- QRUN | 21 +++++++++++++++ cmds/uinit/uinit.go | 63 ++++++++++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 QRUN diff --git a/QRUN b/QRUN new file mode 100644 index 000000000..7e854ba11 --- /dev/null +++ b/QRUN @@ -0,0 +1,21 @@ +# The file /tmp/t3 was produced as follows: +# go run usb/*.go -dev=/tmp/t +# /tmp/t2 and /tmp/t3 are created and you can use /tmp/t3 +# as hda as shown below. +# -s is gdb +# -monitor allows you to hit ^C in the term window you start +# this from to kill QEMU +qemu-system-x86_64 \ +-m 2048M \ +-cpu max \ +-machine pc-q35-zesty \ +-kernel linux-stable/arch/x86/boot/bzImage \ +-s \ +-monitor /dev/null \ +-serial stdio \ +-vga cirrus \ +-append 'nichromeroot=/dev/sda' \ +-drive id=disk,file=/tmp/t3,if=none \ +-device ich9-ahci,id=ahci \ +-device ide-drive,drive=disk,bus=ahci.0 \ + diff --git a/cmds/uinit/uinit.go b/cmds/uinit/uinit.go index 8bf36a966..d367f5c8b 100644 --- a/cmds/uinit/uinit.go +++ b/cmds/uinit/uinit.go @@ -270,6 +270,39 @@ func xrunuser() error { return x11("/usr/local/bin/aterm") } +func cpioRoot(r string) error { + var err error + log.Printf("Try device %v", r) + cmd := exec.Command("cpio", "i") + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + if cmd.Stdin, err = os.Open(r); err != nil { + return fmt.Errorf("%v", err) + } + if err := cmd.Run(); err != nil { + return fmt.Errorf("cpio of tcz failed %v", err) + } + return nil +} +// This is a best effort. It does not return an error because +// an error may not really be an error; we may be intentionally +// running without a root. +func guidRoot() { + // USB sucks. + // We've tried a few variants of this loop so far trying for + // 10 seconds and waiting for 1 second each time has been the best. + for i := 0; i < 10; i++ { + r, err := findRoot("/dev/sda", "/dev/sdb", "/dev/mmcblk0", "/dev/mmcblk1") + if err != nil { + log.Printf("Could not find root: %v", err) + } else { + if err := cpioRoot(r); err == nil { + break + } + } + time.Sleep(time.Second) + } +} + func main() { // nasty, but I'm sick of losing boot messages. f, err := os.OpenFile("/log", os.O_RDWR|os.O_CREATE, 0755) @@ -318,32 +351,10 @@ func main() { verbose = true } - var cpio bool - // USB sucks. - // We've tried a few variants of this loop so far trying for - // 10 seconds and waiting for 1 second each time has been the best. - for i := 0; i < 10; i++ { - r, err := findRoot("/dev/sda", "/dev/sdb", "/dev/mmcblk0", "/dev/mmcblk1") - if err != nil { - log.Printf("Could not find root: %v", err) - } else { - log.Printf("Try device %v", r) - cmd := exec.Command("cpio", "i") - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - if cmd.Stdin, err = os.Open(r); err == nil { - if err := cmd.Run(); err != nil { - log.Printf("cpio of tcz failed %v; continuing", err) - } else { - cpio = true - } - } else { - log.Printf("Can't open (%v); not trying to cpio it", r) - } - if cpio { - break - } - } - time.Sleep(time.Second) + if d, ok := cmdline["nichromeroot"]; ok { + cpioRoot(d) + } else { + guidRoot() } if err := tczSetup(); err != nil {