五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

一篇簡述 Linux 移植與系統(tǒng)啟動

2023-11-09 15:57 作者:補給站Linux內(nèi)核  | 我要投稿

1、Linux系統(tǒng)啟動與U-Boot

所謂移植就是把程序代碼從一種運行環(huán)境轉(zhuǎn)移到另一種運行環(huán)境。對于內(nèi)核移植來說,主要是從一種硬件平臺轉(zhuǎn)移到另一種硬件平臺上運行。

體系結(jié)構(gòu)級別的移植是指在不同體系結(jié)構(gòu)平臺上Linux內(nèi)核的移植,例如,在ARM、MIPS、PPC等不同體系結(jié)構(gòu)上分別都要對每個體系結(jié)構(gòu)進行特定的移植工作。一個新的體系結(jié)構(gòu)出現(xiàn)就需要進行這個層次上的移植。

SoC級別的移植是指在具體的SoC處理器平臺上Linux內(nèi)核的移植,例如,ARM i.MX6Dual處理器要進行SoC特定的移植工作,主要包括處理器相關(guān)的內(nèi)核修改、集成外設(shè)驅(qū)動。

主板級別的移植是指在具體的目標主板上Linux內(nèi)核的移植,例如,在i.MX6DualFS2410目標板上,需要進行主板特定的移植工作,主要包括特定目標板系統(tǒng)啟動與主板擴展外設(shè)相關(guān)的外設(shè)驅(qū)動等。

基于同一款處理器的不同嵌入式設(shè)備并不是所有的外部設(shè)備都相同,不同的開發(fā)板可以使用不同的SDRAM、Flash、以太網(wǎng)接口芯片等。這就需要根據(jù)硬件修改或者開發(fā)驅(qū)動程序。

一個最基本的Linux操作系統(tǒng)應(yīng)該包括:引導程序、內(nèi)核與根文件系統(tǒng)三部分。因此,需要移植一個Linux系統(tǒng)的話,那么需要以下4個步驟:

  • 搭建交叉開發(fā)環(huán)境;

  • BootLoader的選擇和移植;

  • kernel的配置、編譯、和移植;

  • 根文件系統(tǒng)的制作。

(1)BootLoader簡介

引導加載程序(Boot Loader)就是在操作系統(tǒng)內(nèi)核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準備好正確的環(huán)境。

如下圖所示:


為什么系統(tǒng)移植之前要先移植BootLoader?

BootLoader的任務(wù)是引導操作系統(tǒng),所謂初始化CPU運行環(huán)境,引導操作系統(tǒng)。就是啟動內(nèi)核,讓內(nèi)核運行就是把內(nèi)核加載到內(nèi)存RAM中去運行。

是誰把CPU運行環(huán)境初始化的?

是誰把內(nèi)核搬到內(nèi)存中去運行?

SRAM只要系統(tǒng)上電就可以運行,而SDRAM需要軟件進行初始化才能運行,那么內(nèi)存是由誰來初始化的呢?

(2)Bootloader的執(zhí)行過程

uboot 啟動流程詳細分析

  • 初始化SDRAM;

  • 初始化串口;

  • 檢測處理器類型;

  • 設(shè)置Linux啟動參數(shù);

  • 調(diào)用Linux內(nèi)核映像。

(3)BootLoader的分類

很多人說BootLoader就是U-Boot,這種說法是錯誤的,確切來說是U-Boot是BootLoader的一種。u-boot和bootloader到底有什么區(qū)別。

如下圖所示。


可以知道如果使用開發(fā)板board/<board_name>,就先執(zhí)行“make <board_name>_config”命令進行配置,然后執(zhí)行“make all”, 就可以生成如下3個文件:

  • u-boot.bin:二進制可執(zhí)行文件,它就是可以直接燒入eMMC中的文件。

  • u-boot: ELF格式的可執(zhí)行文件。

  • u-boot.srec: 原摩托羅拉格式的可執(zhí)行文件。

對于imx6dlsabresd開發(fā)板,可以根據(jù)開發(fā)板的型號選擇執(zhí)行“make imx6dlsabresd_defconfig”、“make"進行編譯。

編譯后生成的u-boot.imx鏡像可以燒入SD卡中執(zhí)行,具體命令如下:

其中sdb代表SD卡在系統(tǒng)中對應(yīng)的設(shè)備。

(4)u-boot配置過程

在配置之前,為了使編譯后的u-boot在開發(fā)板上運行,首先需要安裝交叉編譯鏈。并使用如下命令配置環(huán)境變量:



u-boot啟動流程分析如下

第一階段:(注明下每個步驟的作用)

