Open Pin-Jiun opened 2 years ago
ROM有寫好的相關執行code
auipc
$t0=0x1000+0x0=0x1000=4096
addi
$a1=4096+32=4128
csrr
將csr register(mhartid)的值讀入$a0
$mhartid=hardware thread ID = 0x0
$a0=$mhartid=0x0
ld t0 24(t0)
將t0=0x1000加上24byte的offset後=0x1018
使用x 0x1018查找此記憶體,發現值為0x80000000
因為Little-Endian
上面gdb顯示的0x101a才會顯示0X8000
unimp
unimportant 的指令
全為0的指令
jr t0
跳轉至$t0儲存的值0x80000000,並將PC(0X1010)+4後儲存至$ra
由於編譯時kernel.ld檔有設定好0x80000000為_entry
,開始進入 entry.S
kernel.ld部分如下
OUTPUT_ARCH( "riscv" )
ENTRY( _entry )
SECTIONS
{
/*
* ensure that entry.S / _entry is at 0x80000000,
* where qemu's -kernel jumps.
*/
. = 0x80000000;
假設我們有一個 CPU讀取到的 32 位元(bits)整數資料為 0x12345678
實際讀取記憶體的方式如下
憑感覺最直觀的方式,會將記憶體依序讀取並fetch至CPU(如圖將其攤平),讀取到最後面(LSB)為較 大 的記憶體位置
將記憶體以遞增
(越來越大big)的方式排列,攤平後讀取
雖然最不直觀,但大多CPU存取的方式多為此
會將記憶體以相反的順序讀取並fetch至CPU,讀取到最後面(LSB)為較 小 的記憶體位置
將記憶體以遞減
(越來越小little)的方式排列,攤平後讀取
你所指定的address永遠會存在在LSB , 這樣是有很多好處的
the address of a given value in memory, taken as a 32, 16, or 8 bit width, is the same.
In other words, if you have in memory a two byte value:
0x00f0 16
0x00f1 0
taking that '16' as a 16-bit value (c 'short' on most 32-bit systems) or as an 8-bit value (generally c 'char') changes only the fetch instruction you use — not the address you fetch from. The addresses both are0x00f0
On a big-endian system, with the above layed out as:
0x00f0 0
0x00f1 16
taking that '16' as a 16-bit value (c 'short' on most 32-bit systems) , the address is 0x00f0
taking that '16' as a 8-bit value(generally c 'char') , the address is 0x00f1
NOT 0x00f0
先了解MEM的實際狀況 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
Address | store bit -- | -- 0X1016 | 0x00 0X1017 | 0x00 0X1018 | 0x00 0X1019 | 0x00 0X101a | 0x00 0X101b | 0x80
Starting xv6 with GDB
開啟兩個Treminal,第一個進入xv6資料夾輸入
此時會有提示說*** Now run 'gdb' in another window.,故以下指令開始在第二個Treminal中執行
修改自己 home 目錄下的 .gdbinit 文件,允许 gdb 在xv6-labs-2022这个目錄啟動的時候,加載 .gdbinit 文件
進入xv6資料夾,執行
gdb-multiarch
<<MIT課堂教授輸入的是riscv64-linux-gnu-gdb
???接著在gdb模式下執行
layout split
,以利我們trace code設立break point 1.
b _entry
2.b start
3.b main
4.b userinit
5.b scheduler
6.b usertrap
7.b syscall
8.b exec
使用ni指令細看整個OS的運作流程
搭配指令1.
i r
2.i r t0(register)
3.ni
orn
4.si
ors