1. 程式人生 > >Linux系統啟動那些事—基於Linux 3.10核心

Linux系統啟動那些事—基於Linux 3.10核心

對於嵌入式平臺ARM平臺,說說其NANDFlash的啟動過程,請先看圖2.2描述的NAND flash中的程式佈局,上電時,首先cpu會自動將自動從NAND flash中拷貝一定程式碼到記憶體中執行,這是任何支援nand方式啟動必須支援的,一般我見到的有2K還有4K的,這部分的程式碼我們將其稱為bootstrap,這個有點類似MBR中的執行程式碼,那部分程式碼是grub的stage1程式碼,bootstrap然後會拷貝bootloader到記憶體中,這個就類似PC中的grub的stage2,這部分程式碼大小是有限的,遇到過32K,128K的bootloade。Bootstrap會將32K或者128K的空間裡的東西拷貝到記憶體中而不管實際的bootloader大小,然後將控制權移交給bootloader,相比bootstrap而言,bootloader發揮的空間較大了,它會讀取一個叫ptb裡的內容,這裡存的是分割槽資訊,根據nand的儲存特點記錄app,kernel…bootstrap的大小,其實各部分的block,page的資訊,然後bootloader將這些內容統統拷貝到記憶體中,至於拷貝到記憶體中的地址各個平臺的差異性就比較大了,不像PC載入核心到記憶體中的地址是固定的。


圖1.2.1嵌入式ARM啟動流程

Uboot主要還是為kernel服務的,所以它準備好外部環境後將控制權交給kernel,其實轉交過程就是jump,並且會將相關的資訊傳遞給核心,比如裝置樹表的地址,kernel部分的程式碼然後開始執行,主要系統初始化工作還是在startkernel中完成的,例如會解析命令,然後還有一個重要動作,那就是解析裝置樹,並使用一個連結串列將其串接在一塊,在後續驅動註冊的probe方法中會用到這個連結串列,3.10的核心是這麼處理裝置的。接著一系列的初始化,初始化的工作交給一個核心執行緒完成,該執行緒會執行/sbin/init的內容,這個內容就涉及到根檔案系統了,在PC情況下就是initrd了,ARM下initramfs了,這裡需要說明的是init並不屬於核心,為了保持核心的精簡,底層服務搭建好了以後,初始化任務還是交給了使用者空間去完成了,最後啟動shell,至此PC下的任務完成了,嵌入式下會把需要的應用,即app裡的內容放在init裡去載入,或者init下呼叫另一個去載入。至此整個載入過程就完畢了。


圖1.2.2NAND Flash中所有的佈局

本文會講解兩種架構下的啟動流程,各個階段對用的概念是一樣的,如grub等價於uboot,PC下的initrd對應於嵌入式的根檔案系統等,到Linux啟動時,他們的程式碼概念上都是一樣的,如建立頁表、中斷等。

MBR& grub

Linux核心啟動時的一些資訊就是MBR和bootloader給的,那麼就先將講的MBR的分割槽資訊吧,bootloader和核心都會依賴分割槽,因為分割槽資訊指明瞭程式碼在儲存介質上的分佈資訊,一些操作依賴於該分割槽資訊,比如,核心在哪裡,一般在/boot分割槽,這些分割槽資訊在安裝作業系統格式化磁碟時就會存在,或者新的硬碟的格式化,也會有分割槽資訊存在裡面。這裡使用的兩個命令查看了硬碟的分割槽情況,在MBR中有該分割槽資訊。


圖2.1.1 分割槽資訊


