vincent_zhu

导航

庖丁解牛Linux内核分析笔记-1

2019-5-3
主要内容摘自 孟宁《庖丁解牛Linux内核分析》

天下大事必作于细,天下难事必作于易

1.计算机三大法宝

  • 存储程序计算机
  • 函数调用堆栈
  • 中断

2.虚拟一个x86的CPU硬件平台

2.1 虚拟环境搭建

sudo apt-get install qemu # 安装qemu
sudo ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu # 生成qemu-system-i386的符号链接qemu
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.4.tar.xz # 下载linux-3.9.4.tar.xz
# 下载mykernel补丁
wget https://www.raw.github.com/mengning/mykernel/master/mykernel_for_linux3.9.4sc.patch 
xz -d linux-3.9.4.tar.xz
tar -xvf linux-3.9.4.tar
cd linux-3.9.4
patch -p1 < ../mykernel_for_linux3.9.4sc.patch # 添加补丁,注意参数为p1不是pl
make allnoconfig
make # 编译mykernel
qemu -kernel arch/x86/boot/bzImage

2.2使用mykernel编写时间片轮转多道程序内核

1.mykernel相关文件

  • mypcb.h
  • mymain.c
  • myinterrupt.c

2.使用gdb调试内核

gdb # 运行gdb
# 在gdb程序中,输入:
file linux3.9.4/vmlinux # 加载符号表
target remote:1234 # 建立连接
break start_kernel # 插入断点

3.MenuOS的构造

3.1 Linux内核源代码简介

操作系统两把“宝剑”

  • 中断上下文
  • 进程上下文

使用版本:linux-3.18.6

内核分析中重要的文件:

  • arch/x86
  • init/main.c
  • kernel

linux readme

  • what is linux?
  • on what hardware does it run?
  • documentation
  • installing the kernel source
  • software requirements
  • build directory for the kernel
  • configuring the kernel
  • compiling the kernel
  • if something goes wrong
  1. 编译安装内核大概步骤
    (1) 安装开发包组
    (2) 下载源码文件
    (3) .config:准备内核选项
    (4) make menuconfig:配置内核选项
    (5) make [-j #]
    (6) make modules_install:安装模块
    (7) make install:安装内核相关文件
    (8) 安装bzImage为/boot/vmlinuz-VERSION_RELEASE
    (9) 生成initramfs文件
    (10) 编辑grub的配置文件

2.编译配置选项
(1) 配置内核选项
(2) 支持“更新”模式进行配置:make help

  • make config:在命令行中以遍历的方式去配置内核中可配置的每一个选项。
  • make menuconfig:基于curses的文本窗口界面
  • make gconfig:基于GTK(GNOME)环境窗口界面
  • make xconfig:基于QT(KDE)环境的窗口界面
    (3) 支持“全新配置”模式进行配置
  • make defconfig:基于内核为目标平台提供的默认配置进行配置
  • make allyesconfig:所有选项回答为"yes"
  • make allnoconfig:所有选项回答为"no"

3.编译
make [-j #] : 全部编译

3.2 构造一个简单的Linux内核

编译、运行、跟踪源代码
MenuOS:由Linux内核和该文件系统集成

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

解释
qemu: 仿真kernel的虚拟机;
bzImage:vmLinux经过gzip压缩后的文件,是压缩的内核映像,'b'表示'big'(bzImage适用于大内核,zImage适用于小内核);
vmLinux:编译出来的最原始的内核ELF文件;
根文件系统:一般包含内存根文件和磁盘文件系统
initrd:是“initial ramdisk”简写,普通用户一般感受不到这个内存根文件系统的存在,因为普通Linux在启动时,是boot loader将存储介质中的initrd文件加载到内存,内核启动时先访问initrd文件系统(内存根文件系统),然后再切换到磁盘文件系统。为简化实验只使用了initrd根文件系统

(1)下载内核源代码并解压

wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz
xz -d linux-3.18.6.tar.xz
tar -xvf linux-3.18.6.tar
cd linux-3.18.6
make i386_defconfig
make

(2)制作根文件系统(返回上级目录)

mkdir rootfs
git clone https:/github.com/mengning/menu.git
cd menu
gcc pthread -o init linkable.c menu.c test.c -m32 -static
cd ../rootfs
cp ../menu/init ./ # 将init复制到rootfs下
find . | cpio -o -Hnewc | gzip -9 > ../rootfs.img # 把当前rootfs下的所有文件打包成一个镜像文件

配置内核编译选项出现的问题

zgd@zgd-ThinkPad-X260:~/kernel/linux-3.18.6$ make menuconfig
  HOSTLD  scripts/kconfig/mconf
/usr/bin/ld: scripts/kconfig/zconf.tab.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
scripts/Makefile.host:100: recipe for target 'scripts/kconfig/mconf' failed
make[1]: *** [scripts/kconfig/mconf] Error 1
Makefile:541: recipe for target 'menuconfig' failed
make: *** [menuconfig] Error 2

原因及解决方法
原因:gcc版本太高,ubuntu18自带gcc版本为7.4,高版本gcc默认开启-fPIC(Position independent code)支持动态库的重定位
方法:安装gcc-4.8,生成新的/usr/bin/gcc链接,重新配置menuconfig再编译即可

posted on 2019-05-03 20:24  vincent_zhu  阅读(1902)  评论(0编辑  收藏  举报