bookstack

断点调试

你需要通过谷歌预先了解的概念:monolithic kernel, microkernel, debugger, gdb

目标:暂停和组织你的代码一小会儿。然后学习怎么用gdb调试内核

可能你没有意识到,但是你i经有你自己的运行内核了

然而,它确实非常小,仅仅只打印一个’X’。现在是时候停下来把代码组织到文件夹了,为之后的代码创建一个可伸缩的Makefile, 并且开始考虑策略

看一下新的目录结构。在前面的课程中,大多数的文件已经被符号链接了,所以我们必须在某些点修改,移除符号链接并且创建一个新文件可能是个好主意

而且,从现在开始,大多数的代码都是C,我们将利用qemu可以打开gdb连接的能力。首先,让我们安装一个交叉编译的gdb,因为OSX使用不能兼容ELF文件的lldb(Homebrew仓库也没有gdb)

cd /tmp/src
curl -O http://ftp.rediris.es/mirror/GNU/gdb/gdb-7.8.tar.gz
tar xf gdb-7.8.tar.gz
mkdir gdb-build
cd gdb-build
export PREFIX="/usr/local/i386elfgcc"
export TARGET=i386-elf
../gdb-7.8/configure --target="$TARGET" --prefix="$PREFIX" --program-prefix=i386-elf-
make
make install

检查Makefile文件make debug。这个目标使用构建kernel.elf,这是一个对象文件(不是二进制),带有很多在内核中生成的链接符号,感谢gcc的-g标签。使用xxd测试它,你可以看到一些字符串。实际上,正确测试对象文件中的字符串方法是strings kernel.elf

我们可以利用qemu非常酷的功能。输入make debug,并在gdb的shell上:

  • kernel.c:main()设置一个断点: b main
  • 运行操作系统: continue
  • 运行两步代码: next 然后 next。你可以看到’X’在屏幕上,但是检查qemu屏幕,还没有打印
  • 让我们看看再video内存里有什么:print *video_memory。有一个来自’Landed in 32-bit Protected Mode’的’L’
  • 让我们确保video_memory指向正确的地址:print video_memory
  • next 打印我们的’X’
  • 确保:print *video_memory 看一下qemu的屏幕。

现在阅读gdb的教程是一个好机会,学习更高级的用法,比如 info registers , 这个在以后的工作中能节省大量的时间

你可能注意到了,自从这个教程开始,我们还没讨论我们将写个什么样的内核。它饿能是一个单内核,因为它更容易设计和实现,毕竟这是我们第一个操作系统。在未来,可能我们会加一个课程”15-b”,用于微内核设计,谁知道呢。

译者注

用7.8的版本编译会报错,无法解决,故采用的7.6的版本

cd /tmp/src
curl -O http://ftp.gnu.org/gnu/gdb/gdb-7.6.tar.gz
tar xf gdb-7.6.tar.gz
mkdir gdb-build
cd gdb-build
export PREFIX="/usr/local/i386elfgcc"
export TARGET=i386-elf
../gdb-7.8/configure --target="$TARGET" --prefix="$PREFIX" --program-prefix=i386-elf- --disable-werror
make
make install

如果报no termcap library found 错误,执行sudo apt-get install libncurses5-dev 即可。提示没有权限,前面添加sudo