はじめに
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 は次の通りです。
$ 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です。
git clone https://github.com/mit-pdos/xv6-public.git
cd xv6-public
Make / Start
次のコマンドでmakeをします。その後、qemuで実行開始をします。
lsコマンドで filesystem の内容を表示します。
Ctl + a -> x で終了します。
$ 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接続待ち状態になります。
$ 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つめと同じです。
$ 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で次のコマンドを入力します。
(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しています。
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の理解に役立ちます。