Sunday, April 24, 2011

Linux 內核編譯說明

Linux 內核編譯說明

(http://blog.roodo.com/eshingx/archives/1731986.html)


[內容為個人存檔參考用]

1.Linux內核源碼結構: 
內核源碼中主要包含以下子目錄:
    arch
:包含了與體系結構相關的代碼
對應於每一個支援的體系結構,有一個相應的子目錄如i386armalpha等。
其每個體系結構子目錄下包含幾個主要的子目錄:
    kernel
:包含與體系結構相關的內核代碼
    mm  包含與體系結構相關的記憶體管理代碼
    lib  包含與體系結構相關的庫代碼
    documentation:包含內核的文檔
    drivers :包含設備驅動代碼。每類設備有相應的子目錄,如char blocknet
    fs  包含檔系統的代碼。每個支援的檔系統有相應的子目錄,如 ext2proc
    include :內核頭檔,對每一種體系結構,分別有相應的子目錄。
    init  包含內核初始化代碼
    lib  包含內核的庫代碼
    mm :包含記憶體管理代碼
    kernel :包含內核管理代碼
    net :包含網路部分的代碼 

2.系統引導的過程 
pc機上系統啟動過程:
    系統加電以後bois對系統完成監測設置後將控制權交給硬碟上MBR中的 BootLoader在這裏即是lilogrub等。
    BootLoader 將作業系統代碼調入記憶體,然後將控制權交給arch/i386/boot中的Setup.S這段程式。
    Setup.S 這段程式在386實模式下對系統進行基本的檢測和設置後轉入保護模式把控制權交給Head.S     Head.S 建立記憶體管理和中斷管理的框架後調用init/main.c中的start_kernel()函數在start_kernel執行完成後用戶就可以登錄和使用linux了。Start_kernel()函數在init /main.c 中定義。
 
Start_kernel
的流程中的主要步驟:
    setup_arch(&command_line);
用於和處理器、記憶體等最基本的硬體相關部分的初始化。  arch/i386/kernel/setup.c 中定義;
    parse_options(command_line); 把啟動時得到的參數從命令行的字串中分離出來並賦給相應的變數。在 init/main.c 中定義;
    trap_init(); 對中斷向量表進行初始化。在 arch/i386/kernel/trap.c 中定義;
    init_IRQ(); 與中斷有關的初始化,  arch/i386/kernel/i8259.c 中定義;
    sched_init(); 進程調度初始化。  kernel/sched.c 中定義;
    softirq_init(); kernel/softirq.c 中定義;
    time_init(); 時間部分初始化。  arch/i386/kernel/time.c 中定義;
    console_init(); 對終端初始化。  drivers/char/tty_io.c 中定義;
    buffer_init(mempages); 對用於指示塊緩存的buff free list 初始化。 fs/buffer.c 中定義;
    mem_init(); 記憶體管理初始化。  arch/i386/mm/init.c中定義;
    rest_init(); 此函數中調用
    kernel_thread(init,NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)函數時會調用init/main.c中的init()函數 init()函數中將會建立dbflushkswapd兩個新的內核線程。初始化tty1設備。尋找/etc/init/sbin/init /bin/init來建立一個init進程。
Init
進程根據/etc/inittab檔進行檔系統檢查、啟動系統守護進程為聯機終端建立getty進程,執行/etc/rc下的命令檔。
此後getty會在終端上顯示login提示符,以等待用戶登錄。

3.
使用make建立內核
    1.使用make menuconfig命令:
使用以下編譯選項:
    Processor type and features --->     (Pentium-Pro/Celeron/Pentium-II) Processor family     (3GB) Maximum Virtual Memory     General setup --->     (ELF) Kernel core (/proc/kcore) format     [*] Kernel support for ELF binaries     File systems --->     [*] /proc file system support     [*] Second extended fs support     ATA/IDE/MFM/RLL support --->     [*] ATA/IDE/MFM/RLL support     [*] Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support     [*] Include IDE/ATA-2 DISK support     Character devices --->     [*] Virtual terminal     Console drivers --->     [*] VGA text console
生成內核bzImage 大小為 309892 byte; 此內核可在pc上成功引導系統
此命令生成一個檔 .config 其中根據你在menuconfig中的選擇定義了相應的變數。在Makefile檔中將會包含這個檔。

2.
使用make dep命令 建立依賴關係。

3.
使用make bzImage 命令建立內核。
    如設置正確將在arch/i386/boot/目錄下生成內核bzImage

4.make bzImage
的流程簡單說明
    當我們使用make命令時,make程式將首先找到當前目錄下的Makefile檔。根據Makefile檔的語法進行處理。
    在主Makefile檔中包含了arch/i386/Makefile我們make的目標bzImage即在該檔中定:
    bzImage: vmlinux     @$(MAKEBOOT) bzImage #此命令將解釋為:make -C arch/i386/boot bzImage 現在make需要先去建立目標 vmlinux 然後再執行 arch/i386/boot/ 目錄下的 make bzImae。我們現在假設vmlinux目標已生成,則 arch/i386/boot目錄下的make程式將執行如下操作:
    tools/build -b bbootsect bsetup compressed/bvmlinux.out ./ bzImage 即將vmlinux tools/build工具壓縮成目標檔 bzImage(在此過程中,還會構建build 程式,將vmlinux轉換成bvmlinux.out等,可參考tools compressed目錄下的Makefile檔)。
生成vmlinux目標:
在主目錄下Makefile檔中vmlinux生成規則如下:
    vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs     $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \     --start-group \     $(CORE_FILES) \     $(DRIVERS) \     $(NETWORKS) \     $(LIBS) \     --end-group \     -o vmlinux #生成vmlinux     $(NM) vmlinux |grep –v \(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)    \|\(LASH[RL]DI\) | sort > System.map #此命令根據vmlinux生成System.map文件
在當前設置下此ld連接命令被解釋為:
    ld -m elf_i386 -T /home/arm/linux/arch/i386/vmlinux.lds -e stext arch/i386/kernel/head.o arch/i386/kernel/init_task.o init/main.o init/version.o --start-group     arch/i386/kernel/kernel.o arch/i386/mm/mm.o kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o drivers/char/char.o drivers/block/block.o drivers/misc/misc.o drivers/net/net.o drivers/media/media.o drivers/ide/idedriver.o drivers/video/video.o net/network.o /home/arm/linux/arch/i386/lib/lib.a /home/arm/linux/lib/lib.a /home/arm/linux/arch/i386/lib/lib.a --end-group -o vmlinux
即連接程式ld 將各個.o檔連接成目標檔 vmlinux
此命令中用到的各個 .omake程式會根據Makefile檔的規則去自動生成,下面簡單介紹一下由ipc目錄生成ipc.o過程:
ipc目錄下Makefile檔內容如下:
    O_TARGET := ipc.o     obj-y := util.o     obj-$(CONFIG_SYSVIPC) += msg.o sem.o shm.o     include $(TOPDIR)/Rules.make #包含的Rules.make檔中為通用的規則;
如我們在make menuconfig時選中了SYSVIPC選項,則 .config檔中將定義變數 CONFIG_SYSVIPC=y; objy 就等於util.o msg.o sem.o shm.o;根據Rules.make將四個.c檔編譯為 .o文件。再將四個.o檔連接成 ipc.o文件。在我們的當前設置中沒有選擇SYSVIPC;將只使用util.o一個檔生成目標 ipc.o ;而util.outil.c生成。
    當所有需要的.o檔生成以後,由ld將其連接生成vmlinux檔,再將其壓縮成我們所需要的內核檔 bzImageMake程式就執行完了。

No comments:

Post a Comment