20135302魏靜靜——linux課程第三週實驗及總結

linux課程第三週實驗及總結

1、實驗:跟蹤分析Linux內核的啓動過程

  1. cd LinuxKernel/
  2. qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

內核啓動完成後進入menu程序(《軟件工程C編碼實踐篇》的課程項目),支持三個命令help、version和quit,您也能夠添加更多的命令,對選修過《軟件工程C編碼實踐篇》的童鞋應該是a piece of cake.html

  • 使用gdb跟蹤調試內核
  1. qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 關於-s和-S選項的說明:
  2. # -S freeze CPU at startup (use ’c’ to start execution)
  3. # -s shorthand for -gdb tcp::1234 若不想使用1234端口,則可使用-gdb tcp:xxxx來取代-s選項
  • 另開一個shell窗口
  1. gdb
  2. (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote以前加載符號表
  3. (gdb)target remote:1234 # 創建gdb和gdbserver之間的鏈接,按c 讓qemu上的Linux繼續運行
  4. (gdb)break start_kernel # 斷點的設置能夠在target remote以前,也能夠在以後

實驗過程分析

  • Linux內核的啓動過程

        啓動Linux內核的三個參數:linux

    • kernel
    • initrd
    • root所在分區、目錄
qemu -kernel (文件名) -initrd (rootfs.img)
  1. qemu至關於打開一個虛擬機
  2. kernel啓動一個內核,位置由其後的文件名指定。若是在當前目錄下,能夠直接輸入文件名,若是不是,則須要輸入該內核的全路徑。
  3. initrd指令是掛了一個ramdisk虛擬硬盤,是內核的重要補充,rootfs.img就是這個虛擬硬盤,內有分區,而後啓動的實際上是其中的init文件,這個文件是由以前的menuOS編譯而成,gcc -o命名爲init。

0號進程
有一個全局變量init_task,即手工建立的PCB,0號進程,即最終的idle進程。0號進程一直存在,系統沒有進程須要執行時調度到0號進程。nginx

init_process 是默認的一號進程git

  • 實驗截圖

    1. 運行截圖
      enter description heregithub

    2. 第一個斷點,start_kernel
      enter description hereshell

    3. 實驗目錄bash

      • arch目錄
        佔有至關龐大的空間
        arch/x86目錄下的代碼是須要重點關注的。
        arch下其餘目錄能夠刪掉。tcp

      • init目錄
        內核啓動相關的基本代碼基本都在init目錄下。
        main.c 文件中有一個start_kernel函數,初始化Linux內核的起點,這個函數至關於普通c程序的main函數。函數

      • kernel目錄
        Linux內核的核心代碼在kernel目錄中ui

      • 其餘
        Documentation 文檔
        drivers 驅動
        fs-filesystem 文件系統
        include
        ipc 進程間通訊

      • README:
        INSTALLING 怎樣安裝內核源代碼——怎麼解壓怎麼打補丁
        make mrproper 把生成的中間代碼清理乾淨
        menuconfig

    4. GDB使用
 gdb (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote以前加載符號表 (gdb)target remote:1234 # 創建gdb和gdbserver之間的鏈接,按c 讓qemu上的Linux繼續運行 (gdb)break start_kernel # 斷點的設置能夠在target remote以前,也能夠在以後
(gdb)c # 系統開始啓動,啓動到start_kernel (gdb)list # 能夠看到start_kernel上下的代碼 (gdb)break rest_init (gdb)c # 當前系統執行到rest_init (gdb)list # 能夠看到rest_init是在start_kernel的尾部調用的。
 5.實驗函數

trap_init() 初始化一些中斷向量
mm_init() 內存管理模塊
sched_init() 調度模塊

                        rest_init()中有kernel_thread(kernel_init,NULL,CLONE_FS),kernel_init中有run_init_process,建立了一號進程,默認路徑下的程序。

2、課程總結

 
 

一、Linux內核啓動過程

  • 計算機的啓動過程概述
    • x86 CPU啓動的第一個動做CS:EIP=FFFF:0000H(換算爲物理地址爲000FFFF0H,由於16位CPU有20根地址線),即BIOS程序的位置。
    • BIOS例行程序檢測完硬件並完成相應的初始化以後就會尋找可引導介質,找到後把引導程序加載到指定內存區域後,就把控制權交給了引導程序。這裏通常是把硬盤的第一個扇區MBR和活動分區的引導程序加載到內存(即加載BootLoader),加載完整後把控制權交給BootLoader。
    • 引導程序BootLoader開始負責操做系統初始化,而後起動操做系統。啓動操做系統時通常會指定kernel、initrd和root所在的分區和目錄,好比root (hd0,0),kernel (hd0,0)/bzImage root=/dev/ram init=/bin/ash,initrd (hd0,0)/myinitrd4M.img
    • 內核啓動過程包括start_kernel以前和以後,以前所有是作初始化的彙編指令,以後開始C代碼的操做系統初始化,最後執行第一個用戶態進程init。
    • 通常分兩階段啓動,先是利用initrd的內存文件系統,而後切換到硬盤文件系統繼續啓動。
      • initrd文件的功能主要有兩個:
      • 一、提供開機必需的但kernel文件(即vmlinuz)沒有提供的驅動模塊(modules)
      • 二、負責加載硬盤上的根文件系統並執行其中的/sbin/init程序進而將開機過程持續下去

二、怎麼編譯內核?

  • 最簡單的是make config,可是這個須要的時間很長
  • make menuconfig,是圖形化的界面,比上面更爲方便
  • make allnoconfig,全部能選no的都選no,簡單粗暴。
  • Makefile和config
    這兩個和在一塊兒可以決定內核中哪些須要被編譯,哪些不會被編譯。

 
參考連接:

詳細實驗過程介紹及分析http://www.cnblogs.com/20135202yjx/p/5262907.html

相關文章
相關標籤/搜索