XV6 啟動過程

RISC-V 通電以后,會運(yùn)行保存在ROM中的引導(dǎo)程序(BootLoader),引導(dǎo)程序?qū)v6內(nèi)核加載到物理地址為0x80000000。
然后在機(jī)器模式下,CPU從kernel/entry.S開始運(yùn)行xv6 _entry。

    # qemu -kernel loads the kernel at 0x80000000
        # and causes each CPU to jump there.
        # kernel.ld causes the following code to
        # be placed at 0x80000000.
.section .text
_entry:
    # set up a stack for C.
        # stack0 is declared in start.c,
        # with a 4096-byte stack per CPU.
        # sp = stack0 + (hartid * 4096)
        la sp, stack0
        li a0, 1024*4
    csrr a1, mhartid
        addi a1, a1, 1
        mul a0, a0, a1
        add sp, sp, a0
    # jump to start() in start.c
        call start
spin:
        j spin

_entry函數(shù),主要用于開辟??臻g,以便后續(xù)C代碼運(yùn)行
每個CPU都有自己的棧,把棧地址存入sp寄存器,接著_entry跳轉(zhuǎn)到start執(zhí)行C代碼。

start.c文件中運(yùn)行start()函數(shù)
RISCV提供了mret指令,這個指令一般是從前一個Supervisor模式轉(zhuǎn)換到Machine模式的
調(diào)用返回。但是start并沒有從這樣的調(diào)用返回。
所以,start函數(shù)假裝自己從這樣的調(diào)用返回。
在mstatus寄存器設(shè)置運(yùn)行模式為Supervisor,以便進(jìn)入內(nèi)核
mepc寄存器設(shè)置為main函數(shù)地址,將返回地址設(shè)為main
satp寄存器寫入0,禁用虛擬地址轉(zhuǎn)換。
最后通過mret指令進(jìn)入main函數(shù)

void
start()
{
  // set M Previous Privilege mode to Supervisor, for mret.
  unsigned long x = r_mstatus();
  x &= ~MSTATUS_MPP_MASK;
  x |= MSTATUS_MPP_S;
  w_mstatus(x);

  // set M Exception Program Counter to main, for mret.
  // requires gcc -mcmodel=medany
  w_mepc((uint64)main);

  // disable paging for now.
  w_satp(0);

  // delegate all interrupts and exceptions to supervisor mode.
  w_medeleg(0xffff);
  w_mideleg(0xffff);
  w_sie(r_sie() | SIE_SEIE | SIE_STIE | SIE_SSIE);

  // ask for clock interrupts.
  timerinit();

  // keep each CPU's hartid in its tp register, for cpuid().
  int id = r_mhartid();
  w_tp(id);

  // switch to supervisor mode and jump to main().
  asm volatile("mret");
}

在main函數(shù)中,初始化設(shè)備和子系統(tǒng)后,通過調(diào)用userinit創(chuàng)建第一個進(jìn)程
第一個進(jìn)程執(zhí)行initcode.S程序

# Initial process that execs /init.
# This code runs in user space.

#include "syscall.h"

# exec(init, argv)
.globl start
start:
        la a0, init
        la a1, argv
        li a7, SYS_exec
        ecall

# for(;;) exit();
exit:
        li a7, SYS_exit
        ecall
        jal exit

# char init[] = "/init\0";
init:
  .string "/init\0"

# char *argv[] = { init, 0 };
.p2align 2
argv:
  .long init
  .long 0

通過exec系統(tǒng)調(diào)用,重新進(jìn)入內(nèi)核。exec系統(tǒng)調(diào)用用一個新程序init替換當(dāng)前進(jìn)程的內(nèi)存和寄存器。
一旦內(nèi)核完成了exec,它就返回到init的用戶空間。init程序?qū)?chuàng)建一個新的控制臺設(shè)備文件,然后以文件描述符0、1和2打開它。然后在控制臺上啟動一個shell。這樣系統(tǒng)就啟動了。

使用vscode調(diào)試xv6
在程序的入口_entry設(shè)置一個斷點


調(diào)試06.PNG

xv6從entry.S開始啟動,運(yùn)行在Machine模式下,運(yùn)行到start.c后切換到supervisor模式,然后運(yùn)行main.c
在main函數(shù)中,做了設(shè)備和子系統(tǒng)的初始化。


調(diào)試07.PNG

調(diào)試08.PNG

然后通過userinit運(yùn)行第一個進(jìn)程,調(diào)用exec運(yùn)行第一個程序

# exec(init, argv)
.globl start
start:
        la a0, init
        la a1, argv
        li a7, SYS_exec
        ecall

將init內(nèi)容的指針加載到a0,argv參數(shù)的地址加載到a1,exec系統(tǒng)調(diào)用對應(yīng)的數(shù)字加載到a7,最后調(diào)用ecall
在syscall設(shè)置斷點


截圖09.PNG

num = p->trapframe->a7,會讀取系統(tǒng)調(diào)用號


截圖10.PNG

sys_exec系統(tǒng)調(diào)用,會從用戶空間讀取參數(shù),會讀取path,也就是要執(zhí)行程序的文件名。


截圖11.PNG

init會為用戶空間設(shè)置好console,調(diào)用fork,并在fork出的子進(jìn)程中執(zhí)行shell。這樣OS就運(yùn)行起來了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 操作系統(tǒng)的隔離性 如果沒有操作系統(tǒng),應(yīng)用程序會直接與硬件交互。比如,應(yīng)用程序可以直接看到CPU的多個核,看到磁盤,...
    西部小籠包閱讀 560評論 0 0
  • 啟動理論部分 本節(jié)來說說捋清啟動需要知道的一些東西,因知識點的確很多,涉及了各個方面,我就不像其他章節(jié)一樣各個部分...
    Rand_cs1閱讀 273評論 0 1
  • 環(huán)境 deepin 20 64 位系統(tǒng) 說在前面 本次Lab我也覺得比較難,到最后也有部分測試點沒有通過,在實現(xiàn)p...
    扶桑與克里斯閱讀 1,054評論 0 0
  • 1. 背景 原本計劃自己學(xué)習(xí)寫個操作系統(tǒng)的,但是工欲善其事必先利其器,先學(xué)習(xí)下別人是怎么做出來的,自己再動手,自然...
    pingpong_龘閱讀 17,680評論 5 16
  • xv6閱讀匯報-2 xv6中的進(jìn)程線程相關(guān)的模塊有types.h param.h memlayout.h defs...
    早飯棒閱讀 4,932評論 0 2

友情鏈接更多精彩內(nèi)容