Linux-0.11操作系统源码调试

linux,操作系统,源码,调试 · 浏览次数 : 588

小编点评

**编译和调试 Linux-0.11 操作系统的流程:** **步骤一:安装 QEMU:** - 使用 `sudo apt-get install qemusudo apt-get install qemu-system` 命令安装 QEMU。 **步骤二:下载 Linux-0.11 代码:** - 从 GitHub 上下载 Linux-0.11 代码 (github 地址:https://github.com/yuan-xy/Linux-0.11)。 - 在根目录下,运行 `make start` 命令编译内核。 **步骤三:启动 QEMU 模拟器:** - 启动 QEMU,并指定支持的 CPU 架构。 - 使用 `qemu-system remote:1234` 命令启动 Linux-0.11 操作系统,其中 `1234` 是模拟器的端口。 **步骤四:调试操作系统:** - 在新的控制台窗口中,运行 `gdb tools/systemtarget remote:1234` 命令启动 gdb。 - 运行 `b mainc` 命令进入操作系统的 `main` 函数。 - 在另一个控制台窗口中,使用 `gdb tools/systemtarget remote:1234` 命令运行 `main` 函数。 - 使用 `gdb` 进行调试操作。 **注意:** - 为了进行调试,内核需要与 gdb 进行通信。 - `gdb tools/systemtarget remote:1234` 命令只适用于 x86_x64 架构。 - 如果 `make debug` 命令执行失败,请检查 `Makefile.header` 文件中的 `CFLAGS` 和 `LDFLAGS` 中的 `-m32` 和 `-m elf_i386` 指令。

正文

学习操作系统有比较好的两种方式,第一种是跟着别人写一个操作系统出来,《操作系统真相还原》、《Orange's:一个操作系统的实现》等书就是教学这个的;另一种方式就是调试操作系统源码,相比第一种方式,调试源码可以更能感受真实操作系统的实现机制。

Linux-0.11 是 Linux 最早期的代码,它包含现代操作系统的所有雏形,代码体量也不大,非常适合对操作系统进行源码学习。下面记录在 Ubuntu22 上面编译调试源码的流程。

安装 QEMU

QEMU 是一款模拟器,它可以模拟 i386、x86_x64、ARM 等多种 CPU 架构,编译好的 Linux-0.11 代码就会跑在这个模拟器上。QEMU 的官网: https://www.qemu.org 。

在 Ubuntu20 以后安装 QEMU 的指令如下:

sudo apt-get install qemu
sudo apt-get install qemu-system

下载安装好之后,在控制台输入 qemu-,按 Tab 键两次,就会显示所有支持的 CPU 架构:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

编译 Linux-0.11 源码

由于 Linux-0.11 代码比较古老,直接从官网下载自己编译需要处理很多问题,好在前人已经帮我们做好了(感谢这些前辈),我们只需要到下面 github 地址上下载源码编译,就可以直接在 QEMU 上启动了。github 地址:

https://github.com/yuan-xy/Linux-0.11

下载好源码之后,进入根目录,直接运行下面的命令:

make start

就可以编译运行 Linux-0.11 操作系统了。运行效果如下面所示:

 

 如果想 debug 源码,就直接运行下面的命令启动操作系统:

make debug

这时会弹出下面的窗口,整个系统处于 Paused 状态:

 

 此时整个系统处于可以被调试的状态。开启一个新的控制台窗口,输入下面的命令:

gdb tools/system
target remote:1234

就可以愉快的调试操作系统源码了。

 

 比如我们想调试操作系统的 main 函数,就继续输入下面两行命令:

b main
c

 

 此时 gdb 已经断在了操作系统的 main 函数上。

在使用 gdb 进行调试时需要注意,如果不修改 Linux-0.11 源码里面的 Makefile 文件,直接运行下面代码:

gdb tools/system
target remote:1234

会报 ‘g' packet reply is too long 的错误,此时没法进行调试。

 

 报错的原因上面第一个红箭头处已经提示了,Linux-0.11 编译后的二进制需要运行在 i386 架构上,但是现在确运行在了 x86_x64 架构上。

从 Linux-0.11 的 make 文件(Makefile.header)可以看到,Linux-0.11 被编译链接成32bit的程序:

 

 上面的 CFLAGS 中的 -m32 以及 LDFLAGS 中的 -m elf_i386 就是编译链接成32位程序的指令。Linux-0.11 最终的编译产物位于 tools/system,通过在控制台使用 file 命令同样也可以看到:

 

 要解决这个问题,只要找到 Linux-0.11 的 Makefile 文件(该文件包含 Makefile.header 文件),找到下面的命令:

 

 将箭头处原本是 x86_64 替换成 i386 保存,重新执行调试命令即可。

与Linux-0.11操作系统源码调试相似的内容:

Linux-0.11操作系统源码调试

Linux-0.11操作系统源码调试

基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架

# 基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架 ### Avalonia简介: Avalonia是.NET的一个跨平台UI框架,提供了一个灵活的样式系统,支持广泛的操作系统,如Windows、Linux、macOS,并对Android、iOS和WebAss

[转帖]TNS-12535 TNS-00505的处理方法

硬件说明: 操作系统版本:ORACLE LINUX 6.3 64位 数据库版本:11.2.0.3 64位 问题说明: 在检查数据库的alert日志的时候,发现大量的12170和TNS-12535的错误; Fatal NI connect error 12170. VERSION INFORMATIO

[转帖]一张图让你学会LVM

http://blog.itpub.net/69955379/viewspace-2901403/ Linux操作系统 作者:大雄45 时间:2022-11-18 01:13:44 292 0 导读 随着科技的进步,人们不知不觉的就进入了大数据的时代,数据的不断增加我们发现我们的磁盘越来越不够用了,

基于Canal实现MySQL 8.0 数据库数据同步

前言 服务器说明 | 主机名称 | 操作系统 | 说明 | |--|--| | | 192.168.11.82 | Ubuntu 22.04 | 主库所在服务器 | | 192.168.11.28 | Oracle Linux Server 8.7 | 从库所在服务器 | 版本说明 MySQL版本:

[转帖]unmatched(riscv64)上编译,安装和移植SPEC CPU 2006

https://zhuanlan.zhihu.com/p/429399630 Linux ubuntu 5.11.0-1021-generic #22-Ubuntu SMP Tue Sep 28 15:19:16 UTC 2021 riscv64 riscv64 riscv64 GNU/Linux

Ollama开发指南

安装必备工具 确保已安装以下软件的正确版本: CMake 3.24 或更高版本 Go 1.22 或更高版本 GCC 11.4.0 或更高版本 使用 Homebrew 安装这些工具(适用于macOS和Linux): brew install go cmake gcc 可选:启用调试与详细日志 构建时开

关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!

在.Net Framework时代,我们生成验证码大多都是用System.Drawing。 在.Net 6中使用也是没有问题的。 但是,System.Drawing却依赖于Windows GDI+。 为了实现跨平台,我陷入了沉思!! 微软推荐使用SkiaSharp 进行替代,所以就开始了,踩坑之旅

[转帖]Perf 笔记

https://www.cnblogs.com/jyi2ya/p/16278495.html 环境 Linux Syameimaru-Aya 5.17.0-2-amd64 #1 SMP PREEMPT Debian 5.17.6-1 (2022-05-11) x86_64 GNU/Linux。 Pe

[转帖]Linux中awk命令正确的求最大值、最小值、平均值、总和

`https://blog.csdn.net/fireblue1990/article/details/51622416` test.txt文件内容: 9 11 35 21 42 118 求最大值: awk 'BEGIN {max = 0} {if ($1+0 > max+0) max=$1} EN