a -- 設(shè)置cpu工作模式為SVC模式。需要SVC權(quán)限對CPU的狀態(tài)寄存器進行操作b -- 關(guān)閉中斷,mmu,,cache。需要直接物理地址訪問v -- 關(guān)看門狗d -- 初始化內(nèi)存,串口。用于初始化基本的存儲空間與通信接口,用于啟動信息交互e -- 設(shè)置棧。用于系統(tǒng)啟動臨時數(shù)據(jù)交換和初始化棧指針f -- 代碼自搬移。用于拷貝系統(tǒng)啟動代碼g -- 清bss

h -- 跳c

第二階段:

a -- 初始化外設(shè),進入超循環(huán)

b -- 超循環(huán)處理用戶命令

函數(shù)前期執(zhí)行流程如下:

1)_start(arch/arm/lib/vector.S)
? ?? ?? ?? ???b? ???reset2)reset(arch/arm/cpu/$CPU/start.S)

? ?? ?? ?? ???bl? ? cpu_init_cp15
? ?? ?? ?? ???bl? ? cpu_init_crit
? ?? ?? ?? ???bl? ? _main

3)_main(arch\arm\lib\crt0.S)

? ?? ?? ?? ???board_init_f(common\Board_f.c)
? ?? ?? ?? ???b? ???relocate_code
? ?? ?? ?? ???ldr? ?lr, =board_init_r(common/Board_r.c)

4)main_loop()

5)啟動內(nèi)核:

? ? main_loop->autoboot_command->run_command_list->cli_simple_run_ command_list->cli_simple_run_command->cmd_process->find_cmd/cmd_call(result=(cmdtp->cmd)(cmdtp, flag, argc, argv))

uboot的最終目的是引導內(nèi)核,在此之前uboot需要完成一系列初始化操作,包括設(shè)置時鐘、初始化DDR、Flash、串口、網(wǎng)卡等等。

這時uboot有兩條路走(1)通過按鍵,觸發(fā)uboot進入命令行模式,等待處理命令。

(2)引導內(nèi)核


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ??


零聲白金VIP體驗卡(含基礎(chǔ)架構(gòu)/高性能存儲/golang/QT/音視頻/Linux內(nèi)核)課程:



2、Linux系統(tǒng)裁剪與移植

內(nèi)核編譯相關(guān)文件主要包括頂層Makefile與子目錄下的Makefile、各級目錄Kconfig文件。

a--在內(nèi)核配置之前先使用make mrproper命令清除以前的內(nèi)核。

b--詳細配置?make menuconfig

c--編譯

make zImage ---生成內(nèi)核鏡像??/arch/arm/boot/zImage

make dtbs ---生成設(shè)備樹文件??/arch/arm/boot/dts/imx6dl-sabresd.dtb

make modules ---把配置值選成M的代碼編譯生成模塊文件。(.ko)??放在對應(yīng)的源碼目錄下。

可以看出,內(nèi)核編譯主要包括兩部分:一部分是內(nèi)核配置;另一部分是內(nèi)核編譯。如下圖所示。


內(nèi)核的Kconfig分析:

a -- 我們解壓內(nèi)核后需要先修改內(nèi)核頂層目錄下的Makefile,配置好交叉編譯工具

b -- 然后導入默認配置(使用make imx_v7_defconfig 或者

cp??arch/arm/configs/imx_v7_deconfig??.config)

c -- 配置內(nèi)核

如下圖所示。

內(nèi)核中的哪些文件將被編譯?它們是怎樣被編譯的?它們連接時的順序如何確定?哪個文件在最前面?哪些文件或函數(shù)先執(zhí)行?這些都是通過Makefile來管理的。

從最簡單的角度來總結(jié)Makefile的作用,有以下3點:

1)-- 決定編譯哪些文件?

2)-- 怎樣編譯這些文件?

3)-- 怎樣連接這些文件,最重要的是它們的順序如何?


1)頂層Makefile 決定內(nèi)核根目錄下哪些子目錄將被編進內(nèi)核;

2)arch/$(ARCH)/Makefile 決定arch/$(ARCH)目錄下哪些文件、哪些目錄將被編進內(nèi)核;

3)各級子目錄下的Makefile決定所在目錄下哪些文件將被編進內(nèi)核,哪些文件將被編程模塊(即驅(qū)動程序),進入哪些子目錄繼續(xù)調(diào)用它們的Makefile。

與移植U-Boot的過程相似,在移植Linux之前,先了解它的啟動過程。

