庖丁解牛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再編譯即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM