Toying Around With Xv6 X86

From the project’s Github repository:

xv6 is a re-implementation of Dennis Ritchie’s and Ken Thompson’s Unix Version 6 (v6). xv6 loosely follows the structure and style of v6, but is implemented for a modern x86-based multiprocessor using ANSI C.

Having a small footprint and code base, xv6 is an excellent tool to deepen in operating systems internals, like boot process, virtual memory setup, basics of a filesystem…
The version I tried is the i386 port, but again in the project’s repo we can read:

NOTE: we have stopped maintaining the x86 version of xv6, and switched our efforts to the RISC-V version

That shouldn’t be a problem, except that the Makefile needs a small update to work with modern gcc:

index 09d790c..3ef2c4b 100644
--- a/Makefile
+++ b/Makefile
@@ -78,6 +78,7 @@ OBJCOPY = $(TOOLPREFIX)objcopy
 OBJDUMP = $(TOOLPREFIX)objdump
 CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer
 CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
+CFLAGS += -Wno-array-bounds -Wno-infinite-recursion
 ASFLAGS = -m32 -gdwarf-2 -Wa,-divide
 # FreeBSD ld wants ``elf_i386_fbsd''
 LDFLAGS += -m $(shell $(LD) -V | grep elf_i386 2>/dev/null | head -n 1)C

gcc is more picky nowadays, and it’s a good thing™️

Now run:

$ make xv6.img fs.img

And fire up qemu:

$ qemu-system-i386 -m 256 -hdb fs.img xv6.img -serial stdio -display none
cpu0: starting 0
sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
init: starting sh
$

Or of course, have a little more fun, in one terminal:

$ qemu-system-i386 -m 256 -hdb fs.img xv6.img -serial stdio -display none -S -s

And another:

$ gdb
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x0000fff0 in ?? ()
(gdb) b *0x7c00
Breakpoint 1 at 0x7c00
(gdb) c
Continuing.

Breakpoint 1, 0x00007c00 in ?? ()
(gdb) x/10i $pc
=> 0x7c00:      cli
   0x7c01:      xor    %eax,%eax
   0x7c03:      mov    %eax,%ds
   0x7c05:      mov    %eax,%es
   0x7c07:      mov    %eax,%ss
   0x7c09:      in     $0x64,%al
   0x7c0b:      test   $0x2,%al
   0x7c0d:      jne    0x7c09
   0x7c0f:      mov    $0xd1,%al
   0x7c11:      out    %al,$0x64

mmmm, tasty…