由fdisk命令可以知道系統共兩個分割槽一個硬碟,通常第一塊硬碟被稱為sda,第二塊硬碟被稱為sdb,表示我的系統有一塊硬碟,兩個分割槽,/sda1和/sda2,其中/sda1是boot分割槽(星號),/sda2是LVM型別的分割槽,一個邏輯管理,適用於需要動態調整大小的場合。從df命令可以看出/boot分割槽的確掛在/dev/sda1下。前面的device.map檔案(boot/grub/):下的(hd0)    /dev/sda,也就不難理解了,/sda表示整個第一塊硬碟。如果有興趣可以使用dd if=/dev/sda1 of=XXX bs=512 count=1, od-x XXX 檢視第一個扇區的內容。最後一個必然是aa55,因為這是一個合法的mbr的必然資訊,前面是grub的stage1,後面是分割槽資訊,每個分割槽16個位元組,由於我的盤只有兩個分割槽,所以aa55的前面會有那麼多零是正常的,關於mbr的分析,如果感興趣自己查查,這裡講篇幅留給其它更有意義的部分吧。


2.1.2MBR內容

好了,接下來正式進入grub2,grub在2014年就一直沒有跟新過了,但uboot更新可真是勤快啊,建議按照這個步驟先做一下,有點成就感,這樣會有信心往下走,而且PC應該不難找到,找個虛擬機器就可以試,在弄個snapshot就不用擔心繫統壞掉了。先來一個grub2的啟動介面:


2.1.3 grub啟動介面

1、  首先去gnu的官網下載一個grub-1.97.2.tar.gz原始碼包,地址

2、  解壓 tar xvzfgrub.1.97.2.tar.gz

3、  進入解壓後目錄 cdgrub-1.97.2

4、  配置grub, ./configure

5、  編譯 make

6、  安裝grub-install/dev/sda

7、  更新grub grub2-mkconfig-o /boot/grub/grub.cfg,這裡的grub.cfg和原來grub.conf的作用是一樣的,該命令會根據/boot下的kernel image和initrd資訊生成啟動資訊。如果是Ubuntu下,需要使用update-grub/dev/sda命令

8、  reboot重啟可以看到該系統啟動grub的資訊。

下面就來說說grub的啟動步驟吧:

1、Bios將MBR中的512B東西拷貝到0x7c00處,然後跳至該處執行,然後裝載start模組。這部分程式碼參看/boot/i386/pc/boot.S

2、start模組載入剩餘的grub stage2部分,參看boot/i386/pc/diskboot.S。

3、 grub stage引導CPU保護模式,自解壓並釋放到0x10000開始記憶體處,解壓完成後再拷貝回原來位置,然後呼叫grub_main,見kern/main.c,grub_main初始化系統,載入模組,並進入normal或者rescue模式。GRUB將根據配置檔案grub.cfg或者使用者輸入,載入作業系統並執行作業系統。

在這裡就贅述Makefile以及映象檔案的連結關係等相關的內容了,這方面的知識會在核心映像生成過程中體現出來。針對越來越大的硬碟儲存容量,開始出現了GTP取代MBR的趨勢,GTP特性需要EFI特性的支援。

 uboot

一個bootloader應當提供一下功能,

1. Setup and initialise the RAM.

2. Initialise one serial port.

3. Detect the machine type.

4. Setup the kernel tagged list or bdt.

5. Call the kernel image.

對其的介紹和使用這裡就不寫了,網上針對2440的文章可謂氾濫了,自己找找動手實踐一下。

Linux核心映像生成過程

也可以檢視精簡版的連結指令碼的書寫格式。

核心映象一般包括兩個部分,一個部分是針對特定處理器、特定平臺的啟動程式碼,這部分通常被稱為boot程式碼,另一部分就是Linux系統本身,這包括記憶體管理、程序排程、檔案系統、程序間通訊、網路子系統等部分。

如果你查下Linux的程式碼會發現,就arch/(x86,arm)/boot下的內容差別就很大,arch/arm/boot目錄下的內容如下:


圖2.3.1 ARM啟動程式碼目錄

arch/x86/boot下的內容如下:



圖2.3.2 X86啟動程式碼目錄

