QEMUでxv6をうごかす

# はじめに
QEMUでxv6をうごかす方法を説明します。xv6とは。[1]から抜粋します。

>
xv6 is a modern reimplementation of Sixth Edition Unix in ANSI C for multiprocessor x86 and RISC-V systems. It was created for pedagogical purposes in MIT's Operating System Engineering course.
>

xv6は教育で使用されるOSです。code sizeが小さく、OSの理解に役立ちます。

# Version
動作確認した Host OS / 各種 Tool の Version は次の通りです。

```bash:console
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
$ uname -r
5.4.0-58-generic
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
(...)

$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
(...)
```

# Get source code
次のコマンドでsource codeを取得します([2])。CPUはx86向けのsource codeです。

```bash:console
git clone https://github.com/mit-pdos/xv6-public.git
cd xv6-public
```

# Make / Start
次のコマンドでmakeをします。その後、qemuで実行開始をします。
lsコマンドで filesystem の内容を表示します。
Ctl + a -> x で終了します。

```bash:console
$ make qemu-nox
qemu-system-i386 -nographic -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp 2 -m 512 
xv6...
cpu1: starting 1
cpu0: starting 0
sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
init: starting sh
$ ls
.              1 1 512
..             1 1 512
README         2 2 2286
cat            2 3 13612
echo           2 4 12624
forktest       2 5 8052
grep           2 6 15488
init           2 7 13208
kill           2 8 12676
ln             2 9 12572
ls             2 10 14760
mkdir          2 11 12756
rm             2 12 12732
sh             2 13 23220
stressfs       2 14 13404
usertests      2 15 56336
wc             2 16 14152
zombie         2 17 12396
console        3 18 0
```

# Gdb
gdbを使って動きを確認できます。
terminalを2つ使用します。

1つめのterminalで次のコマンドを実行します。gdb接続待ち状態になります。

```bash:terminal_1
$ make qemu-nox-gdb
*** Now run 'gdb'.
qemu-system-i386 -nographic -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp 2 -m 512  -S -gdb tcp::26000
```

2つめのterminalで次のコマンドを実行します。working directoryは1つめと同じです。

```bash:terminal_2
$ gdb -x .gdbinit
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
(...)
[f000:fff0]    0xffff0:	ljmp   $0x3630,$0xf000e05b
0x0000fff0 in ?? ()
+ symbol-file kernel
warning: A handler for the OS ABI "GNU/Linux" is not built into this configuration
of GDB.  Attempting to continue with the default i8086 settings.

(gdb) 
```

2つめのterminalで次のコマンドを入力します。

```bash:terminal_2
(gdb) b *0x7c00
Breakpoint 1 at 0x7c00
(gdb) c
Continuing.
[   0:7c00] => 0x7c00:	cli    

Thread 1 hit Breakpoint 1, 0x00007c00 in ?? ()
(gdb) disas 0x7c00, +10
Dump of assembler code from 0x7c00 to 0x7c0a:
=> 0x00007c00:	cli    
   0x00007c01:	xor    %eax,%eax
   0x00007c03:	mov    %eax,%ds
   0x00007c05:	mov    %eax,%es
   0x00007c07:	mov    %eax,%ss
   0x00007c09:	in     $0x64,%al
End of assembler dump.
(gdb) 
```

次の位置でbreakしています。

```:bootasm.S
 10 .code16                       # Assemble for 16-bit mode
 11 .globl start
 12 start:
 13   cli                         # BIOS enabled interrupts; disable
 14 
 15   # Zero data segment registers DS, ES, and SS.
 16   xorw    %ax,%ax             # Set %ax to zero
 17   movw    %ax,%ds             # -> Data Segment
 18   movw    %ax,%es             # -> Extra Segment
 19   movw    %ax,%ss             # -> Stack Segment
```

このようにgdbを使って動かしながら処理を確認できます。

xv6の詳細については[3]-[4]を参照ください。
[5]はOSの理解に役立ちます。

# References
- [1] https://en.wikipedia.org/wiki/Xv6
- [2] https://github.com/mit-pdos/xv6-public
- [3] https://pdos.csail.mit.edu/6.828/2018/reference.html
- [4] https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev10.pdf
- [5] http://pages.cs.wisc.edu/~remzi/OSTEP/