赞
踩
sudo apt install build-essential
sudo apt install qemu # install QEMU#作为一个虚拟机
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
sudo apt install axel
axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar #解压源码
cd linux-5.4.34
make defconfig # Default configuration is based on 'x86_64_defconfig'
make menuconfig# 打开debug相关选项
出现如下界面
修改其中的配置:
Kernel hacking --->
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[*] Provide GDB scripts for kernel debugging
[*] Kernel debugging
# 关闭KASLR(随机地址),否则会导致打断点失败。这样调试器就可以跟踪到源代码,之所以设置随机地址为了防止黑客攻击:
Processor type and features ---->
[ ] Randomize the address of the kernel image (KASLR)
make -j$(nproc)
qemu-system-x86_64 -kernel arch/x86/boot/bzImage
出现kernel panic
axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2
tar -jxvf busybox-1.31.1.tar.bz2
cd busybox-1.31.1
修改为静态编译
make menuconfig
编译安装
make -j$(nproc) && make install
:
mkdir rootfs
cd rootfs
cp ../busybox-1.31.1/_install/* ./ -rf
mkdir dev proc sys home
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
将init脚本文件放在根文件系统跟目录下
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "Wellcome YouYouOS!"
echo "--------------------"
cd home
/bin/sh
对proc和sys进行挂载
chmod +x init
将内存根文件系统镜像打包
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
运行
qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd rootfs.cpio.gz
由于 Linux 内核高度定制化,所以没有办法直接通过配置 includePath 等让 Intellisense 正常提示,这里借助一个 Python 脚本来生成 compile_commands.json 文件帮助 Intellisense 正常提示(包括头文件和宏定义等)
python ./scripts/gen_compile_commands.py
在断点里增加函数断点:start_kernel,运行并启动调试
start_kernel函数会执行一系列初始化操作,其中包括初始化各种重要的数据结构、驱动程序、中断处理程序等。在此阶段,内核会创建一些必要的核心数据结构,例如物理内存管理器、虚拟内存管理器以及进程调度器等。
rest_init
start_kernel的结尾是arch_call_reset_init(),这个函数执行了reset_init()函数,进入reset_init函数内部,并且这个函数是由0号进程执行的。在rest_init函数中,内核将通过下面的代码产生第一个真正的进程。
kernel_thread函数是通过_do_fork函数来创建进程的
在新线程(进程)中运行kernel_init()函数, 在kernel_init()函数里面调用了run_init_process函数
kernel_init()最终会通过do_execve系统调用来执行根文件系统下的/sbin/init文件
然后是2号进程的创建,2号进程比所有内核进程最早创建,而kernel_thread创建了2号进程,同时进程执行的函数是kthreadd():
2号进程在不停地查看是否有需要创建的内核进程,如果kthread_create_list不空即有需要创建的内核进程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。