Article directory
- Compile the kernel
- make root file
- Use gdb to debug
- Configure vscode debugging
- reference article
Compile the kernel
- 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
- Decompress the source code:
tar -xvf linux-5.4.34.tar
- Configure the kernel
make defconfig # Default configuration is based on 'x86_64_defconfig' make menuconfig# Open debug related options
Kernel hacking ---> Compile-time checks and compiler options ---> [*] Compile the kernel with debug info [*] Provide GDB scripts for kernel debugging [*] Kernel debugging#Close 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 the kernel
make -j$(nproc) # nproc gives the number of CPU cores/threads available # Test whether the kernel can be loaded and run normally, because there will be a kernel panic without a file system qemu-system-x86_64 -kernel arch/x86/boot/bzImage
Make root file
- Upload busybox-1.32.0.tar.bz2
- Decompression:
tar -jxvf busybox-1.32.0.tar.bz2
- cut directory
- Configuration file:
make menuconfig
Settings ->
[*] Build static binary (no shared libs) static compilation
- Compile and install:
make -j6 & amp; & amp; make install
- Make a memory root file image:
- File Directory
cd /home/song/workdir/linux-5.4.34 mkdir rootfs cd rootfs cp /home/song/workdir/busybox-1.32.0/_install/* ./ -rf mkdir dev proc sys home sudo cp -a /dev/{<!-- -->null,console,tty,tty1,tty2,tty3,tty4} dev/
- Prepare init file
#!/bin/sh mount -t proc none /proc mount -t sysfs none /sys echo "Welcome Songlw'OS!" echo "--------------------" cd home /bin/sh
- Add permissions:
chmod + x init
- Packaged into a mirror file:
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
- implement
cd /home/song/workdir/linux-5.4.34 qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd rootfs.cpio.gz
Execute the init file and output Welcome Songlw’OS!
Use gdb to debug
- implement:
qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s #Where -S means Stopped, -s provides a debug port tcp:1234 for gdb.
- Open another terminal and enter the command:
gdb vmlinux
- Perform gdb debugging:
(gdb) target remote:1234 //This is to establish a connection through the previously reserved tcp:1234
(gdb) b start_kernel //This is the first breakpoint set
c, bt, list, next, step… //Check the gdb command for details
Configure VScode debugging
-
Install VScode
-
Install plug-ins: plug-ins C/C ++ Intellisense and C/C ++ Themes, GDB Debug, also need to use the following command to install GNU Global.
sudo apt install global
. -
Execute the command in the Linux directory:
python3 ./scripts/gen_compile_commands.py
to generate a compile_commands.json file to help Intellisense prompt normally (including header files and macro definitions, etc.). -
Open the linux-5.4.34 folder
!](https://img-blog.csdnimg.cn/073114e03dbe4d559c9d61ee93d89d37.png#pic_center) -
configuration.vscode
-
start debugging
-
start_kernel. We saw that process 0 init_task is set as the first process of the entire system (process 0 is created manually, and other processes are created by process 0). When the kernel is booted, init_task will be created and started. It is all other The starting point of the process. start_kernel will continue to perform some initialization operations, including initializing various important data structures, drivers, interrupt handlers, etc. At this stage, the kernel will establish some necessary core data structures, such as physical memory manager, virtual memory manager, and process scheduler. The end of start_kernel is arch_call_reset_init(). The definition of this function is to execute the reset_init() function, so we set a function breakpoint “reset_init”.
-
reset_init: Called kernel_thread to create a new kernel thread
-
kernel_thread creates a new kernel thread and finds that the kernel_thread function creates a process through the _do_fork function.
-
The _do_fork function mainly completes calling copy_process() to copy the parent process, calling wake_up_new_task to add the child process to the ready queue to wait for scheduling execution, etc.
-
kernel_init: Run the kernel_init() function in a new thread (process), click on the kernel_init() function, you can see that the run_init_process function is called in this. There are three ifs in total, the first two click on ramdisk_execute_command and execute_command
ramdisk_execute_command can be specified in environment variables via uboot. execute_command is also a global char pointer variable, and the value can also be passed through u-boot.
So if these two have no value, try to jump to /sbin/init, /etc/init, /bin/init, /bin/sh in order to start the init program in user space. The run_init_process function uses the do_execve function
![v
Reference article
- https://blog.csdn.net/double113217/article/details/129614177
- Course PPT