Linux 的過程可以分為兩部分:架構(gòu)/開發(fā)板相關(guān)的引導過程、后續(xù)的通用啟動過程。對于uImage、zImage ,它們首先進行自解壓得到vmlinux ,然后執(zhí)行 vmlinux 開始“正常的”啟動流程。

引導階段通常使用匯編語言編寫,它首先檢查內(nèi)核是否支持當前架構(gòu)的處理器,然后檢查是否支持當前開發(fā)板。

通過檢查后,就為調(diào)用下一階段的start_kernel函數(shù)作準備了。

這主要分如下兩個步驟:

1) 連接內(nèi)核時使用的虛擬地址,所以要設(shè)置頁表、使能MMU;

2)調(diào)用C 函數(shù) start_kernel 之前的常規(guī)工作,包括復制數(shù)據(jù)段、清除BSS段、調(diào)用start_kernel 函數(shù)。

第二階段的關(guān)鍵代碼主要使用C語言編寫。

它進行內(nèi)核初始化的全部工作,最后調(diào)用 rest_init 函數(shù)啟動init 過程,創(chuàng)建系統(tǒng)第一個進程:init 進程。在第二階段,仍有部分架構(gòu)/開發(fā)板相關(guān)的代碼,比如重新設(shè)置頁表、設(shè)置系統(tǒng)時鐘、初始化串口等。

內(nèi)核自解壓階段:

Linux內(nèi)核有兩種映像:一種是非壓縮內(nèi)核,叫Image,另一種是它的壓縮版本,叫zImage。根據(jù)內(nèi)核映像的不同,Linux內(nèi)核的啟動在開始階段也有所不同。

zImage是Image經(jīng)過壓縮形成的,所以它的大小比Image小。但為了能使用zImage,必須在它的開頭加上解壓縮的代碼,將zImage解壓縮之后才能執(zhí)行,因此它的執(zhí)行速度比Image要慢。

但考慮到嵌入式系統(tǒng)的存儲空容量一般比較小,采用zImage可以占用較少的存儲空間,因此犧牲一點性能上的代價也是值得的。所以一般的嵌入式系統(tǒng)均采用壓縮內(nèi)核的方式。

內(nèi)核自解壓階段依次完成以下工作:開啟MMU和Cache,調(diào)用decompress_kernel()解壓內(nèi)核,最后通過調(diào)用call_kernel()進入非壓縮內(nèi)核Image的啟動。

內(nèi)核引導階段:

內(nèi)核引導階段是內(nèi)核啟動第一階段,該部分代碼實現(xiàn)在arch/arm/kernel的 head.S中,該文件中的匯編代碼通過查找處理器內(nèi)核類型和機器碼類型調(diào)用相應(yīng)的初始化函數(shù),再建 立頁表,最后跳轉(zhuǎn)到start_kernel()函數(shù)開始內(nèi)核的初始化工作。如下圖所示:


內(nèi)核初始化階段:

Linux內(nèi)核啟動的第二階段從start_kernel()函數(shù)開始。start_kernel()是所有Linux平臺進入系統(tǒng)內(nèi)核初始化后的入口函數(shù),它主要完成剩余的與硬件平臺相關(guān)的初始化工作,在進行一系列與內(nèi)核相關(guān)的初始化后,調(diào)用第一個用戶進程-init進程并等待用戶進程的執(zhí)行,這樣整個Linux內(nèi)核便啟動完畢。



BusyBox初始化階段:

除了基本的命令之外,BusyBox還支持init功能,如同其它的init一樣,busybox的init也是完成系統(tǒng)的初始化工作,關(guān)機前的工作等等。

BusyBox的init進程會依次進行以下工作:

  • 為init設(shè)置信號處理過程;

  • 初始化控制臺;

  • 分析 inittab文件,/etc/inittab;

  • 執(zhí)行系統(tǒng)初始化腳本,缺省情況下會使用/etc/init.d/rcS;

  • 執(zhí)行所有導致init暫停的inittab命令(動作類型:wait);

  • 執(zhí)行所有僅執(zhí)行一次的inittab(動作類型:once)。

3、Linux根文件系統(tǒng)移植

(1)文件系統(tǒng)與根文件系統(tǒng)

根,可以理解為基礎(chǔ)的意思。根文件系統(tǒng)是一種最基礎(chǔ)的文件系統(tǒng)。

Linux系統(tǒng)也可以將磁盤或Flash等存儲設(shè)備劃分為若干個分區(qū),在不同的分區(qū)存放不同類型的文件,在某個分區(qū)存放u-boot的可執(zhí)行文件;在某個分區(qū)存放內(nèi)核映像文件,在另一分區(qū)存放根文件系統(tǒng)映像文件等。

