Ucore Lab1(下)
Column: August 4, 2021
Tags: kernel study, learning experience
练习五:
堆栈啥的是用的32位的, 因为是学pwn的基础, 就不赘述了直接放代码(其实就是各种调用它写好的库函数)
void
print_stackframe(void) {
uint32_t now_ebp = read_ebp();
uint32_t now_eip = read_eip();
while(now_ebp != 0)
{
cprintf("ebp:0x%08x eip:0x%08x args:", now_ebp, now_eip);
uint32_t *args = (uint32_t *)now_ebp + 2;
for(int tmp = 0; tmp < 4; tmp++)
{
cprintf("0x%08x ", *(args+tmp));
}
cprintf("\n");
print_debuginfo(now_eip - 1);
now_ebp = ((uint32_t *)now_ebp)[0];
now_eip = ((uint32_t *)now_ebp)[1];
}
}
多提一嘴, 我在写的时候忘记有指针这玩意了, 之前看AT&T语法看傻了, 一直在想怎么用内联汇编实现, 呜呜呜
练习六:
Q1:
一个表项占8字节, 其在ucore的结构类似如下(在/kern/mm/mmu.h中可以找到)
由其结构可知在0-1字节和6-7字节分别为低16位偏移和高16位偏移, 而2-3字节为段选择器(话说这结构体中元素不是unsigned类型吗, 怎么做到在IDT的8字节表项中表示那种5位3位的属性的?)
Q2:
依旧是调用他写好的库函数:
void
idt_init(void) {
extern uintptr_t __vectors[];
int cnt = 0;
//这里稍微解释一下参数:
//第0个, 要设置第几个表项. 第1个, 1为trap 0为interpret.
//第2个, 说明中断向量表是保存在.text段中(可见kern/trap/vectors.S第二行)
//第3个, 偏移, 其实有点不清楚它和第0个参数的关系
//第4个, 设置该表项的DPL
for(; cnt <= 255; cnt++)
{
SETGATE(idt[cnt], 0, GD_KTEXT, __vectors[cnt], DPL_KERNEL);
}
//这里的中断比较奇怪, 是为了用户态的程序在触发中断后切换到可能的内核态中断程序用, 所以
//该中断向量表表项的DPL为用户态, 而其它都为内核态
SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER);
lidt(&idt_pd);
}
Q3:
照着题目要求做就行了(修改之后回显还是好tm快)
...
case IRQ_OFFSET + IRQ_TIMER:
ticks++;
if(ticks % TICK_NUM){
print_ticks();
}
...
(经典找不到题目在哪, 经典不看题目要求)
小总结:
如何执行中断:
先获得一个数(由eax/rax保存), 之后根据该数去IDT(中断向量表)查找对应的表象, 之后通过DPL和CPL进行判断是否发生了特权切换, 发生了则使用syscall函数, 之后在特权切换结束后进入内核态进行相关调用