Tuesday, October 4, 2011

BIOS, BootManager, Bootstrap與Bootloader的差別

轉: Embedded.Linux.Primer.A.Practical.Real.World.Approach.Sep.2006.chm

Bootloader與Bootstrap再定義上有什饃差異呢?以下內容則是由網路上蒐集而來,,客觀的了解一下吧!有錯誤請糾正,非常感謝!




一般早期SOC 都會有 三個階段loader.(早期的說法)

  • S1-loader : Bootstrap 是內建在 SOC 裡, 把S2 Loader Download 到 RAM中.
  • S2-loader : 透過Bootstrap download到RAM的程式,一般這個code都會含燒寫 flash,及RS-232.
  • S3-loader : 透過S2-loader Download到RAM並燒錄到flash或EEROM的程式, 也就是一般OS的loader, 也稱為Bootloader. 
基本上S3-loader完成後, 以後就不用S1-loader & S2-loader, 一般的Bootloader是用來load os image.


BIOS、BootManager、Bootstrap、Bootloader 




  • 所謂的BIOS(Basic input output system  基本輸出入系統)  ,是指存在主機板上的 flash ROM 上,負責許多與硬體溝通和初始化硬體的動作的,與同型號的主機緊密結合.
  • 所謂BootManager(開機管理員  )寫好後,可套用在所有的 x86 機器上,大部分存在硬碟主要開機磁區(Master Boot Record, MBR)。BootManager 的工作是將OS 的核心(Kernel)載入.
  • 所謂Bootstrap 就是我們利用了 BootManager 載入kernel 後,OS開始做一堆的初始動作直到我們可以開始使用,在這期間的一連串動作BootManager 也常稱為 Bootstrap Loader。
  • 至於 Bootloader(開機程式)其實跟前面 所提的 BootManager 幾乎一樣(也有許多人將這兩詞視為同意),主要任務就是要讀進 kernel 使系統進入bootstrap的動作。只是在嵌入式系統中常把BIOS 與BootManager 做在一起,且也不需要選擇OS 這種功能,而把從電源一開啟到讀進 kernel 的所有動作統歸為bootloader 所負責.

Bootloader與Bootstrap如何載入與啟動Kernel?

Bootloader 為 "S1-loader"引導裝入程序, Bootstrap loader 翻譯為"S2-loader"引導裝入程序. Bootloader 不用多解釋都能理解--Power on 後執行的第一個程序,絕對不依賴kernel (Ex. u-boot、Redboot, 如下圖所述)。
Bootstrap loader: 屬於Kernel Source Code, 沒編譯進vmlinux, 但是可執行的image(如Bootable kernel image, zImage, 中含有bootstrap ),充當 Bootloader 和 kernel image 之間的glue. Bootstrap通常會check kernel、uncompress kernel、relocate kernel to ram、為kernel可以順利執行, 提供需要的環境(Interrupt cache instructions, data cache、environment setting for C language, etc.)
此外, 下列兩個head.o 不相同, Bootstrap loader用的是/arch/arm/boot/compressed/head.S, 而vmlinux用的是/arch/arm/kernel/head.S. 


/arch/arm/boot/compressed/head.S:
    . arch/arm/boot/compressed/head.o
        ARM-specific startup code generic to ARM processors. It is this object that is passed control by the bootloader.
    . arch/arm/boot/compressed/head-arm.o
        Processor initialization specific to the ARM processor family.
  也就是MCU的初始設定與建立C的環境.


/arch/arm/kernel/head.S:
 經由bootloader轉移控制全到核心時, 就是轉移到此head.S,從此處一直進行到main.c裡的start_kernel().


P.S: 別忘了, bootloader會初始整個Embedded System, 但zImage載入到RAM時,從RAM執行的行為到核心啟動之前稱為bootstrap.
P.S: 文件中指出,CPU控制權的轉移則是由Bootload轉交的, 那麼應該可這麼說"bootstrap對於bootloader來說,應該算是bootloader中的其中一部分的行為".

Fig 1. Power On Sequence.

如下圖, image其实就是vmlinux.bin,vmlinux.bin的生成命令如下:

  • objcopy -O binary -R .note -R .comment -S vmlinux arch/arm/boot/Image
piggy.gz(vmlinux.bin.gz)則為:
  • gzip -f -9 arch/arm/boot/Image piggy.gz


配合原圖說明 kernelmake 的一個最重要的生成檔 vmlinux 去掉了、標記和注釋後生成了image. 再經過gzip壓縮後變成piggy.gz.接下來,一個名為piggy.s(將piggy.gz編譯為piggy.o)的文件被彙編成piggy.o. 最後一步,將piggy.o, misc.ohead.o 等屬於bootstrap的代碼一起鏈結成為zImage成為bootable kernel image。其中misc.o負責解壓縮、head.o head_xx.o 負責進行kernel執行環境的初始化.


最後,說明一下上面的檔案用途:

  1. arch/<cpu_arch>/kernel/head.S (有些平台可能在其他目录)
head.S的功能大概如下:
  • Checks for valid processor and architecture
  • Creates initial page table entries
  • Enables the processor's memory management unit (MMU)
  • Establishes limited error detection and reporting
  • Jumps to the start of the kernel proper, main.c
  1. Kernel startup: main.c
在head.S里有一句汇编,类似如下:

    b start_kernel

start_kernel()位于init/main.c里,是内核的第一个与平台无关的C代码起始函数。

  1. Architecture setup
由start_kernel()调用setup_arch(&command_line)。

回到 main.c 的啟動程序,main.c 會先呼叫 setup_arch(&command_line) 及 setup_processor() ,這裡 &command_line 是由 boot loader 設定開機參數或是寫在 kernel 裡等方法定義,可以讓 kernel 依据參數進行各種不同的啟動行為, setup_processor() 則查詢了硬體的版本及代號等訊息。
kernel_init()->init_post()-> calling /sbin/init (symbolink to busybox)
init() 會創建 PID 為 1 的第一個 user space 的 process, 再來會呼叫 /sbin/init , /etc/init 等程式(依序呼叫直到真的找到 init 這隻程式),然後就進到一般所了解的 runlevel 了。

init() 會掛起一個 ram disk,載入啟動實體 file system(ext2 等) 之前所需的 driver。

另外在嵌入式系統裡,start_kernel 跟 init() 是分別去啟動的,boot loader 會分別把兩個程式的位址記下來,然後用 bootm 進行啟動的動作,如此 kernel 才能找到 ramdisk。



&command_line再u-boot中,可能的形式如下:


    setenv bootargs 'noinitrd console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2 mtdparts=nand_flash:128k(u-boot)ro,64k(u-boot.envs),3m(kernel),30m(root.jffs2),30m(root.jffs2)'



最後,以不講Code的方式在做一次Bootloader 與 Bootstarp的總整理(從etd-0730106-013540.pdf節錄下來)
  未完,待續...


(Ref: etd-0812109-210739.pdf)

      No comments:

      Post a Comment