基於ucore的作業系統實驗lab1

2021-09-29 04:46:46 字數 3352 閱讀 1942

練習1.1

1、先編譯鏈結生成kernel檔案

2、再編譯鏈結生成bootblock檔案

3、生成ucore.imgsign.c生成bootblock

1.2 檢視sign.c可以發現關鍵在於bootblock.out小於510bytes,且 buf[510] = 0x55; buf[511] = 0xaa;

練習2.1 從 cpu 加電後執行的第一條指令開始,單步跟蹤 bios 的執行。

單步跟蹤,方法如下:

1 修改 lab1/tools/gdbinit,內容為:

set architecture

i8086

target remote

:1234

2 在 lab1目錄下,執行

make debug
3 在看到gdb的除錯介面(gdb)後,在gdb除錯介面下執行如下命令

si
即可單步跟蹤bios了。

4 在gdb介面下,可通過如下命令來看bios的**

x /2i $pc 

//顯示當前eip處的彙編指令

練習2.2 在初始化位置0x7c00設定實位址斷點,測試斷點正常。

在gdb中輸入一下命令

b *0x7c00 

//在0x7c00處設定斷點。此位址是bootloader入口點位址,可看boot/bootasm.s的start位址處

c

//continue簡稱,表示繼續執行

x /2i $pc

//顯示當前eip處的彙編指令

得到

breakpoint 2,

0x00007c00 in ?? ()

=> 0x7c00:      cli   

0x7c01: cld

練習2.3 從0x7c00開始跟蹤**執行,將單步跟蹤反彙編得到的**與bootasm.s和 bootblock.asm進行比較。

將2.2中的步驟重複實現與兩個檔案進行對比發現是一致的

練習2.4 自己找乙個bootloader或核心中的**位置,設定斷點並進行測試。

自己按以上步驟測試一下就行了

練習3.1 分析bootloader進入保護模式的過程。

它先將各個暫存器置0

movw $prot_mode_dseg, %ax

movw %ax, %ds

movw %ax, %es

movw %ax, %fs

movw %ax, %gs

movw %ax, %ss

movl $0x0, %ebp

movl $start, %esp

初始化gdt表:乙個簡單的gdt表和其描述符已經靜態儲存在引導區中,載入即可

lgdt gdtdesc
進入保護模式:通過將cr0暫存器pe位置1便開啟了保護模式

movl %cr0, %eax

orl $cr0_pe_on, %eax

movl %eax, %cr0

通過長跳轉更新cs的基位址

ljmp

$prot_mode_cseg, $protcseg

.code32

protcseg:

設定段暫存器,並建立堆疊

movw $prot_mode_dseg, %ax

movw %ax, %ds

movw %ax, %es

movw %ax, %fs

movw %ax, %gs

movw %ax, %ss

movl $0x0, %ebp

movl $start, %esp

轉到保護模式完成,進入boot主方法

call bootmain
練習4 分析bootloader載入elf格式的os的過程。

首先看readsect函式,

readsect從裝置的第secno扇區讀取資料到dst位置

static

void

readsect(void

*dst, uint32_t secno)

readseg簡單包裝了readsect,可以從裝置讀取任意長度的內容。

static

void

readseg(uintptr_t

va, uint32_t count, uint32_t offset)

}

在bootmain函式中,

void

bootmain(void)

struct proghdr *ph, *eph;

// elf頭部有描述elf檔案應載入到記憶體什麼位置的描述表,

// 先將描述表的頭位址存在ph

ph = (struct proghdr *)((uintptr_t)elfhdr +

elfhdr->e_phoff);

eph = ph + elfhdr->e_phnum;

// 按照描述表將elf檔案中資料載入記憶體

for (; ph < eph; ph ++)

// elf檔案0x1000位置後面的0xd1ec位元被載入記憶體0x00100000

// elf檔案0xf000位置後面的0x1d20位元被載入記憶體0x0010e000

// 根據elf頭部儲存的入口資訊,找到核心的入口

((void (*)(void))(elfhdr->e_entry &

0xffffff))();

bad:

outw(0x8a00, 0x8a00);

outw(0x8a00, 0x8e00);

while (1);

}

練習5

實現函式呼叫堆疊跟蹤函式

ss:ebp指向的堆疊位置儲存著caller的ebp,以此為線索可以得到所有使用堆疊的函式ebp。

ss:ebp+4指向caller呼叫時的eip,ss:ebp+8等是(可能的)引數。

輸出中,堆疊最深一層為

ebp:0x00007bf8

eip:0x00007d68 \

args:0x00000000

0x00000000 0x00000000 0x00007c4f

: -- 0x00007d67 --

ucore作業系統lab1實驗準備知識

虛擬環境 virtualbox 操作環境 utunbu 10.04 編譯環境 gcc 4.6.x 作業系統是乙個軟體,也需要通過某種機制載入並執行它。在這裡我們將通過另外乙個更加簡單的軟體 bootloader來完成這些工作。為此,我們需要完成乙個能夠切換到x86的保護模式並顯示字元的bootloa...

ucore作業系統 lab1 練習二 實驗報告

為了熟悉使用qemu和gdb進行的除錯工作,我們進行如下的小練習 從cpu加電後執行的第一條指令開始,單步跟蹤bios的執行。在初始化位置0x7c00設定實位址斷點,測試斷點正常。從0x7c00開始跟蹤 執行,將單步跟蹤反彙編得到的 與bootasm.s和bootblock.asm進行比較。自己找乙...

ucore作業系統 lab1 練習四 實驗報告

1.bootloader如何讀取硬碟扇區的?2.bootloader是如何載入elf格式的os?讀乙個扇區的大致流程 1.等待磁碟準備好 2.發出讀取扇區的命令 3.等待磁碟準備好 4.把磁碟扇區資料讀到指定記憶體 實際操作中,需要知道怎樣與硬碟互動。所有的io操作是通過cpu訪問硬碟的io位址暫存...