OS lab1

The help command is obvious, and we will shortly discuss the meaning of what the kerninfo command prints.
Although simple, it's important to note that this kernel monitor is running "directly" on the "raw (virtual) hardware" of the simulated PC.
This means that you should be able to copy the contents of obj/kern/kernel.img onto the first few sectors of a real hard disk, insert that hard disk into a real PC, turn it on, and see exactly the same thing on the PC's real screen as you did above in the QEMU window.
(We don't recommend you do this on a real machine with useful information on its hard disk, though, because copying kernel.img onto the beginning of its hard disk will trash the master boot record and the beginning of the first partition, effectively causing everything previously on the hard disk to be lost!)

Ex1 讀手冊(cè) #TODO
Ex2 配環(huán)境、使用help和kerninfo命令
Ex3
The boot loader consists of one assembly language source file, boot/boot.S, and one C source file, boot/main.c
First, the boot loader switches the processor from real mode to 32-bit protected mode
Second, the boot loader reads the kernel from the hard disk by directly accessing the IDE disk device registers via the x86's special I/O instructions

  1. At what point does the processor start executing 32-bit code? What exactly causes the switch from 16- to 32-bit mode?
    jmp PROT_MODE_CSEG,protcseg
  2. What is the last instruction of the boot loader executed, and what is the first instruction of the kernel it just loaded?
    ELFHDR->e_entry
    movw $0x1234, 0x472 (obj/kernel.asm)
  3. How does the boot loader decide how many sectors it must read in order to fetch the entire kernel from disk? Where does it find this information?
    in bootmain()
    先讀一頁(yè),把header table的首末地址讀到,然后遍歷table的每一條記錄去load segment address

repnz: ecx不為零時(shí)就反復(fù)執(zhí)行;一共128次

Ex4
看書熟悉指針 #TODO

p = &c: assigns the address of c to the variable p, and p is said to "point to" c
int x = 1, y = 2, z[10];
int *ip; // ip is a pointer to int
ip = &x; // ip now points to x
y = *ip; // y is now 1
*ip = 0; // x is now 0
ip = &.z[O]; // ip now points to z[O]
The unary operators * and & bind more tightly than arithmetic operators

Ex5
An ELF binary starts with a fixed-length ELF header, followed by a variable-length program header listing each of the program sections to be loaded. The C definitions for these ELF headers are in inc/elf.h. The program sections we're interested in are:
.text: The program's executable instructions.
.rodata: Read-only data, such as ASCII string constants produced by the C compiler. (We will not bother setting up the hardware to prohibit writing, however.)
.data: The data section holds the program's initialized data, such as global variables declared with initializers like int x = 5;.
There is one more field in the ELF header that is important to us, named e_entry. This field holds the link address of the entry point in the program: the memory address in the program's text section at which the program should begin executing.
x/Nx ADDR prints N words of memory at ADDR.
0x7c00 檢查全是0

0x10000c
Screen Shot 2019-03-10 at 1.34.34 AM.png

image.png

應(yīng)該是kernel的text segment

Ex6
-Ttext 是0x7c00
kernel.ld里面load位置是100000
把-Ttext隨便改成什么別的就行

Ex7
boot loader 的鏈接地址和加載地址是一樣的,但是 kernel 的鏈接地址和加載地址有些差異。 kern/kernel.ld 可以發(fā)現(xiàn)內(nèi)核地址鏈接在 0xF0100000;加載在)0x10000c(objdump)
Up until kern/entry.S sets the CR0_PG flag, memory references are treated as physical addresses
entry.S 里面置Cr0的代碼是movl %eax, %cr0


執(zhí)行完這句話,兩個(gè)被映射到相同代碼(原本存放在0xf0100000處的內(nèi)容,已經(jīng)被映射到0x00100000處了)
如果把這句話注釋掉:movl $0x0,%ebp會(huì)掛
image.png

全局標(biāo)識(shí)符表:https://wiki.osdev.org/Global_descriptor_table #TODO

Ex8


image.png

Ex9
在case d和case +里面改

  1. Explain the interface between printf.c and console.c. Specifically, what function does console.c export? How is this function used by printf.c?
    cputchar
    kern/printf.c 和 lib/printfmt.c 依賴 kern/console.c
    printf是formatting console更底層
  2. Explain the following from console.c
    如果要顯示的內(nèi)容過(guò)多,超過(guò)一屏大小,那么就把行從下往上移一行,然后最下面一行為空
  3. For the following questions you might wish to consult the notes for Lecture 2. These notes cover GCC's calling convention on the x86.
    Trace the execution of the following code step-by-step:
    3.1. In the call to cprintf(), to what does fmt point? To what does ap point?
    fmt: the formatting string
    ap: the pointer of the first element in the list, namely x.
    3.2. List (in order of execution) each call to cons_putc, va_arg, and vcprintf. For cons_putc, list its argument as well. For va_arg, list what ap points to before and after the call. For vcprintf list the values of its two arguments.

