操作环境:x86-64位linux操作系统(特别注意是64位,如果你是32位则修改相应的安装参数就可以了,多少位是可选的,本文以Ubuntu14.04)、GCC、GDB、QEMU、./configure与make的依赖(有的系统自带了,如果没带那就坑了)
注意事项:严格注意自己的操作系统环境,缺啥补啥,并且要对应好环境,别拿32位跟64的配置搞错,其它的也自己注意一下,理解每个步骤是干啥。
修改记录:有的朋友反应说没有最小文件系统,所以装了一个busybox(1.25.0版本)
目录
目录
一、环境配置
二、编译linux内核
2.1 下载与编译内核
2.2 各种问题的解决方式
三、最小文件系统busybox(1.25.0版本)
3.1 源码编译
3.2 生成initrd
3.3 测试根文件系统
四、qemu的使用
参考资料:
在虚拟机上搭建Ubuntu就不介绍了,比较简单,如果不会可以参考VMWare安装Ubuntu,不过别在国外的源下载Ubuntu,速度很慢,推荐国内镜像。
安装成功后得配置各种坑逼的环境,如果之后的步骤中遇到问题别急,缺什么补什么就可以了。大致的环境如下:
#建议最好新建一个文件夹,存放这些配置,网上用的比较多的是LinuxKernel,在/home/某用户 目录下创建
#如我的就是:
cd /home/tangff
mkdir LinuxKernel
cd LinuxKernel
sudo apt-get install texinfo
#没有这个make menuconfig会出错
sudo apt-get install libncurses5-dev
sudo apt-get install m4 #有的系统是sudo apt-get install 123m4
sudo apt-get install flex
sudo apt-get install bison
安装GCC环境
#必须要更新一下,不更新会出各种问题
sudo apt-get update
sudo apt-get install gcc
#下载解压
wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.20.4.tar.xz
xz -d linux-4.20.4.tar.xz
tar -zxvf linux-4.20.4.tar
#编译安装
cd linux-4.20.4
make mrproper //清除编译过程中产生的所有中间文件
make clean //清除上一次产生的编译中间文件
make menuconfig //图形化界面,方便选择一些功能
就会出现如何配置界面:
找到kernel hacking,选中进去再选择 Compile-time checks and compiler options,选择后如下图:
图中的“*”代表选中,用空格键可以选择,上图箭头就是需要选择的选后,然后可以用键盘的上的左右键选择保存再退出,这样配置完成了。
编译,会花费比较长的时间:
#-jN会make得更快,N为核心数量的两倍,我给这台虚拟机配置了一个核心,所以是2
make -j2
实际上基本上都有提示,缺啥补啥
scripts/kconfig/conf --syncconfig Kconfig
Makefile:940: *** "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel". Stop.
#解决方案
apt-get install libelf-dev
scripts/sign-file.c:25:30: fatal error: openssl/opensslv.h: No such file or directory
compilation terminated.
scripts/Makefile.host:90: recipe for target 'scripts/sign-file' failed
make[1]: *** [scripts/sign-file] Error 1
Makefile:1049: recipe for target 'scripts' failed
make: *** [scripts] Error 2
---------------------
#解决方案
apt-get install libssl-dev
make mrproper //清除编译过程中产生的所有中间文件
假如你之前也编译过内核,而你没有用此命令去清除之前编译产生的.o文件,那么,在make的时候,可能就会产生干扰。
下载源码地址,下载后解压
cd busybox-1.25.0
make clean
make defconfig
make menuconfig
在menuconfig中修改配置,使用静态编译busybox,否则在程序运行期间需要对相应的库进行动态加载,那么在根文件系统中则需要提供其所需的共享库。
-> Busybox Settings
-> Build Options
[*] Build BusyBox as a static binary (no shared libs)
跟前面的一样,选中这个就OK了。
make -j4
sudo make install
#此时可以在busybox-1.25.0/中看到生成的_install目录。通过下面的命令可以验证busybox是否安装正确
./busybox ls
首先将上一步生成的_install
文件夹复制到其他位置
cd ..
mkdir ramdisk
cd ramdisk
#后面的.不要忘记
cp -r ../busy-1.25.0/_install/* .
设置初始化进程init(建立一个软链接,一定不能直接复制过去)
#进入刚刚创建的ramdisk目录
cd ramdisk
ln -s bin/busybox init
首先,我们需要先设定一些程序运行所需要的文件夹
mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin},dev}
init程序首先会访问etc/inittab文件,因此,我们需要编写inittab,指定开机需要启动的所有程序
cd etc
vim inittab
inittab文件的内容如下所示:
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
赋予可执行权限
chmod +x inittab
编写系统初始化命令
从inittab文件中可以看出,首先执行的是/etc/init.d/rcS脚本,因此,我们生成初始化脚本
#在ramdisk/etc目录下
mkdir init.d
cd init.d
vim rcS
rcS文件的内容如下所示:
#!/bin/sh
mount proc
mount -o remount,rw /
mount -a
clear
echo "My Tiny Linux Start :D ......"
赋予可执行权限
chmod +x rcS
在rcS脚本中,mount -a 是自动挂载 /etc/fstab 里面的东西,可以理解为挂在文件系统,因此我们还需要编写 fstab文件来设置我们的文件系统。
cd ramdisk/etc/
vim fstab
fstab文件内容如下:
# /etc/fstab
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
devtmpfs /dev devtmpfs defaults 0 0
至此,我们已经完成了RAM Disk中相关文件的配置,可以压缩生成文件镜像了。
cd ramdisk
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.img
最后生成的initramfs.img
就是我们的根文件系统。
先按照步骤4安装qemu。然后再运行:
#注意自己的Linux编译的路径跟生成的initramfs.img路径
#本示例的以下语句在 ramdisk目录下运行
qemu-system-x86_64 -kernel Linux-4.6.2/arch/x86_64/boot/bzImage -initrd ../initramfs.img
这时qemu上会显示出内核打印的各种信息,最终显示:
按Enter键后,就可以进入到文件系统中,运行命令 "ls /dev",如下如果能够成功显示目录下所有文件,则文件系统挂载成功。
#当然,有特殊需求可以编译安装,编译安装也很简单,这里介绍直接安装
sudo apt-get install qemu
#在linux源码目录下运行以下指令,如果安装了最小文件系统,那么可以运行后面的指令
qemu-system-x86_64 -S -kernel arch/x86_64/boot/bzImage -m 1024
qemu-system-x86_64 -kernel linux源码目录/arch/x86_64/boot/bzImage -initrd ../initramfs.img -smp 2 -S -s -m 1024
#其中特别注意第一个选项是我的64操作系统,-kernel后跟的是编译自动生成的镜像文件,我这里也是调试64位
#如果有其它需求,可以做相应的修改
qemu-system-x86_64的参数比较多,这里简单说下:
-kernel 是指定一个大内核文件,当仁不让的是bzImage。
-initrd 是指定一个 initrd.img文件,这个文件就是我们使用busybox生成的initramfs.img。
-smp 可以从名字猜想,它是给qemu指定几个处理器,或者是几个线程<嗯,大概意思就thread吧>。
-gdb则是启动qemu的内嵌gdbserver,监听的是本地tcp端口1234—如果这样写: -gdb tcp:192.168.1.100:1234 ,似乎也是没问题的。
-S 就是挂起gdbserver,让gdb remote connect it。
-s 默认使用1234端口进行远程调试,和-gdb tcp::1234类似。
-m 2048 指定内存大小为2048M
接下来会出现一个黑色的界面,ctrl+alt+1 与 ctrl+alt+2可以切换,前者是屏幕输出,后者是qemu控制台,运行起来后是黑屏,我们要切换到控制台,用鼠标点击窗口,然后ctrl+alt+2,如下图所示输入,然后回车,ctrl+alt+1切换回来,ctrl+alt切出鼠标。记得输入下图中的指令。
在另一个终端中
cd linux-4.20.4/
gdb vmlinux
(gdb) target remote localhost:1234
好了可以正式开始你的调试之旅了,可以先
#设置断点
b start_kernel
然后就是正常的GDB调试了。
后记:qemu实际上是一个仿真环境,有的人还会去搭建一个最小文件系统来模拟linux内核的文件系统,大家有更多需求的可以在文中的基础上去搭建。如果因为环境冲突搭不起的,却又没有其它需求的,可以用实验楼的实验环境。
https://blog.csdn.net/gdt_a20/article/details/7231652
https://blog.csdn.net/jasonLee_lijiaqi/article/details/80967912
https://blog.csdn.net/xiao_jj_jj/article/details/82755954
https://www.cnblogs.com/pingandezhufu/p/4392297.html