從上面就可以看出X86的啟動程式碼會比arm的啟動多一些,但是上述關於arm的boot程式碼在arch/arm下還有一個板級的初始化,如s3c2440板級一些工作被放在了,arch/arm/mach-s3c24xx下了。一個核心映像的組成至少包括boot部分和kernel部分,我們暫且這麼定,並且後面無特殊說明,也會boot指cpu和板級的初始化程式碼,kernel指脫離了硬體差別的啟動程式碼。

兩種平臺啟動時,其中一個重要的差別是檔案系統,因為arm通常用於嵌入式系統,其記憶體和Flash相對PC而受限,比較出名的嵌入式檔案系統有yaffs2、jffs2、cramfs,由於工作的關係這裡我們就說ubifs檔案系統了,該檔案系統是新一代為NAND Flash設計的檔案系統,但其本身相對也較大,8M左右。PC架構採用ext3檔案系統。

另一差別在對硬體的處理上,arm採用了裝置樹,arch/arm/boot/dts,並且uboot現在也可以採用裝置方法來解析硬體了。嵌入式裝置對硬體的處理(依賴裝置樹)較PC差異較大。這裡先綜述PC下的啟動流程。

首先來看一個縮略的核心映象vmlinux(kernel部分,非boot)輸入檔案編譯過程,使用的連結指令碼是核心原始碼檔案/arch/x86/kernel/vmlinux.lds。

  1. [[email protected] linux-3.10]# make vmlinux  
  2. HOSTCC  scripts/basic/fixdep  
  3.  HOSTCC  arch/x86/tools/relocs_32.o  
  4.  HOSTCC  arch/x86/tools/relocs_64.o  
  5.  HOSTCC arch/x86/tools/relocs_common.o  
  6.  HOSTLD  arch/x86/tools/relocs  
  7.  CHK    include/generated/uapi/linux/version.h  
  8.  CHK    include/generated/utsrelease.h  
  9.  CC      kernel/bounds.s  
  10.  GEN     include/generated/bounds.h  
  11.  CC     arch/x86/kernel/asm-offsets.s  
  12.  GEN    include/generated/asm-offsets.h  
  13.  CALL    scripts/checksyscalls.sh  
  14.  CC      scripts/mod/empty.o  
  15.  HOSTCC  scripts/mod/mk_elfconfig  
  16.  MKELF   scripts/mod/elfconfig.h  
  17.  CC     scripts/mod/devicetable-offsets.s  
  18.  GEN    scripts/mod/devicetable-offsets.h  
  19.  HOSTCC  scripts/mod/file2alias.o  
  20.  HOSTCC  scripts/mod/modpost.o  
  21.  HOSTCC  scripts/mod/sumversion.o  
  22.  HOSTLD  scripts/mod/modpost  
  23.   HOSTCC  scripts/selinux/genheaders/genheaders  
  24.  HOSTCC  scripts/selinux/mdp/mdp  
  25.  HOSTCC  scripts/kallsyms  
  26.  HOSTCC  scripts/pnmtologo  
  27.  HOSTCC  scripts/conmakehash  
  28.  HOSTCC  scripts/sortextable  
  29.  CC      init/main.o  
  30.  CHK    include/generated/compile.h  
  31.   CC     init/version.o  
  32.  CC      init/do_mounts.o  
  33.  CC      init/do_mounts_initrd.o  
  34.  LD      init/mounts.o  
  35.  CC      init/initramfs.o  
  36.  CC      init/calibrate.o  
  37.  CC      init/init_task.o  
  38.  LD      init/built-in.o  
  39.  HOSTCC  usr/gen_init_cpio  
  40.  GEN     usr/initramfs_data.cpio  
  41.  AS      usr/initramfs_data.o  
  42.  LD      usr/built-in.o  
  43.  LD      arch/x86/crypto/built-in.o  
  44.  CC     arch/x86/kernel/process_32.o  
  45.  CC      arch/x86/kernel/signal.o  
  46.  AS      arch/x86/kernel/entry_32.o  
  47.  CC      arch/x86/kernel/traps.o  
  48. …  
  49.  CHK    include/generated/uapi/linux/version.h  
  50.  UPD    include/generated/uapi/linux/version.h  
  51.  CHK    include/generated/utsrelease.h  
  52.  UPD    include/generated/utsrelease.h  
  53.  CC      kernel/bounds.s  
  54.  GEN     include/generated/bounds.h  
  55.  CC     arch/x86/kernel/asm-offsets.s  
  56.  GEN    include/generated/asm-offsets.h  
  57.  CALL    scripts/checksyscalls.sh  
  58.  CC      scripts/mod/empty.o  
  59.  HOSTCC  scripts/mod/mk_elfconfig  
  60.  MKELF   scripts/mod/elfconfig.h  
  61.  CC      scripts/mod/devicetable-offsets.s  
  62.  GEN    scripts/mod/devicetable-offsets.h  
  63.  HOSTCC  scripts/mod/file2alias.o  
  64.  HOSTCC  scripts/mod/modpost.o  
  65.  HOSTCC  scripts/mod/sumversion.o  
  66.  HOSTLD  scripts/mod/modpost  
  67.  HOSTCC scripts/selinux/genheaders/genheaders  
  68.   HOSTCC  scripts/selinux/mdp/mdp  
  69.  HOSTCC  scripts/kallsyms  
  70.  HOSTCC  scripts/pnmtologo  
  71.  HOSTCC  scripts/conmakehash  
  72.  HOSTCC  scripts/sortextable  
  73.  CC      init/main.o  
  74.  CHK    include/generated/compile.h  
  75.  UPD    include/generated/compile.h  
  76.  CC      init/version.o  
  77.  CC      init/do_mounts.o  
  78.  CC      init/do_mounts_initrd.o  
  79.  CC      init/do_mounts_md.o  
  80.  LD      init/mounts.o  
  81.  CC      init/initramfs.o  
  82.  CC      init/calibrate.o  
  83.  CC      init/init_task.o  
  84.  LD      init/built-in.o  
  85.  HOSTCC  usr/gen_init_cpio  
  86.  GEN     usr/initramfs_data.cpio  
  87.  AS      usr/initramfs_data.o  
  88.  LD      usr/built-in.o  
  89.    CC     arch/x86/kernel/process_32.o  
  90.  CC      arch/x86/kernel/signal.o  
  91.  AS      arch/x86/kernel/entry_32.o  
  92.  CC      arch/x86/kernel/traps.o  
  93.   CC     arch/x86/kernel/irq.o  
  94.  CC      arch/x86/kernel/irq_32.o  
  95.  CC     arch/x86/kernel/dumpstack_32.o  
  96.  CC      arch/x86/kernel/time.o  
  97.  CC      arch/x86/kernel/ioport.o  
  98.  CC      arch/x86/kernel/ldt.o  
  99.  CC     arch/x86/kernel/dumpstack.o  
  100.  CC      arch/x86/kernel/nmi.o  
  101.  CC      arch/x86/kernel/setup.o  
  102.  CC      arch/x86/kernel/x86_init.o  
  103.  CC      arch/x86/kernel/i8259.o  
  104.  CC      arch/x86/kernel/irqinit.o  
  105.  CC     arch/x86/kernel/jump_label.o  
  106.  CC      arch/x86/kernel/irq_work.o  
  107.  CC      arch/x86/kernel/probe_roms.o  
  108.  CC     arch/x86/kernel/i386_ksyms_32.o  
  109.  CC     arch/x86/kernel/syscall_32.o  
  110.  CC      arch/x86/kernel/bootflag.o  
  111.  CC      arch/x86/kernel/e820.o  
  112.  CC      arch/x86/kernel/pci-dma.o  
  113.  CC      arch/x86/kernel/quirks.o  
  114.   CC      arch/x86/kernel/topology.o  
  115.  CC      arch/x86/kernel/kdebugfs.o  
  116.  CC     arch/x86/kernel/alternative.o  
  117.  CC      arch/x86/kernel/i8253.o  
  118.  CC     arch/x86/kernel/pci-nommu.o  
  119.  CC     arch/x86/kernel/hw_breakpoint.o  
  120.  CC      arch/x86/kernel/tsc.o  
  121.  CC      arch/x86/kernel/io_delay.o  
  122.  CC      arch/x86/kernel/rtc.o  
  123. 相關推薦

    Linux系統啟動那些基於Linux 3.10核心

    對於嵌入式平臺ARM平臺,說說其NANDFlash的啟動過程,請先看圖2.2描述的NAND flash中的程式佈局,上電時,首先cpu會自動將自動從NAND flash中拷貝一定程式碼到記憶體中執行,這是任何支援nand方式啟動必須支援的,一般我見到的有2K還有4K的,這部分的程式碼我們將其稱為boots

    Linux系統基礎知識(二)基於linux系統下的用戶管理操作以及文件操作補充

    c99 數據塊 upa 系統數據 精確 passwd 列表 sudo 3.4 1、(思考)系統中為什麽要有用戶 1.1用戶??系統中最底層的安全設定,回收(限制)權利。1.2組??共享權利。分為以下兩種:??(1)附加組:由用戶決定的組(每個用戶不一定都有);??(2)初始

    Linux 系統啟動過程(initrd部分) --- Linux boot process (initrd part)

    原帖:http://blog.csdn.net/ropyn/article/details/2489945 以前一直沒有研究過initrd部分,只是知道linux核心啟動後會首先由引導裝載器讀取initrd映像來啟動ramdisk.它的作用是雞和蛋問題的解決方案,即首

    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU啟動那些(11.3)- FlexSPI NOR連線方式大全(RT1010)

    ----   大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是**恩智浦i.MX RT1010的FlexSPI NOR啟動的連線方式**。   在寫完 [《FlexSPI NOR啟動連線方式(RT1015/1020/1050)》](https://www.cnblogs.com/henj

    Linux系統啟動流程

    linux系統啟動流程Linux系統啟動流程Linux系統啟動流程圖1、加電自檢 上電自檢POST,主要負責檢測系統外圍關鍵設備(如:CPU、內存、顯卡、I/O、鍵盤鼠標等)是否正常, 自檢完成後從BIOS中設置的系統啟動順序來搜索用於啟動系統的驅動器2、grub引導(1)grub引導第一階段(stag

    Linux 系統啟動順序 待細化

    linux 啟動過程Linux 系統啟動順序 待細化用戶打開PC的電源,BIOS開機自檢,按BIOS中設置的啟動設備(通常是硬盤)啟動啟動設備上安裝的引導程序lilo或grub開始引導Linux首先進行內核的引導,接下來執行init程序,init程序調用了rc.sysinit和rc等程序,rc.sysinit

    linux系統啟動流程(CentOS5/6/7為例)

    centos 系統一個操作系統要完整啟動起來需要哪些步驟呢?今天以CentOS為例探索一下linux的啟動流程;一、Linux系統的組成--kernel+rootfs(根文件系統)kernel: 內核,進行進程管理、內存管理、網絡管理、驅動程序、文件系統、安全功能等等rootfs: 根文件系統1.內核設計流派

    linux系統啟動過程具體解釋-開機加電後發生了什麽 --linux內核剖析(零)

    界面 種類 system pos 放置 nlog 提示 mar .com 本文參考了例如以下文章 深入理解linux啟動過程 mbr (主引導記錄(Master Boot Record)) 電腦從開機加電到操作系統main函數之前執行的過程

    Linux系統啟動了流程

    linux開機開機自檢(BIOS)MBR引導(光盤、磁盤)GRUB菜單(選擇內核,一般只有一個內核)加載內核運行init進程,選擇運行級別(Linux的第一個運行程序)讀取/etc/inittab配置文件執行/etc/rc.d/rc.sysinit腳本(系統的初始化腳本,設置主機名和IP地址)執行/etc/r

    linux系統啟動詳解

    oca 3.3 哪些 技術 針對 個性 桌面 inux 解壓縮 要學習linux的命令,我們需要先了解linux系統是如何工作的,這裏我們先了解linux是如何在一臺電腦上啟動加載的!! linux系統啟動過程 第一步、 BIOS初始化 1. BIOS檢測所有的外置

    為什麽要有uboot?帶你全面分析嵌入式linux系統啟動過程中uboot的作用

    統一 一次 fail 進入 是我 臺式機 平板 配置 webp 1.為什麽要有uboot 1.1、計算機系統的主要部件 (1)計算機系統就是以CPU為核心來運行的系統。典型的計算機系統有:PC機(臺式機+筆記本)、嵌入式設備(手機、平板電腦、遊戲機)、單片機(家用電器像

    linux 系統啟動過程分析

    系統root 密碼丟失故障 linux啟動順序主板BIOS加電自檢 檢查硬件--> 讀取硬盤引導扇區(MBR)--> 啟動引導程序(grub)--> 選擇系統--> 加載系統內核(kernel shell)--> 啟動系統讀取相應的默認設置(環境變量,運行級別)--

    linux--系統啟動及安裝過程詳解

    linux啟動先通過一張圖來簡單了解下整個系統啟動的流程,整個過程基本可以分為POST-->BIOS-->MBR(GRUB)-->Kernel-->Init-->Runlevel本文出自 “運維自動化” 博客,請務必保留此出處http://shower.blog.51cto.co

    linux系統啟動過程

    字符 tty 我們 變量 默認 終端 .... 用戶 關聯 初始化進程 會根據字符終端設備,打開getty程序,並關聯在字符終端設備上tty0上 getty打開login 進程 login會讀取用戶信息,查詢出登陸shell 登陸成功,啟動shell,開始讀取shell啟動

    linux學習-Linux系統啟動過程

    linux 關機 mage 模式 服務 關機 win sin class windows系統 linux系統啟動過程 Linux系統的啟動過程並不是大家想象中的那麽復雜,其過程可以分為5個階段: 內核的引導。 運行init。 系統初始化。 建立終端 。 用戶登錄系統。

    Linux入門-8 Linux系統啟動詳解

    傳遞參數 傳遞 sin kernel ima 顯示 root密碼 空格 time 系統啟動流程 BIOS MBR GRUB KERNEL INIT 單用戶修改root密碼 GRUB加密 系統啟動流程 BIOS MBR: Boot Code 執行引導程序 - GRUB

    虛擬機中linux系統啟動後 一直黑屏解決辦法

    參數錯誤 初始化 原因 網絡編程 應用 編程 計算 body dns 情況一(一直黑屏):宿主機(windows)管理員模式運行CMD, netsh winsock reset 然後重啟電腦   netsh winsock reset命令,作用是重置 Winsock

    Linux系統啟動和內核管理

    lose ios 安裝操作系統 clas 內容 分區 inf initramfs 參數傳遞 Linux組成 由 kernel 和 rootfs 組成 單內核:(進程管理,內存管理,網絡管理, 驅動程序,文件系統, 安全功能) /boot/vmlinu

    Linux系統啟動排錯實驗集合

    boot分區 服務啟動 linux roo 在操作 splay 守護 故障 進程 Centos6系統啟動流程 1. post 加電自檢 檢查硬件環境 2. 選擇一個硬件類型引導啟動 mbr 446字節 grub stag

    Linux系統啟動流程之chkconfig

    Linux系統啟動流程chkconfig根據用戶的要求,需要在系統正常啟動後自動運行某些腳本。chkconfig xxx on 這個命令就自動在對應的rc2 rc3 rc4的目錄下創建腳本先拿rc2.d來看看這個是rc2.d目錄裏一個文件的內容,chkconfig 2345 57 432345指明了運行級別,