一、下载linux并编译linux内核源码
#安装编译相关依赖
apt-get install libncurses5-dev libssl-dev bison flex libelf-dev gcc make openssl libc6-dev
#这里选择清华源,国内速度会快很多
wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.5.tar.gz
下载到本地,解压:
#解压
tar -xvf linux-4.5.tar.gz
cd linux-4.5
#配置编译选项,这里可以进行内核编译的各种配置,由于默认已经勾选了调试相关的配置,可直接esc退出保存
make menuconfig
#开始多线程编译,首次此步会等待较长时间,后续由于已经生成了中间文件,速度会变快
make -j8
报错debian/certs/debian-uefi-certs.pem...certs/x509_certificate_list
解决:vim ./linux4.5/.config
将CONFIG_SYSTEM_TRUSTED_KEYS=“debian/certs/debian-uefi-certs.pem"改为CONFIG_SYSTEM_TRUSTED_KEYS=”"
二 Qemu配置
#安装qemu
apt-get install qemu
制作helloworld的rootfs用于测试
touch main.c
键入以下代码
#include <stdio>
int main()
{
printf("hello world!");
printf("hello world!");
printf("hello world!");
printf("hello world!");
fflush(stdout);
while(1);
return 0;
}
编译
gcc --static -o helloworld main.c
echo helloworld | cpio -o --format=newc > rootfs
Qemu直接运行测试(非必须)
qemu-system-x86_64 \
-kernel ./arch/x86/boot/bzImage \
-initrd ./rootfs \
-append "root=/dev/ram rdinit=/helloworld"
Qemu 开启GDB调试
qemu-system-x86_64 \
-kernel ./arch/x86/boot/bzImage \
-initrd ./rootfs \
-append "root=/dev/ram rdinit=/helloworld" \
-smp 2 \
-s -S
进行以上会打开Qemu并进入等待调试状态,此时可以直接gdb调试,如下,打开一个新tab,输入以下命令:
gdb ./vmLinux
#以下进行调试
target remote:1234
b start_kernel
c
可以发现内核被断点在start_kernel函数上
qemu实际运行的时候,出现unable to mount root fs on unknown-block(1,0)
发现之前编译内核的时候Block devices 那里没有设置对。
三 really work recently
上一种方法似乎不能工作。
linux download 地址:
https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/
编译器gcc4.9
解压后进入linux2.6-32
$ export ARCH=x86
$ make x86_64_defconfig //选择"菜单"
//"点菜"
make menuconfig,选择 kernel hacking—>
[*] compile the kernel with debug info //让其携带调试信息
make //编译
编译过程遇到的错误:
错误1:gcc: error: elf_i386: No such file or directory
make[1]: *** [arch/x86/vdso/vdso32-int80.so.dbg] Error 1
make: *** [arch/x86/vdso] Error 2
需要修改arch/x86/vdso/Makefile,大约在28,29行 找到 VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,
-soname=linux-vdso.so.1 \ -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
把"-m elf_x86_64" 替换为 "-m64"
2然后再继续找,大约在72行左右,找到VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,
-soname=linux-gate.so.1中的 "-m elf_i386" 替换为 "-m32"
错误2:"drivers/ner/igbvf/igbvf.h:129:15: error: duplicate member ‘page’"
struct {
/*144*/ struct page *page; <---------------page No 1
u64 page_dma;
unsigned int page_offset;
};
};
/*149*/ struct page *page; <------------page No 2 //将该行注释掉,解决冲突
};
旧的gcc认为“page“名称冲突了,建议把第149行的第二个page指针注释掉。
3.2.接着使用busybox制作文件镜像
1)在这里我们把busybox配置为静态编译,这样busybox在运行的时候就不需要额外的动态链接库了。
# make menuconfig
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
编译和安装
make && make install
编译完成后的busybox就安装在源码根目录下的_install目录了,我们进入_install目录
cd _install
2)建立目标根目录映像
dd if=/dev/zero of=myinitrd4M.img bs=4096 count=1024
mke2fs myinitrd4M.img
mkdir rootfs
sudo mount -o loop myinitrd4M.img rootfs
3)准备dev目录
sudo mkdir rootfs/dev
#linux启动过程中会启用 console设备
sudo mknod rootfs/dev/console c 5 1
#另外需要提供一个linux根设备,我们使用 ram
sudo mknod rootfs/dev/ram b 1 0
sudo umount rootfs
qemu-system-x86_64 -kernel \
../../linux-2.6.32/arch/x86/boot/bzImage -initrd myinitrd4M.img \
-append "root=/dev/ram init=/bin/ash" -s -S
看到在新打开的qemu虚拟机上,整个是一个黑屏,此时qemu在等待gdb的链接。接着开启另外一个终端,执行gdb
gdb ./vmlinux
target remote: 1234
hc start_kernel
c
参考@技术简说
https://zhuanlan.zhihu.com/p/105069730?utm_source=wechat_session
https://www.toutiao.com/i6845914458108199436
https://zhuanlan.zhihu.com/p/35180950