linux kernel调试


linux启动流程

POST-->BIOS-->MBR-->bootloader-->kernel-->initrd-->/sbin/init-->/etc/init.d/rcS

kernel

linux-2.6.39内核版本为例:php

// 源码下载
wget https://mirror.tuna.tsinghua.edu.cn/kernel/v2.6/linux-2.6.39.tar.xz
// 编译
make menuconfig
make

生成vmlinux可执行文件,和arch/x86/boot/bzImage
bzImagevmlinx的压缩文件,即vmlinuzlinux

busybox

// 源码下载
wget https://busybox.net/downloads/busybox-1.30.1.tar.bz2
// 编译
make menuconfig
make
make install

uclibc

// 源码下载
 wget https://uclibc.org/downloads/uClibc-0.9.33.tar.xz
 // 编译
 make menuconfig
 make
 sudo make install

initrd

mkdevs.sh

#!/bin/bash

if [ -z "$1" ]; then
    echo "usage: `basename $0` dir"
    exit 1
fi

if [[ $1 =~ "/dev" ]]; then
    DEV_DIR=$1
else
    DEV_DIR=$1/dev
fi

PRE_DIR=`pwd`
mkdir -p $DEV_DIR
cd $DEV_DIR

echo -n "make devs into $DEV_DIR ... "

# misc devs
mknod mem       c 1 1
mknod kmem      c 1 2
mknod null      c 1 3
mknod port      c 1 4
mknod zero      c 1 5
mknod full      c 1 7
mknod random    c 1 8
mknod urandom   c 1 9
mknod console   c 5 1

# ttys
mknod tty c 5 0
for i in `seq 0 9`; do
	mknod tty$i c 4 $i
done

# rams
for i in `seq 0 9`; do
	mknod ram$i b 1 $i
done

# loops
for i in `seq 0 7`; do
	mknod loop$i b 7 $i
done

# vcs
# virtual console screen devs
for i in `seq 0 9`; do
	mknod vcs$i b 7 $i
done
ln -s vcs0 vcs

# vcsa
# virtual console screen attributes devs
for i in `seq 0 9`; do
	mknod vcsa$i b 7 $((128 + i))
done
ln -s vcsa0 vcsa

cd $PRE_DIR
echo "done"

mkrootfs.sh

#!/bin/bash

BUSYBOX_DIR="./busybox"
UCLIBC_DIR="./uClibc"
KERNEL_DIR="./linux-2.6.39"

ROOTFS_DIR="./rootfs"
INITRD="rootfs.gz"

BASE_DIR=`pwd`

rm -r $ROOTFS_DIR
mkdir -p $ROOTFS_DIR
# dev
mkdir -p $ROOTFS_DIR/dev
./mkdevs.sh $ROOTFS_DIR
# sbin bin usr/sbin usr/bin
cp -r $BUSYBOX_DIR/_install/*  $ROOTFS_DIR
# etc
cp -r $BUSYBOX_DIR/examples/bootfloppy/etc  $ROOTFS_DIR

cd $ROOTFS_DIR
# proc
mkdir proc
# sys
mkdir sys
# init
ln -s bin/busybox init
# initrd
echo "make initrd=$BASE_DIR/$INITRD"
find . | cpio -H newc -o | gzip -9 > $BASE_DIR/$INITRD

cd $BASE_DIR
echo "make rootfs done."

/etc/fstab

# fs    dir     type    options     dump    pass
proc    /proc   proc    defaults    0       0
sysfs   /sys    sysfs   defaults    0       0

执行sudo ./mkrootfs.sh后,会在当前目录下产生rootfs.gz(即咱们须要的initrd.img),rootfs目录下ls以下ios

bin  dev  etc  init  proc  sbin  sys usr

qemu

// 源码下载
wget https://download.qemu.org/qemu-4.0.0.tar.xz
// 依赖
sudo apt get install libsdl2-dev
sudo apt get install libncurses5-dev
sudo apt get install libncursesw5-dev
// 编译
mkdir build
cd build
../configure --target-list=x86_64-softmmu
make
sudo make install
// 运行
qemu-system-x86_64 -kernel bzImage -initrd rootfs.gz -nographic -append "console=ttyS0" -s -S
// 退出
Ctrl-a x

gdb

gdb调试时报错
Remote ‘g’ packet reply is too long
此问题须要下载gdb源码,修改源码编译安装。
gdb/remote.c文件中web

if (buf_len > 2 * rsa->sizeof_g_packet)
    error (_("Remote 'g' packet reply is too long: %s"), rs->buf);

更换为bash

if (buf_len > 2 * rsa->sizeof_g_packet) {
    rsa->sizeof_g_packet = buf_len;
    for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
    {
        if (rsa->regs[i].pnum == -1)
            continue;
        if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
            rsa->regs[i].in_g_packet = 0;
        else
            rsa->regs[i].in_g_packet = 1;
    }
}
// 源码下载
wget https://mirror.tuna.tsinghua.edu.cn/gnu/gdb/gdb-8.3.tar.xz
// 编译
./configure
make
sudo make install

安装gdb时若是报错app

WARNING: `makeinfo' is missing on your system.  You should only need it if
         you modified a `.texi' or `.texinfo' file, or any other file
         indirectly affecting the aspect of the manual.  The spurious
         call might also be the consequence of using a buggy `make' (AIX,
         DU, IRIX).  You might want to install the `Texinfo' package or
         the `GNU make' package.

需安装texinfo,如Debian/Ubuntu系统,sudo apt install texinfo便可dom

gdb调试vmlinuxssh

gdb
file vmlinux
target remote localhost:1234
b start_kernel
b rest_init
c
n

syslinux

// 源码下载
wget https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/6.xx/syslinux-6.03.tar.xz
// 编译
sudo apt install nasm
sudo apt install uuid-dev
make

isolinux.cfg

display “Welcome to linux!”
default linux
timeout 10
prompt 1
label linux
	kernel /boot/vmlinuz
	append initrd=/boot/initrd.img

mkisolinux.sh

#!/bin/bash

KERNEL_DIR="./linux-2.6.39"
SYSLINUX_DIR="./syslinux-6.0.3"
TARGET_DIR="syslinux"
TARGET="linux.iso"

mkdir -p $TARGET_DIR
mkdir -p $TARGET_DIR/isolinux
mkdir -p $TARGET_DIR/boot
cp $KERNEL_DIR/arch/x86/boot/bzImage $TARGET_DIR/boot/vmlinuz
cp rootfs.gz $TARGET_DIR/boot/initrd.img
cp $SYSLINUX_DIR/bios/core/isolinux.bin $TARGET_DIR/isolinux/
cp $SYSLINUX_DIR/bios/com32/elflink/ldlinux/ldlinux.c32 $TARGET_DIR/ioslinux/
#cp isolinux.cfg $TARGET_DIR/isolinux/

mkisofs -J -o $TARGET -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table $TARGET_DIR
echo "mkisofs done."

wiki

https://wiki.syslinux.org/wiki/index.php?title=ISOLINUXsvg