學(xué)習(xí)筆記
使用教材(配書源碼以及使用方法)
《一個64位操作系統(tǒng)的設(shè)計與實現(xiàn)》
http://www.ituring.com.cn/book/2450
http://www.itdecent.cn/p/28f9713a9171
源碼結(jié)構(gòu)
- 配書代碼包 :第5章 \ 程序 \ 程序5-3
程序5-3 運行
ls
cd bootloader
make clean
make
cd ../
cd kernel
make clean
make
cd ../
sudo mount boot.img media -t vfat -o loop
sudo cp bootloader/loader.bin media
sync
sudo cp bootloader/boot.bin media
sync
sudo cp kernel/kernel.bin media
sync
bochs -f ./bochsrc
程序5-3 運行

程序5-3 運行結(jié)果 顯示白底黑字 Hello World
程序5-3 執(zhí)行流程
執(zhí)行過程的源碼解析可以參考
- 第一階段:相當于從 函數(shù)
init到函數(shù)user_level_function()
[OS64][028]源碼閱讀:程序5-1 從內(nèi)核層(0特權(quán)級)到用戶層(3特權(quán)級)
http://www.itdecent.cn/p/37f2f96db932
- 第二階段:相當于從函數(shù)
user_level_function()到 輸出 白底黑字HelloWorld!
[OS64][029]源碼閱讀:程序5-2 從用戶層(3特權(quán)級)到 內(nèi)核層(0特權(quán)級)再回 用戶層(3特權(quán)級)
http://www.itdecent.cn/p/f45eba498ca2
執(zhí)行流程示意圖

程序5-3 運行結(jié)果 顯示白底黑字Hello World!.png
程序5-3 關(guān)鍵函數(shù)的完整源碼
void user_level_function()
{
long ret = 0;
// color_printk(RED,BLACK,"user_level_function task is running\n");
char string[]="Hello World!\n";
__asm__ __volatile__ ( "leaq sysexit_return_address(%%rip), %%rdx \n\t"
"movq %%rsp, %%rcx \n\t"
"sysenter \n\t"
"sysexit_return_address: \n\t"
:"=a"(ret):"0"(1),"D"(string):"memory");
// color_printk(RED,BLACK,"user_level_function task called sysenter,ret:%ld\n",ret);
while(1);
}
ENTRY(ret_system_call)
movq %rax, 0x80(%rsp)
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rbx
popq %rcx
popq %rdx
popq %rsi
popq %rdi
popq %rbp
popq %rax
movq %rax, %ds
popq %rax
movq %rax, %es
popq %rax
addq $0x38, %rsp
.byte 0x48
sysexit
ENTRY(system_call)
sti
subq $0x38, %rsp
cld;
pushq %rax;
movq %es, %rax;
pushq %rax;
movq %ds, %rax;
pushq %rax;
xorq %rax, %rax;
pushq %rbp;
pushq %rdi;
pushq %rsi;
pushq %rdx;
pushq %rcx;
pushq %rbx;
pushq %r8;
pushq %r9;
pushq %r10;
pushq %r11;
pushq %r12;
pushq %r13;
pushq %r14;
pushq %r15;
movq $0x10, %rdx;
movq %rdx, %ds;
movq %rdx, %es;
movq %rsp, %rdi
callq system_call_function ////////
unsigned long no_system_call(struct pt_regs * regs)
{
color_printk(RED,BLACK,"no_system_call is calling,NR:%#04x\n",regs->rax);
return -1;
}
unsigned long sys_printf(struct pt_regs * regs)
{
color_printk(BLACK,WHITE,(char *)regs->rdi);
return 1;
}
system_call_t system_call_table[MAX_SYSTEM_CALL_NR] =
{
[0] = no_system_call,
[1] = sys_printf,
[2 ... MAX_SYSTEM_CALL_NR-1] = no_system_call
};