1.Linux內核源碼結構: 內核源碼中主要包含以下子目錄: arch :包含了與體系結構相關的代碼 對應於每一個支持的體系結構,有一個相應的子目錄如i386、arm、alpha等。 其每個體系結構子目錄下包含幾個主要的子目錄: kernel :包含與體系結構相關的內核代碼 mm : 包含與體系結構相關的內存管理代碼 lib : 包含與體系結構相關的庫代碼 documentation:包含內核的文檔 drivers :包含設備驅動代碼。每類設備有相應的子目錄,如char 、block、net等 fs : 包含文件系統的代碼。每個支持的文件系統有相應的子目錄,如 ext2、proc等 include :內核頭文件,對每一種體系結構,分別有相應的子目錄。 init : 包含內核初始化代碼 lib : 包含內核的庫代碼 mm :包含內存管理代碼 kernel :包含內核管理代碼 net :包含網絡部分的代碼
2.系統引導的過程 在pc機上系統啟動過程: 系統加電以後bois對系統完成監測設置後將控制權交給硬盤上MBR中的 BootLoader在這裡即是lilo或grub等。 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()函數中將會建立dbflush、kswapd兩個新的內核線程。初始化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 。 此命令中用到的各個 .o文件make程序會根據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; 則obj-y 就等於util.o msg.o sem.o shm.o;根據Rules.make將四個.c文件編譯為 .o文件。再將四個.o文件連接成 ipc.o文件。在我們的當前設置中沒有選擇SYSVIPC;將只使用util.o一個文件生成目標 ipc.o ;而util.o由util.c生成。 當所有需要的.o文件生成以後,由ld將其連接生成vmlinux文件,再將其壓縮成我們所需要的內核文件 bzImage。Make程序就執行完了。