Configure VSCode
-
Install the VSCode plugins C/C++ Intellisense and C/C++ Themes. Since the plug-in C/C++ Intellisense requires GNU Global, you also need to install GNUGlobal using the following command.
sudo apt install global
-
Modify the .vscode configuration item, refer to
https://github.com/mengning/linuxkernel/tree/master/src/kerneldebuging,
-
Since the Linux kernel is highly customized, there is no way to make Intellisense prompt normally by configuring includePath, etc. Here, a Python script is used to generate the compile_commands.json file to help Intellisense prompt normally (including header files and macro definitions, etc.). Run the following command directly in the Linux source code directory to generate compile_commands.json.
python ./scripts/gen_compile_commands.py
Install development tools
sudo apt install build-essential sudo apt install qemu # install QEMU# as a virtual machine sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
Download kernel source code
Here it is recommended to go directly to the website to download, there will be some problems with axel
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
Configure kernel options
make defconfig # Default configuration is based on 'x86_64_defconfig' make menuconfig
Enter the following interface
Configure as follows
Kernel hacking ---> Compile-time checks and compiler options ---> [*] Compile the kernel with debug info [*] Provide GDB scripts for kernel debugging [*] Kernel debugging # Turn off KASLR (random address), otherwise the breakpoint will fail. In this way, the debugger can trace the source code. The reason why the random address is set is to prevent hacker attacks: Processor type and features ----> [ ] Randomize the address of the kernel image (KASLR)
Compile and run the kernel
make -j$(nproc) # nproc gives the number of CPU cores/threads available qemu-system-x86_64-kernel arch/x86/boot/bzImage
Kernel panics eventually due to no filesystem
Note: Here you need to comment out my_start_kernel() in the code, otherwise the system will get stuck at this step and will not execute it later
Make a memory root file system
-
download source code
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
-
compile and install
make menuconfig make -j$(nproc) & amp; & amp; make install
Note that it should be compiled into a static link instead of a dynamic link library
Settings ---> [*] Build static binary (no shared libs)
-
Make a memory root file system image
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/
-
Prepare the init script file and put it in the root file system and directory (rootfs/init), add the following content to the init file (note that the execution permission is added to the script)
#!/bin/sh mount -t proc none /proc mount -t sysfs none /sys echo "Wellcome MengningOS!" echo "--------------------" cd home /bin/sh
-
Packaged into a memory root file system image
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
-
Test to mount the root file system to see if the init script is executed after the kernel boot is complete
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz
If the execution is successful, it will display as follows
Trace debugging
(After doing this step, I found that there was a problem with Ubuntu22 debugging, and it was replaced by Ubuntu18 later)
-
Put a breakpoint at start_kernel and start debugging
-
Process number 0 is created here
-
After process 0 is created, it is the kernel initialization work, continue to skip. start_kernel will perform some initialization operations, including initializing various important data structures, drivers, interrupt handlers, etc., and establish some necessary core data structures, such as physical memory manager, virtual memory manager, and process scheduler, etc. , until the last remaining initialization function
-
You can enter the function to see
-
There is another layer inside, enter and you can see that the kernel generates the first real process here (pid=1)
-
After rest_init is executed, start_kernel is all completed
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. CS introductory skill tree Introduction to LinuxFirst acquaintance with Linux28824 people are studying systematically