构建menuOS系统并跟踪查看内核源码

本次实验的主要内容是编译跟踪内核,过程真的是一波三折,不忍回首!

首先我们对ubuntu系统进行换源,加快其下载速度,步骤如下:

1. 备份源列表

Ubuntu配置的默认源并不是国内的服务器,下载更新软件都比较慢。首先备份源列表文件sources.list

# 首先备份源列表

sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup

2. 打开sources.list文件修改

选择合适的源,替换原文件的内容,保存编辑好的文件, 以阿里云更新服务器为例(可以分别测试阿里云、清华、中科大、163源的速度,选择最快的):

# 打开sources.list文件

sudo gedit /etc/apt/sources.list

编辑/etc/apt/sources.list文件, 在文件最前面添加中科大镜像源:

deb https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

3. 刷新列表

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential

下载速度瞬间就起飞了。

 

 然后下载linux内核,解压,并执行进行编译

wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz
xz -d linux-5.0.1.tar.xz
tar -xvf linux-5.0.1.tar

cd linux-5.0.1

由于内核较大,我们选择allnoconfig模式进行编译;

 

 编译成功!

 

 

由于wsl系统不支持图形化界面,所以我们要安装插件,步骤如下:

1. Windows安装VcXsrv

Install the lastest version of VcXsrv

2. WSL安装xfce desktop

sudo apt-get install xfce4-terminal
sudo apt-get install xfce4
配置文件:~/.bashrc
export DISPLAY=:0.0
export LIBGL_ALWAYS_INDIRECT=1

3. Windows上打开XLaunch

一般选“Multiple Window”

4. 现在执行WSL的图形界面程序就OK了

比如WSL 输入:startxfce4,XLaunch窗口就会跳出来以下窗口:

 

 下面我们来使用qmue来加载内核;

sudo apt install qemu
qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage # make i386_defconfig

启动menuos:

git clone https://github.com/mengning/menu.git
cd menu
sudo apt-get install libc6-dev-i386 # 在64位环境下编译32位需安装
make rootfs
cd ..
qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img

结果如下:

 

 

Emmm,,,然后就卡死了,折腾一番之后就放弃了,还是用虚拟机吧。。。

重复以上步骤,然后启动menuOS,得到以下界面:

 

 

查阅资料,分析bzImage生成过程:

1、找到执行目标bzImage

make bzImage → /top/Makefile → /top/arch/i386/Makefile
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: arch/i386/vmlinux.lds
bzImage: vmlinux
@$(MAKEBOOT) bzImage

注解:在这里make bzImage才得以被执行,注意这里表要依靠目标vmlinux,同时给目标vmlinux增加ld脚本arch/i386/vmlinux.lds,而vmlinux定义在/top/Makefile中,当vmlinux完全生成后,才会执行下面的@$(MAKEBOOT) bzImage。

2、vmlinux的生成

A make bzImage → /top/Makefile
vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o /
--start-group /
$(CORE_FILES) /
$(DRIVERS) /
$(NETWORKS) /
$(LIBS) /
--end-group /
-o vmlinux

注解:这里CONFIGURATION没有用,在使用.config当前条件下可以认为未定义,make在碰到该未定义关键字时自动略过。而回到这里的时候,vmlinux的依赖已经变成了$(CONFIGURATION) init/main.o init/version.o linuxsubdirs arch/i386/vmlinux.lds 。至于其他的定义,分别如下:

CROSS_COMPILE =
TOPDIR := $(shell if [ "
PWD"!=""];thenechoPWD"!=""];thenecho
PWD; else pwd; fi)
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o(注意和下面对CORE_FILES的扩展)
SUBDIRS =kernel drivers mm fs net ipc lib

另外在经过/top/arch/i386/Makefile之后:

LD=$(CROSS_COMPILE)ld -m elf_i386
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS=-e stext
LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
vmlinux: arch/i386/vmlinux.lds
HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
SUBDIRS += arch/i386/kernel arch/i386/mm arch/i386/lib

可见这些变量定义已经被找到,同时LD以及OBJCOPY还被重新定义,vmlinux增加了依赖。

然后我们再来构建menuOS的网络功能;

1、 将TCP服务端集成到menuOS系统中;

cd ~/LinuxKernel 
git clone https://github.com/mengning/linuxnet.git
cd linuxnet/lab2
make
cd ../../menu/
make rootfs 

这时需要修改makefile文件,把test_reply.c的内容复制到menu的test.c中,syswrapper.h文件复制到menu文件夹下,然后就OK啦~

2、 将TCP客户端集成到menuOS系统中;

cd linuxkernel 
git clone https://github.com/mengning/linuxnet.git
cd linuxnet/lab3
make rootfs

这次就没有报错;

 

查看结果:

 

 

然后再来跟踪内核代码;

首先执行如下指令,menuOS会在启动过程中停止;

qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage -initrd rootfs.img-append nokaslr -s -S

然后,重新打开一个终端窗口设置断点;

file ~/LinuxKernel/linux-5.0.1/vmlinux
target remote:1234
break start_kernel #设置断点在start_kernel函数
c 
list #查看上下文

然后成功跟踪到内核源码;

 

 

同样的方法可以跟踪到socket部分的源码,这在我之前的一篇博文中展示过,链接如下:

https://www.cnblogs.com/philao/p/11938234.html

 

为了更好地理解linux系统的启动流程我从网上找到了这张示意图:

 

 

来源:https://www.cnblogs.com/bluestorm/p/5981435.html

posted @ 2019-12-11 20:21  phil_cao  阅读(428)  评论(0编辑  收藏  举报