updated: 2024-02-05 Mon 00:00

HURD notes

Table of Contents


1. build gnumach and mig

2. experiments with gnumach

2.1. generate ISO

Install necessary packages to generate iso:

# apt-get install mtools
# apt-get install grub-pc-bin    //if you are using grub EFI boot in host OS

create grub.cfg

menuentry "Hurd" {
	multiboot /boot/gnumach
}
$ cd gnumach/build/
$ mkdir -p hurdiso/boot/grub
$ cp gnumach hurdiso/boot/
$ cp grub.cfg hurdiso/boot/grub/grub.cfg
$ grub-mkrescue -o hurdiso.iso hurdiso
$ qemu-system-i386 -cdrom hurdiso.iso

2.2. run kernel directly

You can run kernel direcly using -kernel option:

$ qemu-system-i386 -kernel gnumach

3. serial port output

boot gnumach with parameter "console=com0 or com1"

$ qemu-system-i386 -kernel gnumach -nographic -append "console=com0"

exit from qemu

ctrl+a x 

4. debugging

$ qemu-system-i386 -s -S -kernel gnumach

In another shell

$ gdb ./gnumach
(gdb) target remote :1234
Press c to continue booting

5. grub note for HURD

https://www.gnu.org/software/grub/manual/grub/html_node/GNU_002fHurd.html

grub> multiboot /boot/gnumach.gz root=device:hd0s1
grub> module  /hurd/ext2fs.static ext2fs --readonly \
		   --multiboot-command-line='${kernel-command-line}' \
		   --host-priv-port='${host-port}' \
		   --device-master-port='${device-port}' \
		   --exec-server-task='${exec-task}' -T typed '${root}' \
		   '$(task-create)' '$(task-resume)'
grub> module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'

Install necessary packages to generate iso:

# apt-get install mtools
# apt-get install grub-pc-bin    //if you are using grub EFI boot in host OS

6. HURD SMP testing guide

download: https://www.gnu.org/software/hurd/hurd/running/qemu.html

unzip debian-hurd-*.img and run

$ kvm -m 2G -drive cache=writeback,file=debian-hurd-VERSION.img -device rtl8139,netdev=net0 -netdev user,id=net0,hostfwd=tcp::2223-:22

Set your password and username. You can ssh using username@127.0.0.1 -p 2223

Install git, necessary tools to build gnumach

$ git clone git://git.savannah.gnu.org/hurd/gnumach.git
$ cd gnumach
$ autoreconf -i
$ mkdir build
$ cd build
$ ../configure --enable-ncpus=4 --enable-apic --enable-kdb --disable-linux-groups
$ make gnumach.gz
$ su
# mv /boot/gnumach-1.8-486.gz /boot/gnumach-1.8-486.gz.bak
# cp gnumach.gz /boot/gnumach-1.8-486.gz

update /boot/grub/grub.cfg change hd0 to wd0 and add console=com0 (optional).

/boot/gnumach-1.8-486.gz root=part:2:device:wd0 console=com0

update /etc/fstab and update wd0 instead of hd0.

...
/dev/wd0s2      /               ext2    defaults        0       1
/dev/wd0s1      none            swap    sw              0       0

You can shutdown /sbin/poweroff

start qemu with -smp 4. add -nographic if you want to use com0

$ qemu-system-i386 -M q35,accel=kvm -smp 4 -m 2G -net user,hostfwd=tcp::2223-:22 -net nic  -hda debian-hurd-VERSION.img -nographic

To test smp:

$ sudo /path/to/smp /bin/bash
$ stress -c 7

source: https://lists.gnu.org/archive/html/bug-hurd/2024-02/msg00088.html

/* Run a task on slave_pset
    Copyright (C) 2024 Free Software Foundation, Inc.

    This file is part of the GNU Hurd.

    The GNU Hurd is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2, or (at
    your option) any later version.

    The GNU Hurd is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <hurd.h>
#include <version.h>
#include <mach/mach_types.h>
#include <mach/mach_host.h>

static void
smp(char * const argv[])
{
   int err;
   unsigned int pset_count;
   mach_port_t hostpriv;
   processor_set_name_array_t psets = {0};
   processor_set_t slave_pset = {0};

   if (get_privileged_ports (&hostpriv, NULL))
     error (1, 0, "Must be run as root for privileged cpu control");

   err = host_processor_sets (hostpriv, &psets, &pset_count);
   if (err)
     error (1, 0, "Cannot get list of host processor sets");

   if (pset_count < 2)
     error (1, 0, "gnumach does not have the expected processor sets, are you running smp kernel?");

   err = host_processor_set_priv (hostpriv, psets[1], &slave_pset);
   if (err)
     error (1, 0, "Cannot get access to slave processor set");

   err = task_assign(mach_task_self(), slave_pset, FALSE);
   if (err)
     error (1, 0, "Cannot assign task self to slave processor set");

   execve(argv[1], &argv[1], NULL);
   /* NOT REACHED */
}

int
main (int argc, char **argv)
{
   smp(argv);
   return 0;
}

7. useful links