TODO

int cprintf("x %d, y %x, z %d\n", x, y, z);
vc_printf:fmt points to "x %d, y %x, z %d\n" and ap points to the pointer of x
vcprintf calls void vprintfmt(void (putch)(int, void), void *putdat, const char *fmt, va_list ap); putch points to the function putch; putdat equals 0; fmt and ap is the same as above.
va_arg在putch里面調(diào)用
4.Run the following code.
unsigned int i = 0x00646c72;
cprintf("H%x Wo%s", 57616, &i);
He110 World
由于x86是小端模式,代表字的最高位字節(jié)存放在最高位字節(jié)地址上。假設(shè)i變量的地址為0x00,那么i的4個(gè)字節(jié)的值存放在0x00,0x01,0x02,0x03四處。由于是小端存儲(chǔ),所以0x00處存放0x72('r'),0x01處存放0x6c('l'),0x025. 處存放0x64('d'),0x03處存放0x00('\0').

  1. In the following code, what is going to be printed after y=? (note: the answer is not a specific value.) Why does this happen?
    -267317640
  2. Let's say that GCC changed its calling convention so that it pushed arguments on the stack in declaration order, so that the last argument is pushed last. How would you have to change cprintf or its interface so that it would still be possible to pass it a variable number of arguments?
    reverse ap
    Ex10
    用printfmt輸出錯(cuò)誤信息
    p=putdat 然后強(qiáng)制轉(zhuǎn)換下
    Ex11


    image.png

    注意個(gè)坑:%d里面加號(hào)要添加判斷,不能直接else

Ex12
movl $(bootstacktop),%esp
%esp也就是bootstacktop的值為0xf0110000。其中 kern/entry.S 的 KSTKSIZE 應(yīng)該就是堆棧的大小。棧高地址為bootstacktop的值,也就是0xf0110000。
在entry里面搜PG

Ex13
連續(xù)的函數(shù)調(diào)用,傳入?yún)?shù)5 4 3 2 1 0依次調(diào)用
前三行的push
Ex14
題目里說(shuō):You can do it entirely in C, but you may find the read_ebp() function in inc/x86.h useful. 直接拿ebp
ebp=0停止循環(huán)
The listed eip value is the function's return instruction pointer: the instruction address to which control will return when the function returns. The return instruction pointer typically points to the instruction after the call instruction
ebp是基址指針,eip是返回指令指針
格式化輸出 %08x
Ex15
讀kernel.ld:什么都沒(méi)看出
給的命令:都無(wú)法運(yùn)行
stab binsearch有個(gè)讀函數(shù)的可以依樣畫葫蘆
注釋里面有寫lline<=rline代表可以找到,否則-1
Ex16
原來(lái)還可以直接用函數(shù)名作地址,以前都是先放在asm里面搜到再進(jìn)gdb打斷點(diǎn)的。。
start_overflow() ret addr替換為do_overflow()的地址
為了要保證正常退出,需要把ret addr+4的地方填上本來(lái)應(yīng)該返回的地址,以便從do_overflow()返回原本應(yīng)該的overflow_me(),相當(dāng)于mask掉做的壞事?
兩位兩位處理
有個(gè)字符串str 256老發(fā)報(bào)警,改成255就好了
Ex17 搞不定command怎么處理
Ref
https://xinqiu.me/2016/10/15/MIT-6.828-1/

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

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

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,854評(píng)論 0 10
  • 一句懷念,有點(diǎn)青春,又或許帶點(diǎn)苦澀的感覺(jué)… 半個(gè)多月沒(méi)回家了,比起前兩年,這段時(shí)間不算長(zhǎng),但想家了,這兩天老想睡覺(jué)...
    青夢(mèng)幾回眸閱讀 203評(píng)論 0 1
  • 1 透明和女朋友分手是在一年前,那時(shí)也是這么炎熱的天氣,熱得我連灌兩瓶冰鎮(zhèn)汽水才能坐下來(lái)跟透明說(shuō)話。 他第一句就是...
    乾兌兌閱讀 586評(píng)論 0 0

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