關於RISC-V OS開發 1 OS啟動,開始起飛

2022-05-19     大方老師單片機

原標題:關於RISC-V OS開發 1 OS啟動,開始起飛

關於RISC-V OS 1 OS啟動開始起飛

///插播一條:我自己在今年年初錄製了一套還比較系統的入門單片機教程,想要的同學找我拿就行了免費的,私信我就可以~點我頭像黑色字體加我地球呺也能領取哦。最近比較閒,帶做畢設,帶學生參加省級或以上比///

QEMU模擬的是整SoC,我們需要驗證並調OS,外設是必不可少的QEMUbootloader映射到物理地址空間0x1000-0xf000的這ROM中,RAM映射0x8000000處。剩下主要是各種外設和支QEMU自身。

xv6的結構:

xv6是宏內核kernel下的文件.c/.h/.S)會被編譯成一個叫kernel的二進位文件,然後這個二進位文件會被運行kernle mode中。

第二個部分user。這基本上是運行user mode的程序。這也是為什麼一個目錄稱kernel,另一個目錄稱user的原因。

第三部分叫mkfs。它會使fs.img創建一個空的文件鏡像,我們會將這個鏡像存在磁碟上,這樣我們就可以直接使用一個空的文件系統。

makefilekernel下的文件編譯.o文件,之後會使ld連結成可執行文kernel,並使objdumpkernel.asm便於調試。

最後會調qemu來運行起xv6

xv6編譯過程

qemu有兩個依賴文件$K/kernelfs.img。其$K/kernel這樣生成:

$K/kernel: $(OBJS) $K/kernel.ld $U/initcode

$(LD) $(LDFLAGS) -T $K/kernel.ld -o $K/kernel $(OBJS)

$(OBJDUMP) -S $K/kernel > $K/kernel.asm

$(OBJDUMP) -t $K/kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $K/kernel.sym

$K/kernel就是整xv6內核的二進位文件。它的依賴文件就/kernel下的所有內容.c.S文件由隱含規則自動生.o文件xv6的編譯首先就是編/kernel下的所.c.S文件生成相.o文件,之後再根kernel.ld進行連結生kernel二進位文件,並將其反彙編成用於調試的彙編文件。此外對$U/initcode.S這個文件也要編譯、連結、反彙編,具體作用見後文。

再之後是user文件夾下的用戶程序進行編譯、連結、反彙編。然後使makefs把這些用戶程序的二進位文件寫fs.img這個磁碟鏡像上。最後就可以使qemu-system-riscv64命令啟動虛擬機了。這裡本質上是通C語言來模擬仿RISC-V處理器。

qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic

-drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0

我們來看傳QEMU的幾個參數:

-kernel:這裡傳遞的是內核文件kernel目錄下kernel文件),這是QEMU中運行的程序文件

-m:這裡傳遞的RISC-V虛擬機將會使用的內存數量

-smp:這裡傳遞的是虛擬機可以使用CPU核數

-drive:傳遞的是虛擬機使用的磁碟驅動,這裡傳入的fs.img文件

這樣XV6QEMU中啟動了QEMU就是C程序,它通C語言來完全模擬硬體的行為。

xv6啟動過程

RISC-V採用內存映I/O的方式,主板的設計人員決定了,在完成了虛擬到物理地址的翻譯之後,如果得到的物理地址大0x80000000會走DRAM晶片,如果得到的物理地址低0x80000000會走向不同I/O設備。這是由這個主板的設計人員決定的物理結構。如果你想要查看這裡的物理結構,你可以閱讀主板的手冊,手冊中會一一介紹物理地址對應關係QEMU也會默0x80000000是物理內存的起始處,它會從這裡開始執行指令。kernel/kernel.ldkernel/entry.S中的指令放0x80000000處,讓每CPU都從這裡開始執行kernel/entry.S的作用就是為每CPU接下來運C程序設置4KB大小的棧。之後會跳kernel/start.cstart()函數。它M模式下進行一些初始化,然後通mretS模式進入main.c中。main()CPU0會完成絕大多數初始化並且分init進程。接著等CPU1CPU2完成自己的一per-CPU初始化之後,進scheduler()中,開始選擇進程來執行。從此就進入OS死循當中,永遠不會返回了。

文章來源: https://twgreatdaily.com/zh/5ed3e41327433db3d3f410bf301afeb6.html