- 디버깅을 통해서 배우는 리눅스 커널의 구조와 원리
- xv6
$ uname -a
Linux good-VirtualBox 5.3.0-59-generic #53~18.04.1-Ubuntu SMP Thu Jun 4 14:58:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/apt/sources.list | grep -v "#"
deb http://kr.archive.ubuntu.com/ubuntu/ bionic main restricted
deb http://kr.archive.ubuntu.com/ubuntu/ bionic-updates main restricted
deb http://kr.archive.ubuntu.com/ubuntu/ bionic universe
deb http://kr.archive.ubuntu.com/ubuntu/ bionic-updates universe
deb http://kr.archive.ubuntu.com/ubuntu/ bionic multiverse
deb http://kr.archive.ubuntu.com/ubuntu/ bionic-updates multiverse
deb http://kr.archive.ubuntu.com/ubuntu/ bionic-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu bionic-security main restricted
deb http://security.ubuntu.com/ubuntu bionic-security universe
deb http://security.ubuntu.com/ubuntu bionic-security multiverse
$ uname -a
Linux good-VirtualBox 5.3.0-59-generic #53~18.04.1-Ubuntu SMP Thu Jun 4 14:58:26 UTC 2020 x86_64
$ sudo apt install git bc bison flex libssl-dev make
$ mkdir ~/code && cd ~/code
$ git clone --depth=1 --branch rpi-4.19.y https://github.com/raspberrypi/linux
# wget https://downloads.raspberrypi.org/raspios_lite_armhf_latest.zip
# unzip raspios_lite_armhf_latest.zip
$ sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev
$ git clone https://github.com/raspberrypi/tools ~/tools
$ echo PATH=\$PATH:~/tools/arm-bcm2708/arm-linux-gnueabihf/bin >> ~/.bashrc
$ echo export KERNEL=kernel7 >> ~/.bashrc
$ source ~/.bashrc
$ vi env.sh
#!/bin/sh
export PATH=~/tools/arm-bcm2708/arm-linux-gnueabihf/bin:$PATH
export KERNEL=kernel7
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
$ cd ~/code/linux
$ KERNEL=kernel
# For Pi 1, Pi Zero, Pi Zero W, or Compute Module:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig
# For Pi 2, Pi 3, Pi 3+, or Compute Module 3:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
# For Raspberry Pi 4:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig
# all platform
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
$ cat ~/code/linux/build.sh
#!/bin/sh
OUTPUT="~/code/out"
KERNEL=kernel7
make ARCH=arm O=$OUTPUT CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
make ARCH=arm O=$OUTPUT CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j3
$ make menuconfig
Kernel hacking --> Compile-time checks and compiler option -->
Compile the kernel with debug info --> Enable
Generate dwarf4 debuginfo --> Enable
Provide GDB scripts for kernel debuffing--> Enable
$ build.sh
# 커널과 device tree 파일 추출
$ ~/code/linux/scripts/mkknlimg arch/arm/boot/zImage ~/rpi3/kernel7.img
$ cp arch/arm/boot/dts/bcm2709-rpi-2-b.dtb ~/rpi3
$ vi ~/rpi3/run_qemu.sh
#!/bin/sh
BOOT_CMDLINE="rw earlyprintk loglevel=8 console=ttyAMA0,115200 console=tty1 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2"
DTB_FILE="bcm2709-rpi-2-b.dtb"
KERNEL_IMG="kernel7.img"
SD_IMG="raspbian-jessie.img"
echo "target remote localhost:1234"
qemu-system-arm -s -S -M raspi2 \
-kernel ${KERNEL_IMG} \
-sd ${SD_IMG} \
-append "${BOOT_CMDLINE}" \
-dtb ${DTB_FILE} -serial stdio
$ source env.sh
$ cd ~/kernel/linux/
$ ddd --debugger arm-linux-gnueabihf-gdb ./vmlinux
# GDB shell에서 target remote localhost:1234 명령을 친다.
(gdb) target remote localhost:1234
# start_kernel 에 브레이크 포인트 셋팅
(gdb) b start_kernel
# 디버깅 시작.
(gdb) c
$ ls -l ~/code/out/arch/arm/boot/dts/bcm2709-rpi-2-b.dtb
-rw-r--r-- 1 good good 25334 6월 20 00:53 ~/code/out/arch/arm/boot/dts/bcm2709-rpi-2-b.dtb
$ ls -l ~/code/out/arch/arm/boot/zImage
-rwxr-xr-x 1 good good 5470168 6월 20 01:01 ~/code/out/arch/arm/boot/zImage
$ ls -l ~/code/out/arch/arm/boot/zImage
-rwxr-xr-x 1 good good 5470168 6월 20 01:01 ~/code/out/arch/arm/boot/zImage
$ vi ~/git/pi2/run_qemu.sh
#!/bin/sh
BOOT_CMDLINE="rw earlyprintk loglevel=8 console=ttyAMA0,115200 console=tty1 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2"
DTB_FILE="bcm2709-rpi-2-b.dtb"
KERNEL_IMG="kernel7.img"
SD_IMG="raspbian-jessie.img"
echo "target remote localhost:1234"
qemu-system-arm -s -S -M raspi2 \
-kernel ${KERNEL_IMG} \
-sd ${SD_IMG} \
-append "${BOOT_CMDLINE}" \
-dtb ${DTB_FILE} -serial stdio
$ source env.sh
$ cd ~/code/linux/
$ ddd --debugger arm-linux-gnueabihf-gdb ./vmlinux
# GDB shell에서 target remote localhost:1234 명령을 친다.
(gdb) target remote localhost:1234
# start_kernel 에 브레이크 포인트 셋팅
(gdb) b start_kernel
# 디버깅 시작.
(gdb) c
root@raspberry:~# raspi-config
[*] en_GB.UTF-8
[*] en_US.UTF-8 UTF-8
[*] ko_KR.UTF-8 UTF-8
한글 폰트 설치
# apt-get update
# apt-get upgrade
# apt-get install ibus
# apt-get install ibus-hangul
# apt-get install korean *
$ git clone https://github.com/0xabu/qemu.git -b raspi
$ git submodule update --init dtc
$ ./configure
$ make -j$(nproc)
$ sudo make install
$ wget http://downloads.raspberrypi.org/raspbian/images/raspbian-2015-11-24/2015-11-21-raspbian-jessie.zip
$ sudo /sbin/fdisk -lu 2015-11-21-raspbian-jessie.img
Disk 2015-11-21-raspbian-jessie.img: 3.7 GiB, 3934257152 bytes, 7684096 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xea0e7380
Device Boot Start End Sectors Size Id Type
2015-11-21-raspbian-jessie.img1 8192 131071 122880 60M c W95 FAT32 (LBA)
2015-11-21-raspbian-jessie.img2 131072 7684095 7553024 3.6G 83 Linux
- P0의 start 주소는 8192, Sector size 512
- Offset 계산: 8192 * 512 = 4194304
$ mkdir tmp
$ sudo mount -o loop,offset=4194304 2015-11-21-raspbian-jessie.img tmp
$ mkdir 2015-11-21-raspbian-boot
$ cp tmp/kernel7.img 2015-11-21-raspbian-boot
$ cp tmp/bcm2709-rpi-2-b.dtb 2015-11-21-raspbian-boot