HExSA-Lab / nautilus

Nautilus Aerokernel
Other
44 stars 60 forks source link

[BUG] #21

Closed mikerainey closed 5 years ago

mikerainey commented 5 years ago

Describe the bug Nautilus fails to boot in qemu.

One potential complication is that I'm running qemu in Nixos, a distribution of Linux. Given the nature of the error, however, it's not obvious to me that the problem is related to Nix or the various packages of grub, qemu, etc., that are provided by Nix.

The version of grub2 that I'm using is the version recommended by the Nautilus manual.

If it seems too tricky to boot Nautilus in Nixos, I can instead try with Ubuntu. However, having a Nautilus package for Nix might be independently useful. One perk is, for example, that all package dependencies are handled automatically by the Nix package manager.

To Reproduce This process can be reproduced using any distribution of Linux, as long as the Nix package manager is installed on the target machine.

  1. Install the nix package manager.

  2. Create the file default.nix as listed below.

default.nix

{ pkgs   ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  gcc ? pkgs.gcc,
  grub ? pkgs.grub2,
  xorriso ? pkgs.xorriso
}:

stdenv.mkDerivation rec {
  name = "nautilus";

  # uncomment the line below, if you want to build from the official nautilus repository
  # src = pkgs.fetchFromGitHub {
  #   owner  = "HExSA-Lab";
  #   repo   = "nautilus";
  #   rev    = "85aadf2c5df31e364f19c00384d0950df6ea32e8";
  #   sha256 = "1l0dvrd1bjzx5b53nhj9hi3z1bs9fghlmfwj7dj3nzzb9zxfarg2";
  # };

  # uncomment the line below, if you want to build from local sources, in the folder ./nautilus
  #  src = ./nautilus;

  src = pkgs.fetchFromGitHub {
    owner  = "PrescienceLab";
    repo   = "nautilus-cs446";
    rev    = "7c3073ac66c78ef0e9f0b8acc6c25d6d186c5f15";
    sha256 = "0h64jgf1wfb9zfhm5mm5hhcj2fkrw72k43rn644s86h9b9hjqc54";
  };

  buildInputs = [ gcc grub xorriso ];

  buildPhase = ''
    cp configs/cs446-example-config .config
    echo "N" | make oldconfig
    make isoimage
  '';

  installPhase = ''
    mkdir -p $out
    cp nautilus.iso $out/    
  '';

}
  1. Build the Nautilus ISO image.
$ nix-build

After building, there should appear in the current folder a new symlink named result, which points to a folder. In this folder, there should appear the file nautilus.iso.

  1. Start a nix shell, making available the qemu package.
$ nix-shell -p qemu
  1. Try to run the iso image.
$ qemu-system-x86_64 -cdrom result/nautilus.iso -m 2048 -curses -nographic

Expected behavior The screenshot displayed below will alternate between the grub and Nautilus screens in an apparent infinite loop.

Screenshots Below is the output from qemu.

SeaBIOS (version rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org)

iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+7FF913B0+7FEF13B0 C980
Press Ctrl-B to configure iPXE (PCI 00:03.0)...

Booting from Hard Disk...
Boot failed: could not read the boot disk

Booting from Floppy...
Boot failed: could not read the boot disk

Booting from DVD/CD...
Welcome to GRUB!

Booting `Nautilus'

error: you need to load the kernel first.
CPU ? (): dev: devices inited
CPU ? (): chardev: init
CPU ? (): blkdev: init
CPU ? (): netdev: init
Welcome to                                         
    _   __               __   _  __                
   / | / /____ _ __  __ / /_ (_)/ /__  __ _____    
  /  |/ // __ `// / / // __// // // / / // ___/    
 / /|  // /_/ // /_/ // /_ / // // /_/ /(__  )     
/_/ |_/ \__,_/ \__,_/ \__//_//_/ \__,_//____/  
+===============================================+  
 Kyle C. Hale (c) 2014 | Northwestern University   
+===============================================+  

