Mercurial > hg > Members > tobaru > xv6_read
changeset 0:fae2e3cb5821 default tip
xv6_read
author | tobaru |
---|---|
date | Tue, 17 Apr 2018 19:07:15 +0900 |
parents | |
children | |
files | Xv6_read_0416.pdf Xv6読み会.html Xv6読み会.md xv6_BootSequence.graffle xv6_BootSequence.pdf xv6_BootSequence.svg |
diffstat | 6 files changed, 1080 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Xv6読み会.html Tue Apr 17 19:07:15 2018 +0900 @@ -0,0 +1,665 @@ +<!DOCTYPE html> +<html> + +<head> + +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> +<title>X.v6読み会</title> + + +<style type="text/css"> +body { + font-family: Helvetica, arial, sans-serif; + font-size: 14px; + line-height: 1.6; + padding-top: 10px; + padding-bottom: 10px; + background-color: white; + padding: 30px; } + +body > *:first-child { + margin-top: 0 !important; } +body > *:last-child { + margin-bottom: 0 !important; } + +a { + color: #4183C4; } +a.absent { + color: #cc0000; } +a.anchor { + display: block; + padding-left: 30px; + margin-left: -30px; + cursor: pointer; + position: absolute; + top: 0; + left: 0; + bottom: 0; } + +h1, h2, h3, h4, h5, h6 { + margin: 20px 0 10px; + padding: 0; + font-weight: bold; + -webkit-font-smoothing: antialiased; + cursor: text; + position: relative; } + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA09pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoMTMuMCAyMDEyMDMwNS5tLjQxNSAyMDEyLzAzLzA1OjIxOjAwOjAwKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM2NjlDQjI4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM2NjlDQjM4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzY2OUNCMDg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzY2OUNCMTg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsQhXeAAAABfSURBVHjaYvz//z8DJYCRUgMYQAbAMBQIAvEqkBQWXI6sHqwHiwG70TTBxGaiWwjCTGgOUgJiF1J8wMRAIUA34B4Q76HUBelAfJYSA0CuMIEaRP8wGIkGMA54bgQIMACAmkXJi0hKJQAAAABJRU5ErkJggg==) no-repeat 10px center; + text-decoration: none; } + +h1 tt, h1 code { + font-size: inherit; } + +h2 tt, h2 code { + font-size: inherit; } + +h3 tt, h3 code { + font-size: inherit; } + +h4 tt, h4 code { + font-size: inherit; } + +h5 tt, h5 code { + font-size: inherit; } + +h6 tt, h6 code { + font-size: inherit; } + +h1 { + font-size: 28px; + color: black; } + +h2 { + font-size: 24px; + border-bottom: 1px solid #cccccc; + color: black; } + +h3 { + font-size: 18px; } + +h4 { + font-size: 16px; } + +h5 { + font-size: 14px; } + +h6 { + color: #777777; + font-size: 14px; } + +p, blockquote, ul, ol, dl, li, table, pre { + margin: 15px 0; } + +hr { + background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0; + border: 0 none; + color: #cccccc; + height: 4px; + padding: 0; +} + +body > h2:first-child { + margin-top: 0; + padding-top: 0; } +body > h1:first-child { + margin-top: 0; + padding-top: 0; } + body > h1:first-child + h2 { + margin-top: 0; + padding-top: 0; } +body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { + margin-top: 0; + padding-top: 0; } + +a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { + margin-top: 0; + padding-top: 0; } + +h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { + margin-top: 0; } + +li p.first { + display: inline-block; } +li { + margin: 0; } +ul, ol { + padding-left: 30px; } + +ul :first-child, ol :first-child { + margin-top: 0; } + +dl { + padding: 0; } + dl dt { + font-size: 14px; + font-weight: bold; + font-style: italic; + padding: 0; + margin: 15px 0 5px; } + dl dt:first-child { + padding: 0; } + dl dt > :first-child { + margin-top: 0; } + dl dt > :last-child { + margin-bottom: 0; } + dl dd { + margin: 0 0 15px; + padding: 0 15px; } + dl dd > :first-child { + margin-top: 0; } + dl dd > :last-child { + margin-bottom: 0; } + +blockquote { + border-left: 4px solid #dddddd; + padding: 0 15px; + color: #777777; } + blockquote > :first-child { + margin-top: 0; } + blockquote > :last-child { + margin-bottom: 0; } + +table { + padding: 0;border-collapse: collapse; } + table tr { + border-top: 1px solid #cccccc; + background-color: white; + margin: 0; + padding: 0; } + table tr:nth-child(2n) { + background-color: #f8f8f8; } + table tr th { + font-weight: bold; + border: 1px solid #cccccc; + margin: 0; + padding: 6px 13px; } + table tr td { + border: 1px solid #cccccc; + margin: 0; + padding: 6px 13px; } + table tr th :first-child, table tr td :first-child { + margin-top: 0; } + table tr th :last-child, table tr td :last-child { + margin-bottom: 0; } + +img { + max-width: 100%; } + +span.frame { + display: block; + overflow: hidden; } + span.frame > span { + border: 1px solid #dddddd; + display: block; + float: left; + overflow: hidden; + margin: 13px 0 0; + padding: 7px; + width: auto; } + span.frame span img { + display: block; + float: left; } + span.frame span span { + clear: both; + color: #333333; + display: block; + padding: 5px 0 0; } +span.align-center { + display: block; + overflow: hidden; + clear: both; } + span.align-center > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: center; } + span.align-center span img { + margin: 0 auto; + text-align: center; } +span.align-right { + display: block; + overflow: hidden; + clear: both; } + span.align-right > span { + display: block; + overflow: hidden; + margin: 13px 0 0; + text-align: right; } + span.align-right span img { + margin: 0; + text-align: right; } +span.float-left { + display: block; + margin-right: 13px; + overflow: hidden; + float: left; } + span.float-left span { + margin: 13px 0 0; } +span.float-right { + display: block; + margin-left: 13px; + overflow: hidden; + float: right; } + span.float-right > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: right; } + +code, tt { + margin: 0 2px; + padding: 0 5px; + white-space: nowrap; + border: 1px solid #eaeaea; + background-color: #f8f8f8; + border-radius: 3px; } + +pre code { + margin: 0; + padding: 0; + white-space: pre; + border: none; + background: transparent; } + +.highlight pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + +pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + pre code, pre tt { + background-color: transparent; + border: none; } + +sup { + font-size: 0.83em; + vertical-align: super; + line-height: 0; +} + +kbd { + display: inline-block; + padding: 3px 5px; + font-size: 11px; + line-height: 10px; + color: #555; + vertical-align: middle; + background-color: #fcfcfc; + border: solid 1px #ccc; + border-bottom-color: #bbb; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #bbb +} + +* { + -webkit-print-color-adjust: exact; +} +@media screen and (min-width: 914px) { + body { + width: 854px; + margin:0 auto; + } +} +@media print { + table, pre { + page-break-inside: avoid; + } + pre { + word-wrap: break-word; + } +} +</style> + + +</head> + +<body> + +<h1 id="toc_0">X.v6読み会</h1> + +<h2 id="toc_1">Boot Sequence</h2> + +<p><strong>Boot</strong></p> + +<div><pre><code class="language-none"> Kernel load + Page Table (Boot用のPagetableの設定) + initialize (memory / IO / process / file ) + ini process + </code></pre></div> + +<p><img src="./xv6_BootSequence.svg" alt=""></p> + +<ul> +<li><p>Kernel load </p> + +<ul> +<li>x86ならEFIがある</li> +<li>ARMだとVersatile(firmware)</li> +</ul></li> +<li><p>paging を設定しなければ動かない</p></li> +<li><p>Boot用のpagetableの設定ができた後一連の初期化を行う</p> + +<ul> +<li>memory</li> +<li>I/O</li> +<li>process</li> +<li>file</li> +</ul></li> +<li><p>初期化が終わった後</p> + +<ul> +<li>init process(process番号1番)</li> +<li>init process は linux だと rc.d/~ の下にある</li> +</ul></li> +</ul> + +<h2 id="toc_2">ls 時の User と System</h2> + +<div><pre><code class="language-none">User Sys +fork +exec ls (lsを探す) + open ls + load ls + (loadの後にmemory空間の初期化を行う) + pase table reset + goto User Mode +opendir + system call (file IO) (VM) + (filesystemを読んでまたUserに値を返す) + + + </code></pre></div> + +<ul> +<li><p>10行目 <strong>VM</strong> の説明</p> + +<ul> +<li>lsは自分で仮装メモリにアクセスしていくので memory allocation をやる</li> +<li>malloc は User library だが memory の要求は System でやらなきゃいけない</li> +<li>break とい System call で memory を増やす</li> +<li>memory を増やすと OS は最初に ls のバイナリを生成</li> +<li>すると、break で取った領域が別にできる</li> +<li>breakで 取った memory が全部 リアル memory に割り当てられるわけではない</li> +<li>いくつかは仮想メモリに行く</li> +<li>memory にアクセスした時に仮装メモリだったらtrapしてmemoryを割り当てる</li> +<li>memoryが割り当てられなければ、他の実メモリを追い出して書き換える</li> +<li>VM関係の一連の処理がある</li> +</ul></li> +<li><p>fork</p> + +<ul> +<li>forkすると process structure ができる</li> +<li>process自体は active や waitの状態を持っている</li> +<li>複数のactiveがあると順に実行していく(scheduler)</li> +</ul></li> +<li><p>kernel の要素 </p> + +<ul> +<li>process manegement</li> +<li>scheduler</li> +<li>file IO</li> +<li>Virtual Memory</li> +</ul></li> +</ul> + +<p>この4つの Kernel の要素を読んでいく</p> + +<h2 id="toc_3">X.v6 の trace</h2> + +<p>arm 用の gdb で kernel.elf を開く</p> + +<p>dalmoreに入って</p> + +<div><pre><code class="language-none">cd /mnt/dalmore-home/one/src/xv6-rpi/src +/net/open/Linux/arm/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-gdb kernel.elf</code></pre></div> + +<p>qemuを立ち上げる +見たいのは Boot Sequence だから qemu-debug を使う</p> + +<div><pre><code class="language-none">make clean; make -f makefile-armclang qemu-debug</code></pre></div> + +<h3 id="toc_4">makefile-armclang の qemu-debug 部分</h3> + +<div><pre><code class="language-none">qemu-debug : kernel.elf + @clear + @echo "Press Ctrl-A and then X to terminate QEMU session\n" + export QEMU_AUDIO_DRV=none ; $(QEMU) -M versatilepb -m 128 -cpu ${QEMUCPU} -nographic -singlestep -d exec,cpu,guest_errors -D qemu.log -kernel kernel.elf -s -S</code></pre></div> + +<ul> +<li>-M versatilepb + +<ul> +<li>仮想メモリにこの firmwere を使うという指示</li> +<li>versarilepb は Raspi(ARM) のfirmwereの一種 </li> +</ul></li> +<li> -m 128 + +<ul> +<li>memory の量</li> +</ul></li> +<li>-cpu ${QEMUCPU} + +<ul> +<li>cpu の種類</li> +<li>アーキテクチャによって命令違う</li> +<li>armのxv6を作る時のcompile時にcpuに教えるcpuの種類と合わせる必要がある</li> +<li>名前がqemu側とcompile側のcpuの名前が違うので試行錯誤して合わせる</li> +</ul></li> +<li>-s -S + +<ul> +<li> Boot時に debugger が接続するまで止めるようにする </li> +</ul></li> +</ul> + +<h3 id="toc_5">gdb</h3> + +<div><pre><code class="language-none">(gdb)b _start + +# remote 接続 +(gdb)target remote :1234 + +# bt: stackを参照して、stack上のfanction callの履歴を調べる +(gdb)bt + +(gdb)info registarts (初期のレジスタ) +r0 ~ r12 (ARMのレジスタは0~12) +sp (stack pointer) +lr (link regester) +pc (program counter) +cpsr (cpu statusのレジスタ) + +(gdb)disass +# disassemblerの略 + +(gdb)x/20x $pc+48+4 +0x100030 +# entry.Sのr1,=edata_entryやend_entryが$pc+48に変わってる +# pcは次の命令を指している10030->10038だから48からさらに+4 + +(gdb)p (void*) edata_entry +$1 = (void *0) 0x10588 <edata_entry> +# 10588がレジスタのr1に入る + +(gdb)stepi +(gdb)info registers +r1 0x10588 66952 + +(gdb)stepi +(gdb)info registers +r1 0x10588 66952 +r2 0x19000 102400 + +(gdb)define ni +>x/1i $pc +>x/1i $pc +>end +# こうするとentry.Sを1命令ずつ実行できる + + +(gdb)si +0x0001000c in _start () +=> 0x1000c <_start+12>: cmp r1,r2 + +(gdb)si +0x0001000c in _start () +=> 0x1014c <_start+16>: cmp r1,{r3} + +(gdb)disass +=> 0x00010014 <*20>: blt + 0x00010018 <*24>: msr +# blt でループしてることがわかる + +(gdb)tb *0x00010018 +(gdb)c +# bltのループを抜ける + +(gdb)disass +(gbd)info registers +r1 0x19000 102400 +r2 0x19000 102400 +# r2の値になるまでr1をincrementすることでループを抜けてる事がわかる +# 19000までmemoryがある + +# CPUのコントロール + + +(gdb)si +(gdb)info registers +cpsr 0x600001d3 + +# entry.Sの MSRの行を実行 +(gdb)si +(gdb)info registers +cpsr 0xd3 +# CPUのコントロールレジスタを指定している +# supervisorじゃないとアクセスできない + +# entry.Sの LDR の行を実行 +(gdb) si +(gdb) info registers +sp 0x12000 +# 0x0 -> 0x12000 +# stack ponterが設定されたのでサブルーチンコールが使えるようになる +# サブルーチンコール 戻り先をstackに覚えておいてそこに飛ぶ +# lr(link register)に覚えさせる事で1回だけアクセスせずに飛ぶ事ができる +# BL breach & link + + +(gdb)si +(gdb)info registers +lr 0x10024 + +(gdb)disass _start + 0x00010024 <+36>: b + +# startまできたのでここ以降はstart.c +(gdb)l +# cなので next が使える + +(gdb)next +(gdb)next +(gdb)s +set_bootpgtbl(... lent=1048576 ...) +(gdb)p (void*) len +$2 = (void *) 0x100000 +# 1048576 は16進数で100000 + +(gdb)disass +</code></pre></div> + +<ul> +<li><p>memory に直接 load できる値は 長い値だとmemory一旦置かないといけない</p></li> +<li><p>一番最初に呼び出すのは C で書かれたファイルじゃなくてアセンブラ</p> + +<ul> +<li>entry.S で行なっている</li> +</ul></li> +</ul> + +<h3 id="toc_6">entry.S</h3> + +<div><pre><code class="language-none">_start: + LDR r1, =edata_entry + LDR r2, =end_entry + MOV r3, #0x00 + +# BLT までをループ +1: + CMP r1, r2 + STMLTIA r1!, {r3} # {}はレジスタのリスト r1にセーブする + # !は セーブした数だけr1を進める(++とかと一緒) + # Memclear とかと一緒 + + BLT 1b + + + # initialize stack pointers for svc modes + # CPUのコントロールレジスタを指定 + # cpsr 0xd3 + MSR CPSR_cxsf, #(SVC_MODE|NO_INT) + LDR sp, =svc_stktop + + BL start + B .</code></pre></div> + +<ul> +<li>B . まで行くとそこを永遠とループする + +<ul> +<li>ARM fault持ってるので Bではなくfaultにすべき </li> +</ul></li> +</ul> + +<h3 id="toc_7">start.c</h3> + +<p>l.166~</p> + +<div><pre><code class="language-none">void start (void) +{ + uint32 vectbl; + _puts("starting xv6 for ARM...\n"); + + // double map the low memory, required to enable paging + // we do not map all the physical memory + set_bootpgtbl(0, 0, INIT_KERNMAP, 0); + set_bootpgtbl(KERNBASE, 0, INIT_KERNMAP, 0);</code></pre></div> + +<p>l.69~</p> + +<div><pre><code class="language-none"> for (idx = 0; idx < len; idx++) { + pde = (phy << PDE_SHIFT); + + if (!dev_mem) { + // normal memory, make it kernel-only, cachable, bufferable + pde |= (AP_KO << 10) | PE_CACHE | PE_BUF | KPDE_TYPE; + // |(or) を使って足して行く + } else { + // device memory, make it non-cachable and non-bufferable + pde |= (AP_KO << 10) | KPDE_TYPE; + }</code></pre></div> + +<ul> +<li>ARMv6 page table entry +https://developer.arm.com/docs/ddi0211/h/memory-management-unit/hardware-page-table-translation/armv6-page-table-translation-subpage-ap-bits-disabled</li> +</ul> + + + + +</body> + +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Xv6読み会.md Tue Apr 17 19:07:15 2018 +0900 @@ -0,0 +1,302 @@ +# X.v6読み会 + +## Boot Sequence + + **Boot** + + ``` + Kernel load + Page Table (Boot用のPagetableの設定) + initialize (memory / IO / process / file ) + ini process + + ``` + ![](./xv6_BootSequence.svg) + + +- Kernel load + - x86ならEFIがある + - ARMだとVersatile(firmware) + + +- paging を設定しなければ動かない +- Boot用のpagetableの設定ができた後一連の初期化を行う + - memory + - I/O + - process + - file +- 初期化が終わった後 + - init process(process番号1番) + - init process は linux だと rc.d/~ の下にある + +## ls 時の User と System +``` +User Sys +fork +exec ls (lsを探す) + open ls + load ls + (loadの後にmemory空間の初期化を行う) + pase table reset + goto User Mode +opendir + system call (file IO) (VM) + (filesystemを読んでまたUserに値を返す) + + + +``` + +- 10行目 **VM** の説明 + - lsは自分で仮装メモリにアクセスしていくので memory allocation をやる + - malloc は User library だが memory の要求は System でやらなきゃいけない + - break とい System call で memory を増やす + - memory を増やすと OS は最初に ls のバイナリを生成 + - すると、break で取った領域が別にできる + - breakで 取った memory が全部 リアル memory に割り当てられるわけではない + - いくつかは仮想メモリに行く + - memory にアクセスした時に仮装メモリだったらtrapしてmemoryを割り当てる + - memoryが割り当てられなければ、他の実メモリを追い出して書き換える + - VM関係の一連の処理がある + +- fork + - forkすると process structure ができる + - process自体は active や waitの状態を持っている + - 複数のactiveがあると順に実行していく(scheduler) + + +- kernel の要素 + - process manegement + - scheduler + - file IO + - Virtual Memory + +この4つの Kernel の要素を読んでいく + +## X.v6 の trace +arm 用の gdb で kernel.elf を開く + +dalmoreに入って + +``` +cd /mnt/dalmore-home/one/src/xv6-rpi/src +/net/open/Linux/arm/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-gdb kernel.elf +``` + +qemuを立ち上げる +見たいのは Boot Sequence だから qemu-debug を使う + +``` +make clean; make -f makefile-armclang qemu-debug +``` + +### makefile-armclang の qemu-debug 部分 + +``` +qemu-debug : kernel.elf + @clear + @echo "Press Ctrl-A and then X to terminate QEMU session\n" + export QEMU_AUDIO_DRV=none ; $(QEMU) -M versatilepb -m 128 -cpu ${QEMUCPU} -nographic -singlestep -d exec,cpu,guest_errors -D qemu.log -kernel kernel.elf -s -S +``` +- -M versatilepb + - 仮想メモリにこの firmwere を使うという指示 + - versarilepb は Raspi(ARM) のfirmwereの一種 +- -m 128 + - memory の量 +- -cpu ${QEMUCPU} + - cpu の種類 + - アーキテクチャによって命令違う + - armのxv6を作る時のcompile時にcpuに教えるcpuの種類と合わせる必要がある + - 名前がqemu側とcompile側のcpuの名前が違うので試行錯誤して合わせる +- -s -S + - Boot時に debugger が接続するまで止めるようにする + +### gdb + +``` +(gdb)b _start + +# remote 接続 +(gdb)target remote :1234 + +# bt: stackを参照して、stack上のfanction callの履歴を調べる +(gdb)bt + +(gdb)info registarts (初期のレジスタ) +r0 ~ r12 (ARMのレジスタは0~12) +sp (stack pointer) +lr (link regester) +pc (program counter) +cpsr (cpu statusのレジスタ) + +(gdb)disass +# disassemblerの略 + +(gdb)x/20x $pc+48+4 +0x100030 +# entry.Sのr1,=edata_entryやend_entryが$pc+48に変わってる +# pcは次の命令を指している10030->10038だから48からさらに+4 + +(gdb)p (void*) edata_entry +$1 = (void *0) 0x10588 <edata_entry> +# 10588がレジスタのr1に入る + +(gdb)stepi +(gdb)info registers +r1 0x10588 66952 + +(gdb)stepi +(gdb)info registers +r1 0x10588 66952 +r2 0x19000 102400 + +(gdb)define ni +>x/1i $pc +>x/1i $pc +>end +# こうするとentry.Sを1命令ずつ実行できる + + +(gdb)si +0x0001000c in _start () +=> 0x1000c <_start+12>: cmp r1,r2 + +(gdb)si +0x0001000c in _start () +=> 0x1014c <_start+16>: cmp r1,{r3} + +(gdb)disass +=> 0x00010014 <*20>: blt + 0x00010018 <*24>: msr +# blt でループしてることがわかる + +(gdb)tb *0x00010018 +(gdb)c +# bltのループを抜ける + +(gdb)disass +(gbd)info registers +r1 0x19000 102400 +r2 0x19000 102400 +# r2の値になるまでr1をincrementすることでループを抜けてる事がわかる +# 19000までmemoryがある + +# CPUのコントロール + + +(gdb)si +(gdb)info registers +cpsr 0x600001d3 + +# entry.Sの MSRの行を実行 +(gdb)si +(gdb)info registers +cpsr 0xd3 +# CPUのコントロールレジスタを指定している +# supervisorじゃないとアクセスできない + +# entry.Sの LDR の行を実行 +(gdb) si +(gdb) info registers +sp 0x12000 +# 0x0 -> 0x12000 +# stack ponterが設定されたのでサブルーチンコールが使えるようになる +# サブルーチンコール 戻り先をstackに覚えておいてそこに飛ぶ +# lr(link register)に覚えさせる事で1回だけアクセスせずに飛ぶ事ができる +# BL breach & link + + +(gdb)si +(gdb)info registers +lr 0x10024 + +(gdb)disass _start + 0x00010024 <+36>: b + +# startまできたのでここ以降はstart.c +(gdb)l +# cなので next が使える + +(gdb)next +(gdb)next +(gdb)s +set_bootpgtbl(... lent=1048576 ...) +(gdb)p (void*) len +$2 = (void *) 0x100000 +# 1048576 は16進数で100000 + +(gdb)disass + +``` + + +- memory に直接 load できる値は 長い値だとmemory一旦置かないといけない + +- 一番最初に呼び出すのは C で書かれたファイルじゃなくてアセンブラ + - entry.S で行なっている + +### entry.S + +``` +_start: + LDR r1, =edata_entry + LDR r2, =end_entry + MOV r3, #0x00 + +# BLT までをループ +1: + CMP r1, r2 + STMLTIA r1!, {r3} # {}はレジスタのリスト r1にセーブする + # !は セーブした数だけr1を進める(++とかと一緒) + # Memclear とかと一緒 + + BLT 1b + + + # initialize stack pointers for svc modes + # CPUのコントロールレジスタを指定 + # cpsr 0xd3 + MSR CPSR_cxsf, #(SVC_MODE|NO_INT) + LDR sp, =svc_stktop + + BL start + B . +``` + +- B . まで行くとそこを永遠とループする + - ARM fault持ってるので Bではなくfaultにすべき + + +### start.c +l.166~ + +``` +void start (void) +{ + uint32 vectbl; + _puts("starting xv6 for ARM...\n"); + + // double map the low memory, required to enable paging + // we do not map all the physical memory + set_bootpgtbl(0, 0, INIT_KERNMAP, 0); + set_bootpgtbl(KERNBASE, 0, INIT_KERNMAP, 0); +``` + +l.69~ + +``` + for (idx = 0; idx < len; idx++) { + pde = (phy << PDE_SHIFT); + + if (!dev_mem) { + // normal memory, make it kernel-only, cachable, bufferable + pde |= (AP_KO << 10) | PE_CACHE | PE_BUF | KPDE_TYPE; + // |(or) を使って足して行く + } else { + // device memory, make it non-cachable and non-bufferable + pde |= (AP_KO << 10) | KPDE_TYPE; + } +``` +- ARMv6 page table entry +https://developer.arm.com/docs/ddi0211/h/memory-management-unit/hardware-page-table-translation/armv6-page-table-translation-subpage-ap-bits-disabled +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xv6_BootSequence.svg Tue Apr 17 19:07:15 2018 +0900 @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="675 204 865 258" width="865" height="258"> + <defs> + <font-face font-family="Helvetica Neue" font-size="16" panose-1="2 0 5 3 0 0 0 2 0 4" units-per-em="1000" underline-position="-100" underline-thickness="50" slope="0" x-height="517" cap-height="714" ascent="951.9958" descent="-212.99744" font-weight="400"> + <font-face-src> + <font-face-name name="HelveticaNeue"/> + </font-face-src> + </font-face> + <font-face font-family="Hiragino Sans" font-size="16" panose-1="2 11 3 0 0 0 0 0 0 0" units-per-em="1000" underline-position="-75" underline-thickness="50" slope="0" x-height="545" cap-height="766" ascent="880.0018" descent="-120.00024" font-weight="300"> + <font-face-src> + <font-face-name name="HiraginoSans-W3"/> + </font-face-src> + </font-face> + <marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black"> + <g> + <path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/> + </g> + </marker> + </defs> + <metadata> Produced by OmniGraffle 7.7.1 + <dc:date>2018-04-17 01:17:12 +0000</dc:date> + </metadata> + <g id="Canvas_1" fill-opacity="1" stroke-dasharray="none" stroke="none" stroke-opacity="1" fill="none"> + <title>Canvas 1</title> + <rect fill="white" x="675" y="204" width="865" height="258"/> + <g id="Canvas_1: Layer 1"> + <title>Layer 1</title> + <g id="Graphic_17"> + <rect x="721" y="205.42697" width="127" height="75.62921" fill="white"/> + <rect x="721" y="205.42697" width="127" height="75.62921" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + <text transform="translate(726 234.01757)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="41.764" y="15">CPU</tspan> + </text> + </g> + <g id="Graphic_16"> + <rect x="913.0562" y="205.42697" width="127" height="232.5955" fill="white"/> + <rect x="913.0562" y="205.42697" width="127" height="232.5955" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + </g> + <g id="Graphic_15"> + <rect x="721" y="310" width="127" height="75.62921" fill="white"/> + <rect x="721" y="310" width="127" height="75.62921" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + <text transform="translate(726 338.5906)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="34.052" y="15">paging</tspan> + </text> + </g> + <g id="Graphic_14"> + <rect x="1092.0625" y="205.42697" width="127" height="75.62921" fill="white"/> + <rect x="1092.0625" y="205.42697" width="127" height="75.62921" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + <text transform="translate(1097.0625 234.01757)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="45.46" y="15">dev</tspan> + </text> + </g> + <g id="Graphic_13"> + <rect x="1347" y="310" width="127" height="75.62921" fill="white"/> + <rect x="1347" y="310" width="127" height="75.62921" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + <text transform="translate(1352 338.5906)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="9.604" y="15">MacBook Pro</tspan> + </text> + </g> + <g id="Graphic_12"> + <rect x="938.7416" y="283.9101" width="75.62921" height="75.62921" fill="white"/> + <rect x="938.7416" y="283.9101" width="75.62921" height="75.62921" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + <text transform="translate(943.7416 312.50072)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="9.854607" y="15">Kernel</tspan> + </text> + </g> + <g id="Graphic_11"> + <rect x="934.4607" y="229.6854" width="85.61798" height="34.24719" fill="white"/> + <rect x="934.4607" y="229.6854" width="85.61798" height="34.24719" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="0"/> + <text transform="translate(939.4607 237.585)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="8.464989" y="15">Memory</tspan> + </text> + </g> + <g id="Graphic_10"> + <text transform="translate(1150.5625 289.1861)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x="21.612" y="15">UART</tspan> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x=".276" y="33.448">( VM</tspan> + <tspan font-family="Hiragino Sans" font-size="16" font-weight="300" fill="black" y="33.448">で動く</tspan> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" y="33.448">)</tspan> + </text> + </g> + <g id="Graphic_9"> + <text transform="translate(1312 277.5569)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x=".048" y="15">USB serial Interface</tspan> + </text> + </g> + <g id="Graphic_8"> + <text transform="translate(680 407.5)" fill="black"> + <tspan font-family="Helvetica Neue" font-size="16" font-weight="400" fill="black" x=".292" y="15">paging</tspan> + <tspan font-family="Hiragino Sans" font-size="16" font-weight="300" fill="black" y="15">のメカニズムを使って</tspan> + <tspan font-family="Hiragino Sans" font-size="16" font-weight="300" fill="black" x="24.98" y="39.000016">メモリにアクセスする</tspan> + </text> + </g> + <g id="Line_7"> + <line x1="784.5" y1="281.05618" x2="784.5" y2="300.1" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + </g> + <g id="Line_6"> + <line x1="848" y1="339.18844" x2="903.2463" y2="331.6835" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + </g> + <g id="Line_5"> + <line x1="1219.0625" y1="243.72663" x2="1347" y2="244.7039" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + </g> + <g id="Graphic_4"> + <path d="M 1347 275.3483 L 1377.5 275.3483 C 1392.75 275.3483 1408 268.21348 1408 246.809 C 1408 225.4045 1392.75 218.26966 1377.5 218.26966 L 1347 218.26966 Z" fill="white"/> + <path d="M 1347 275.3483 L 1377.5 275.3483 C 1392.75 275.3483 1408 268.21348 1408 246.809 C 1408 225.4045 1392.75 218.26966 1377.5 218.26966 L 1347 218.26966 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + </g> + <g id="Line_3"> + <path d="M 1408 246.73742 C 1447.2415 247.48006 1512.5942 251.80183 1531.3377 271.7809 C 1558.6766 300.92206 1508.234 328.1297 1474 349.67043" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + </g> + </g> + </g> +</svg>