Linux也需要在一個分區(qū)上存放系統(tǒng)啟動的必要文件,比如內(nèi)核啟動運行后的第一個程序(init進程)、用于掛接文件系統(tǒng)的腳本、給用戶提供操作界面的shell程序,應(yīng)用程序所要依賴的庫等,這些必要的基本文件的集合稱為根文件系統(tǒng)(一般也叫做rootfs)。

Linux系統(tǒng)啟動后首先會掛載這個分區(qū),這稱為掛載(mount)根文件系統(tǒng)。其他分區(qū)上的所有目錄、文件的集合,稱為文件系統(tǒng)。

為什么需要根文件系統(tǒng)?

1)init進程的應(yīng)用程序在根文件系統(tǒng)上;

2)根文件系統(tǒng)提供了根目錄/;

3)內(nèi)核啟動后的應(yīng)用層配置(etc目錄)在根文件系統(tǒng)上。可以認為:發(fā)行版=內(nèi)核+rootfs。

4)shell命令程序在根文件系統(tǒng)上。譬如ls、cd等命令。

因此,一套Linux體系,只有內(nèi)核本身是不能工作的,必須要rootfs(上的etc目錄下的配置文件、/bin與/sbin等目錄下的shell命令,還有/lib目錄下的庫文件等)相配合才能工作。

(2)根文件系統(tǒng)概述

Linux中的根文件系統(tǒng)更像是一個文件夾或者叫做目錄(特殊的文件夾),在這個目錄里面會有很多的子目錄。

根目錄下和子目錄中會有很多的文件,這些文件是Linux運行所必須的,比如庫、常用的軟件和命令、設(shè)備文件、配置文件等等。

根文件系統(tǒng)和Linux內(nèi)核是分開的,單獨的Linux內(nèi)核是沒法正常工作的,必須要搭配根文件系統(tǒng)。

(3)根文件系統(tǒng)的結(jié)構(gòu)

? ?Linux的根文件系統(tǒng)是采用級層式的樹狀目錄結(jié)構(gòu),在此結(jié)構(gòu)中的最上層是根目錄“/”,然后在此目錄下再創(chuàng)建其他的目錄。樹的根結(jié)點為根目錄root。


其中:

1)/root 系統(tǒng)管理員的主目錄2)/bin 存放二進制可執(zhí)行命令的目錄3)/boot 存放的是啟動Linux時使用的一些核心文件,包括一些連接文件以及鏡像文件。4)/dev 存放設(shè)備文件的目錄5)/etc 存放系統(tǒng)管理和配置文件的目錄6)/home 用戶主目錄7)/lib 存放動態(tài)鏈接共享庫的目錄8)/sbin存放系統(tǒng)管理員使用的管理程序的目錄9)/mnt 系統(tǒng)提供這個目錄是讓用戶臨時掛載其他的文件系統(tǒng)10)/proc 虛擬文件系統(tǒng)11)/usr 最龐大的目錄12)/var某些大文件的溢出區(qū)13)/tmp 公用的臨時文件存儲點

一般我們在Linux驅(qū)動開發(fā)的時候都是通過nfs掛載根文件系統(tǒng)的,當產(chǎn)品最終上市開賣的時候才會將根文件系統(tǒng)燒寫到EMMC或者NAND中。

1)修改Makefile,添加編譯器;

2)配置busybox ;

3)編譯busybox ;

4)向根文件系統(tǒng)添加lib庫(完成基本根文件系統(tǒng));

5)創(chuàng)建其他文件夾;

6)完善根文件系統(tǒng)。

Linux系統(tǒng)掛載完根文件系統(tǒng)之后,就會執(zhí)行init程序,創(chuàng)建init進程。執(zhí)行過程大概如下圖所示。


來源:面包板社區(qū)



一篇簡述 Linux 移植與系統(tǒng)啟動的評論 (共 條)

分享到微博請遵守國家法律
方城县| 宿松县| 时尚| 新泰市| 宝鸡市| 菏泽市| 宁阳县| 保亭| 普兰县| 尼玛县| 昂仁县| 盐边县| 济宁市| 黑龙江省| 望谟县| 新蔡县| 友谊县| 资兴市| 呼伦贝尔市| 苏尼特左旗| 涡阳县| 尤溪县| 项城市| 什邡市| 鞍山市| 赫章县| 利辛县| 利津县| 呼玛县| 赤峰市| 九龙坡区| 卢湾区| 晋中市| 望城县| 灵武市| 禹城市| 建水县| 博客| 绥棱县| 通辽市| 前郭尔|