Detected AuthenticAMD Processor
BOOTMEM: Setting up boot memory allocator
BOOTMEM: Memory map[] - [0x00000000 - 0x00000000] <>
BOOTMEM: Memory map[] - [0x00000001 - 0x000a0000]

Build Environment (please complete the following information):

Runtime Environment (please complete the following information):

Kernel Configuration (please include):

Changes Made to Nautilus (please include): The Nix package default.nix specifies that Nautilus be built from sources in the cs446 repository, using the student configuration cs446-example-config.

PeterDinda commented 5 years ago

Interesting differential - on the same environment (Ubuntu 18) a switch from clang to gcc and the bug shows up. It almost looks like a compiler decision results in code being generated for a very early code path that clobbers the e820 and mptable.

Also, there is something strange in multiboot_get_modules_end, in that it seems to detect modules (I can see "Increasing kern end... " to an improbable value:

CPU ? (): DEBUG: Increasing kern end to 0x00467421

PeterDinda commented 5 years ago

More info - the first indication of problems on the gcc build is that in printing the memory table, the string array that contains memory type names is clobberd, or perhaps not loaded:

pdinda@Petronius:~/test/nautilus$ grep memregion *.syms nautilus.bin.clang.syms:00000000003ed600 g O .data 0000000000000030 mem_region_types nautilus.bin.gcc.syms:0000000000465720 g O .data 0000000000000030 mem_region_types

Note that clang places them much earlier - it basically builds NK much more compactly than gcc. Perhaps grub isn't loading enough "enough", or something clobbers this early on.

If you look at the elf sections for both builds, it also looks---possibly---strange that the physaddrs of th load sections are not aligned.

PeterDinda commented 5 years ago

Mike, if you do a pull now and rebuild everything, does your problem go away? Particularly the commit marked "gcc compile fix"

khale commented 5 years ago

Confirmation from @pzhzqt that a clean pull resolves the bootup issue on Ubuntu

mikerainey commented 5 years ago

Hi Kevin & Peter,

Thanks for the update!

I tried again using the procedure listed in my previous message, above, but this time using the latest revision in the nautilus repository (rev 47c20f54478f69407228d60848cb886f5fcb8402). The configuration file I'm using is configs/testing/default.config. The default.nix script that I used appears below.

{ pkgs   ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  gcc ? pkgs.gcc,
  grub ? pkgs.grub2,
  xorriso ? pkgs.xorriso
}:

stdenv.mkDerivation rec {
  name = "nautilus";

  src = pkgs.fetchFromGitHub {
    owner  = "HExSA-Lab";
    repo   = "nautilus";
    rev    = "47c20f54478f69407228d60848cb886f5fcb8402";
    sha256 = "0f612kraxibhs3ggrpzyr1081i3634hrzjx3vyir4bqvdp61l5hv";
  };

#  src = ./nautilus;

  # src = pkgs.fetchFromGitHub {
  #   owner  = "PrescienceLab";
  #   repo   = "nautilus-cs446";
  #   rev    = "7c3073ac66c78ef0e9f0b8acc6c25d6d186c5f15";
  #   sha256 = "0h64jgf1wfb9zfhm5mm5hhcj2fkrw72k43rn644s86h9b9hjqc54";
  # };

  buildInputs = [ gcc grub xorriso ];

  buildPhase = ''
    cp configs/testing/default.config .config
    echo "N" | make oldconfig
    make isoimage
  '';

  installPhase = ''
    mkdir -p $out
    cp nautilus.iso $out/    
  '';

}

After building, I run the command below.

$ cp ./result/nautilus.iso nautilus6.iso && chmod a+rwx ./nautilus6.iso
$ sudo qemu-system-x86_64 -cdrom ./nautilus6.iso -m 2048 -curses -nographic -chardev stdio,id=char0,mux=on,logfile=serial.log,signal=off -serial chardev:char0 -mon chardev=char0

This time there is different behavior, but the boot process seems to get stuck earlier.

SeaBIOS (version rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org)

iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+7FF913B0+7FEF13B0 C980
Press Ctrl-B to configure iPXE (PCI 00:03.0)...

Booting from Hard Disk...
Boot failed: could not read the boot disk

Booting from Floppy...
Boot failed: could not read the boot disk

Booting from DVD/CD...
Welcome to GRUB!

Booting `Nautilus'
PeterDinda commented 5 years ago

A few questions:

PeterDinda commented 5 years ago

Also, what happens if you use nautilus/configs/eecs446-example-config for your configuration?

The testing configs force a run of tests at boot, and don't boot to a shell. It may be functional, but with all output sitting on the serial port.

mikerainey commented 5 years ago

Using a new nautilus configuration file seemed to make the difference. Now, when I run qemu, the terminal shows the following.

CPU 0 (P 1 "*unnamed*"): DEBUG: e1000_pci: RDLEN=0x00000800, RDH=0x00000000, RDT=0x00000000, RCTL=0x0080802
CPU 0 (P 1 "*unnamed*"): fs: inited
PMC: Initializing PMC subsystem
CPU 0 (P 1 "*unnamed*"): WARNING : PMC: Insufficient AMD PMC support for perf counter subsystem
CPU 0 (P 1 "*unnamed*"): WARNING : PMC: Disabling PMC subsystem
parsing cmdline 
CPU 0 (P 1 "*unnamed*"): Shell root-shell launched on cpu 0 as 0000000001872000
Nautilus boot thread yielding (indefinitely)
root-shell>

At this point, when I try to type something into the root-shell> prompt, nothing happens, but it may just be the correct behavior, or something related to the way I configured qemu.

For reference, I'm attaching the scripts I used to install and run this build of nautilus. First, the build script I used is default.nix, shown below.

{ pkgs   ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  gcc ? pkgs.gcc,
  grub ? pkgs.grub2,
  xorriso ? pkgs.xorriso,
  nautilusConfig ? ./.
}:

stdenv.mkDerivation rec {
  name = "nautilus";

  src = pkgs.fetchFromGitHub {
    owner  = "HExSA-Lab";
    repo   = "nautilus";
    rev    = "47c20f54478f69407228d60848cb886f5fcb8402";
    sha256 = "0f612kraxibhs3ggrpzyr1081i3634hrzjx3vyir4bqvdp61l5hv";
  };

  buildInputs = [ gcc grub xorriso ];

  buildPhase = ''                                                                                                      
    cp ${nautilusConfig}/nautilus-config.txt .config                                                                   
    make oldconfig -j                                                                                                  
    make isoimage -j                                                                                                   
  '';

  installPhase = ''                                                                                                    
    mkdir -p $out                                                                                                      
    cp nautilus.iso $out/                                                                                              
  '';

}

The script I used to run the iso image of nautilus is named shell.nix.

{ pkgs   ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  nautilus ? import ./default.nix { pkgs = pkgs; },
  qemu ? pkgs.qemu
}:

stdenv.mkDerivation {
  name = "nautilus-shell";
  buildInputs = [ qemu nautilus ];
  shellHook = ''                                                                                                       
    qemu-system-x86_64 -cdrom ${nautilus}/nautilus.iso -m 2048 -curses -nographic                                      
  '';
}

Finally, the nautilus configuration file is linked by nautilus-config.txt. The sample configuration file at nautilus/configs/eecs446-example-config seems to be missing a number of parameters (e.g., NAUT_CONFIG_RUST_SUPPORT), which is why I provide a link to an alternative configuration file.

To reproduce, put all three of these files in the same folder, and run nix-shell.

I succeeded in building nautilus with gcc versions 5.5.0 and 7.4.0. The version of gcc can be specified by changing the default value of the gcc parameter in default.nix (e.g., from pkgs.gcc to pkgs.gcc5).

khale commented 5 years ago

Thanks for the link to the new config file @mikerainey. I'm going to mark this issue as closed now.