6.828: Operating System Engineering (14)

普通に考えて進捗悪い。まだ一コマ目なのに 14th だし。
ええと segmentation and paging とか出てますね。とりあえずどんどん読みます。

Exercise 7. Use QEMU and GDB to trace into the JOS kernel and find where the new virtual-to-physical mapping takes effect. Then examine the Global Descriptor Table (GDT) that the code uses to achieve this effect, and make sure you understand what's going on.

What is the first instruction after the new mapping is established that would fail to work properly if the old mapping were still in place? Comment out or otherwise intentionally break the segmentation setup code in kern/entry.S, trace into it, and see if you were right.

んーと、
とりあえず起動しっぱなしの gdb が kernel に jmp した所で止まっている。

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

Breakpoint 1, 0x00007c00 in ?? ()
(gdb) b *0x7d84
Breakpoint 2 at 0x7d84
(gdb) c
Continuing.
The target architecture is assumed to be i386
=> 0x7d84:      call   *%eax

Breakpoint 2, 0x00007d84 in ?? ()
(gdb) n
Cannot find bounds of current function
(gdb) si
=> 0x10000c:    movw   $0x1234,0x472
0x0010000c in ?? ()
(gdb) 

ちょっと進めてみます。

(gdb) si
=> 0x100015:    lgdtl  0x110018
0x00100015 in ?? ()
(gdb) si
=> 0x10001c:    mov    $0x10,%eax
0x0010001c in ?? ()
(gdb) x/x 0x110018
0x110018:       0x00000017
(gdb) 

0x110018 の中身が 0x00000017 とのことですが、ソース的には以下。

mygdtdesc:
	.word	0x17			# sizeof(mygdt) - 1
	.long	RELOC(mygdt)		# address mygdt

一応当たっているのかどうか。もう少し進めてみます。

(gdb) si
=> 0x10001c:    mov    $0x10,%eax
0x0010001c in ?? ()
(gdb) si
=> 0x100021:    mov    %eax,%ds
0x00100021 in ?? ()
(gdb) si
=> 0x100023:    add    %al,(%eax)
0x00100023 in ?? ()
(gdb) si
=> 0x100025:    add    %al,(%eax)
0x00100025 in ?? ()
(gdb) si
=> 0x100027:    add    %al,(%eax)
0x00100027 in ?? ()
(gdb) si
=> 0xf010002e <relocated>:      mov    $0x0,%ebp
relocated () at kern/entry.S:61
61              movl    $0x0,%ebp                       # nuke frame pointer
(gdb) 

上記の部分、なんとなくソースと違うんですよね。ソースの記述は以下。

	# Establish our own GDT in place of the boot loader's temporary GDT.
	lgdt	RELOC(mygdtdesc)		# load descriptor table

	# Immediately reload all segment registers (including CS!)
	# with segment selectors from the new GDT.
	movl	$DATA_SEL, %eax			# Data segment selector
	movw	%ax,%ds				# -> DS: Data Segment
	movw	%ax,%es				# -> ES: Extra Segment
	movw	%ax,%ss				# -> SS: Stack Segment
	ljmp	$CODE_SEL,$relocated		# reload CS by jumping
relocated:

	# Clear the frame pointer register (EBP)
	# so that once we get into debugging C code,
	# stack backtraces will be terminated properly.
	movl	$0x0,%ebp			# nuke frame pointer

ちなみに CODE_SEL の定義が以下です。

.set CODE_SEL,0x8		# index of code seg within mygdt

どうもこのあたり (ljmp のあたり) がキモな模様。それにしてもうにまがの Linux のブートプロセスをみる、な連載は凄いな。このあたりも網羅してるのか。

続き

Read through kern/printf.c, lib/printfmt.c, and kern/console.c, and make sure you understand their relationship. It will become clear in later labs why printfmt.c is located in the separate lib directory.

とのことなのですが、ここは明日の朝練でナニさせて頂きます。