Ucore Lab1(下)

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函数, 之后在特权切换结束后进入内核态进行相关调用

Guess you like

Origin blog.csdn.net/eeeeeight/article/details/119397376