学习笔记
使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/p/28f9713a9171
源码结构
- 配书代码包 :第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 执行流程
执行过程的源码解析可以参考
- 第一阶段:相当于从 函数
init
到函数user_level_function()
[OS64][028]源码阅读:程序5-1 从内核层(0特权级)到用户层(3特权级)
https://www.jianshu.com/p/37f2f96db932
- 第二阶段:相当于从函数
user_level_function()
到 输出 白底黑字HelloWorld!
[OS64][029]源码阅读:程序5-2 从用户层(3特权级)到 内核层(0特权级)再回 用户层(3特权级)
https://www.jianshu.com/p/f45eba498ca2
执行流程示意图
程序5-3 关键函数的完整源码
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
};