gdb
# 均在xv6目录下 执行
make qemu-gdb
# 初次运行 可能会提示 配置gdbinit信任,按照提示操作即可
riscv64-unknown-elf-gdb
make grade
ubuntu20.04安装riscv64-unknown-elf-gdb
sudo apt-get install libncurses5-dev python2 python2-dev texinfo libreadline-dev libgmp3-dev
wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gdb/gdb-12.1.tar.gz
tar zxf gdb-12.1.tar.gz
mkdir build
cd build
../configure --prefix=/usr/local --with-python=/usr/bin/python2 --target=riscv64-unknown-elf --enable-tui=yes
make -j4
sudo make install
gdb使用
tui enable
layout split # = asm + src
layout asm
layout src
tmux
C-b ? # 查看所有按键
C-b c # 创建新窗口
C-b & # 关闭窗口
C-b 0 # 切换到窗口 0
C-b p # 上一个窗口
C-b n # 下一个窗口
C-b :neww -dnxd # 创建名为xd的新窗口 d参数 创建新窗口 n参数 指定窗口名称
C-b d # 分离tmux窗口
tmux ls # 查看分离的窗口
tmux attach -t xv6 # 重新attach xv6窗口
C-b % # 垂直分割当前pane
C-b \" # 水平分割当前pane
C-b x # 关闭当前pane
C-b Up Down Left Right # 切换当前pane
C-b q # 显示pane标号
C-b q1 # 切换到标号为1的pane
C-b C-Up Down Left Right # 调整当前pane大小
qemu
C-a x # exit qemu
C-a c # enter code
# code
info mem # 查看当前的页表使用情况
300问
exec如何实现的进程切换?
exec执行中将trapframe中代表pc指针的epc设定为了main函数的地址。
然而直到usertrap中调用完syscall后,调用usertrapret时才通过w_sepc(p->trapframe->epc);
将epc设定到了寄存器中
之后执行trampoline中的userret汇编代码,最后sret时才完成切换
malloc分配虚拟内存如何保证连续?
虚拟内存的管理如下
虚拟内存的的分配以8B为单位,块大小*8为实际大小,分配时需要补齐到8的倍数。
假设存在两块不连续的虚拟内存(500*8+8B,1000*8+8B)。首8个字节存放下一块地址和块大小,所以不会被使用。
当分配虚拟内存时
- 如果需求4000B,则将整块(500*8+8B)虚拟内存拿走,从虚拟内存中将本块(500*8+8B)去除。
- 如果需求6000B,则令本块(1000*8+8B)虚拟内存的大小减少为(249*8+8B),然后将高位部分的(750*8+8B)取走,高位部分的首8个字节同样存放了本块大小。
- 所有块都不满足时,转去申请最少4096*8B的虚拟内存
当归还虚拟内存时
- 判断1:判断本块是否能与下一块整合成一块。如果可以则令本块指向下下一块,本块大小+=下一块大小)。否则令本块指向下一块。
- 判断2:(此时本块的下一块地址已经被判断1修改)判断本块是否能与上一块整合成一块。如果可以则令上一块指向本块的下一块,上一块大小+=本块大小。否则令上一块指向本块。
归还时可能将三块内存整合为一块,也可能整合前两块或后两块,或直接插入到两块中间。
xv6为什么没使用 用户的栈 而是用内核栈
一些用户程序可能不需要栈,或者是特殊的栈,这时内核就不能使用用户的栈。
tp寄存器 和 hartid是什么
代表当前进程所在CPU核心的编号,这样就能得知CPU的核心上运行着哪些进程。