Linux 系統的編譯、鏡像制作、以及燒錄的概述


1.    獲取Loader、Kernel、File System

  這里不同CPU廠家的有些許差異,如果廠家沒有提供可以獲取基礎版,目前市面上做系統移植的基本都是去各個CUP廠家下載源碼,新建立幾個文件夾,分別用來保存獲取到的文件便於后續的編譯管理,ex:使用mkdir uboot kernel rootfs 命令建立uboot  kernel  rootfs  3個文件夾。

 

2.配置交叉編譯器

  不同廠家的交叉編譯器會不同,根據要編譯的CPU選擇對應的交叉編譯器;初次配置好交叉編譯器后,你再次編譯該廠家的系統就不需要重新編譯了;配置交叉編譯器本質就是:把交叉編譯器下載下來,修改文件權限,解壓到一個文件夾,再把該文件夾的路徑配置到環境變量中即可

ex: 控制台輸入vim ~/.bashrc ,在文件最后添加export PATH=${PATH}:/home/aplex/aplex/tools/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin(冒號后面是你解壓的環境變量bin文件的路徑),保存退出即可。當設置好之后,可以通過來檢驗一下。輸入對應的bin文件夾下面的工具,比如:arm-linux-xxxx-gcc -v (arm-linux-xxxx是你的交叉編譯器前綴),來查看自己的設置工具鏈版本號,是否是與自己設置的一致使用 交叉編譯器前綴-gcc -v 命令可查看交叉編譯器

 

3.編譯前先配置一下編譯環境

  控制台輸入vim ~/.bashrc ,在文件最后添加 export ARCH=arm (arm是你CPU的平台,這里是告訴make命令要編譯的是什么平台的系統)、export CROSS_COMPILE=arm-linux-gnueabihf-(arm-linux-gnueabihf-是第二步你配置好的交叉編譯器的前綴,告訴make文件使用什么編譯器編譯),因為在make的時候會執行makefile文件,該文件會尋找ARCH和CROSS_COMPILE的信息進行配置;

第2第3步配置一次后就永久生效的,這里你如果要編譯其他廠家的不同CPU系統的話,需要把這兩步的內容注釋掉重新配置新的CPU的配置;第2第3部配置好后,可以執行cat ~/.bashrc命令查看環境變量末尾的配置效果如下:

 

配置環境后需要使能環境變量,使用source  ~/.bashrc 命令使能環境變量,注意如果使能后你不重啟這次的使能只能在該命令窗口生效,新開的命令窗口無法生效,如果重啟后就會全局生效

 

4.開始分別編譯boot Loader、Kernel、File System

       每個部分編譯前都要先make一下它對應的配置文件(make ****_deconfig),配置好文件后即可直接編譯。

       編譯boot Loader先進入到保存boot Loader的文件夾,配置對應的項目的配置文件 ***deconfig ,然后執行 make ***deconfig 指令編譯它的配置文件,該指令會讓make自動到下層文件尋找defconfig文件執行配置,然后直接執行make指令系統會直接編譯該文件夾里的loader,如果需要開多線程編譯,可以執行 make -j** 指令(**是指你需要開啟的線程數),編譯后會生成一個MLO文件和一個 ***.img文件,這兩個文件后續做系統鏡像的時候需要用到

       編譯Kernel先跳轉到保存Kernel文件夾,后續步驟跟編譯Loader步驟一樣要先配置deconfig文件(該文件一般保存在 arch/arm/configs/ 或者 arch/arm64/configs/ 文件夾里,注意:arm代表32位,arm64代表64位),更詳細的編譯流程說明可以參考我另一篇博客:https://www.cnblogs.com/xingboy/p/14977729.html 編譯后會在arch/arm/boot文件夾生成一個zImage文件,還會在arch/arm/boot/dts文件夾生成一個 ***.dtb(***是你編譯的內核名,跟前面編譯配置文件時配置文件前的***一致) 文件,這兩個文件后續做系統鏡像需要用到。

       編譯File System關於File System的創建編譯這里先不提,后續補充。這里先說一下一個已經創建編譯好的文件系統如何生成鏡像文件,這里如果你是初次操作,首先需要執行sudo apt install  mtd-utils指令安裝工具。然后用到mkfs.ubifs ,使用指令sudo mkfs.ubifs  -q -r rootfs -m 2048 -e 126976 -c 2047 -o  ubifs.img -F(參數參考表4-1注釋一,可根據自己需求修改這些參數)。

表4-1 注釋一

-r rootfs : 將制作好的文件系統的文件夾rootfs(你用其他名稱的文件夾也行,只要是保存你的文件系統的即可),制作成UBIFS鏡像。

-m 2048:-m參數指定了最小的I/O操作的大小為,這里指定為2048bytes,也就是NAND FLASH一個page的大小。

-e 126976:-e參數指定了邏輯擦除快的大小,這里指定為126976 bytes,等於 (每塊的頁數 - 2)* 頁大小。

-c 2047:-c指定了最大的邏輯塊號,這里指定為2047, 這個是從下表4-2的 ubinize.cfg 里面的( vol_size) / (ubinize 里面的-p參數計算得來)。

-o  ubifs.img:是指定輸出文件名為ubifs.img。

-F:是指自動調整大小,通過此命令制作的出的UBIFS文件系統鏡像可在u-boot下使用ubi write命令燒寫到NAND FLASH上。

接着使用ubinize命令可將使用mkfs.ubifs命令制作的UBIFS文件系統鏡像轉換成可直接在 NAND FLASH 上燒寫的格式。先建立一個ubinize,配置文件,具體如下表4-2敘,使用指令sudo ubinize -o ubi.img -m 2048 -p 128KiB -s 512 -O 2048 ubinize.cfg(參數參考表4-2注釋二,可根據自己需求修改這些參數)。

表4-2 注釋二

-o ubi.img:指輸出文件名為ubi.img。

-m 2048:-m參數指定了最小的I/O操作的大小為,一般是頁大小,這里指定為2048bytes。

-p 128KiB: 指定的是目標flash的physical eraseblock塊的大小。

-s 512:用於UBI頭部信息的最小輸入輸出單元,一般與最小輸入輸出單元(-m參數)大小一樣,這里指定為512 bytes。

ubinize.cfg:是ubinize需要建立的一個配置文件,這個文件我們自己新建,里面配置文件主要內容和說明如下表。

 

[ubifs]

mode=ubi  

image=ubifs.img     #mkfs.ubi生成的鏡像源

vol_id=0            #卷序號 

vol_size=462MiB     #卷大小,即CPU分配給文件系統的內存大小

vol_type=dynamic    #動態卷

vol_name=rootfs     #卷名 

vol_flags=autoresize

 

       經過上過步驟后生成的ubi.img文件,在后面鏡像燒錄時候需要用到。

 

5.生成可燒錄的鏡像文件

參考鏈接:https://www.cnblogs.com/chenfulin5/p/6649801.html

              http://www.orangepi.org/Docs/Makingabootable.html

       新建一個文件夾mkdir Image 把上面編譯boot Loader后生成的MLO、 ***.img文件(兩個都是u-boot文件);編譯Kernel后生成的 ***.dtb文件(設備樹文件)、zImage文件(Kernel鏡像);File System使用ubinize命令操作后生成的ubi.img文件(文件系統鏡像);這5個文件復制進Image文件夾。

       接着新建一個空的鏡像文件,該鏡像文件就是你后續要做復制在SD卡里燒錄系統的鏡像文件。執行指令sudo dd if=/dev/zero of=myname.img  bs=1M count=200 該指令創建了一個名為myneme.img的大小為1M*100=200M的空鏡像文件(由if=/dev/zero定義,if是指定源文件,如果是指定SD卡if= /dev/sdX),該文件大小最好根據上面復制過來的5個文件內存大小來定,比他們加起來的內存大一點即可。

       接着通過 losetup 命令掛載新創建的空鏡像,通過sudo losetup -f --show myname.img指令把文件虛擬成塊設備,在執行該指令后會顯示出一行信息來顯示虛擬的設備塊節點:/dev/loopX (X表示1.2.3…)

       然后對該鏡像進行磁盤分區,使用sudo fdisk /dev/loopX ( X是上一步顯示出來的節點數 ) 指令后根據提示開始磁盤分區過程(這里的分區過程主要是對於Nandflash內存的CPU來說):  

Welcome to fdisk (util-linux 2.31.1).

Changes will remain in memory only, until you decide to write them.

Be careful before using the write command.

 

Device does not contain a recognized partition table.

Created a new DOS disklabel with disk identifier 0xf953eec2.

 

Command (m for help): n   #這里輸入 n 代表新建一個分區

Partition type

   p   primary (0 primary, 0 extended, 4 free)

   e   extended (container for logical partitions)

Select (default p): p     #這里需要你輸入,選擇 p

Partition number (1-4, default 1): 1 #分區號

First sector (2048-204799, default 2048): 2048  #這里輸入2048,First Sector 表示起始扇區,默認從第2048

                                                                       #塊扇區開始是因為,EFI的興起,要給EFI代碼留磁盤最

                                                                       #開始的1M空間.

Last sector, +sectors or +size{K,M,G,T,P} (2048-204799, default 204799): #回車就會把其他內存自動分配

 

Created a new partition 1 of type 'Linux' and of size 99 MiB.

 

Command (m for help): t # 改變分區格式命令

Partition number (1-4): 1 # 改變第幾個分區

Hex code (type L to list codes): e # 把分區改為FAT16

Changed system type of partition 1 to e (W95 FAT16 (LBA))

 

Command (m for help): a     #這里輸入 a ,增加boot屬性使得該分區變成可boot啟動的分區

Selected partition 1          #選定要變增加boot屬性的分區號

The bootable flag on partition 1 is enabled now.

 

Command (m for help): w    #保存相關信息並完成分區步驟

The partition table has been altered.

Calling ioctl() to re-read partition table.

Re-reading the partition table failed.: Invalid argument

 

The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).

       接着同步該分區 sudo kpartx -av /dev/loopX ( X模擬成塊設備時的設備節點數,如果提升找不到該命令執行sudo apt-get install kpartx指令安裝即可),執行該命令后會出現下面提示信息:

[sudo] password for aplex:

add map loopXp1 (253:0): 0 202752 linear 7:2 2048 

#如果你分了兩個區,還會出現多一行類似的信息

       下一步根據上面的顯示信息,使用下面指令對該分區進去格式化:

sudo mkfs.vfat  -n "boot" -F 16  /dev/mapper/loopXp1 

#-n “boot”是指把該分區命名為boot;-F 16 是指把該分區格式化為FAT16格式分區,這個看你CPU,一些CUP可能不需要格式化為FAT16。

---------------------------------------------------------------------------------------------

# sudo mkfs.ext3  -L "rootfs"  /dev/mapper/loopXp2 這里是格式化另外一個分區,並把它命名為rootfs;如果你分區了多一個就要執行多一次該指令,格式化多的那個分區,格式化成ext*沒有要求,有多少分區就格式化多少個。

       接下來根據kpartx同步分區的信息把分區進行掛載,掛載的目的是使文件能夠復制到鏡像的分區:

sudo mount /dev/mapper/loopXp1 /mnt 

#把分區掛載到mnt設備目錄,或者你自己建一個新的Test文件夾掛載到自己的文件夾也可以,掛載了才能讀取內容,而直接訪問只能讀設備信息,好比看碟,你訪問dev相當於直接拿碟片用眼看最多你能看出來是個CD或DVD,但插到光驅里讀就能看到電影了,注意如果你系統原來已經掛載了一個鏡像記得先取消那個鏡像的掛載。

       接着執行 sudo  cp  MLO  ***.img  ***.dtb  zImage  u-boot.img  /mnt/ 指令把前面復制過來的5個備用文件復制到你掛載起來的鏡像里。如果你分區的時候分了多個區就需要再把其他的分區再通過mount指令掛載在mnt上,再把你需要的文件通過cp指令復制到該分區。

       下一步執行指令 sudo umount /mnt/ 將掛載解除,然后分別執行sudo  kpartx -d /dev/loopXsudo  losetup -d /dev/loopX指令,到此鏡像制作完成。

 

6.將鏡像寫入TF卡燒錄

  這里以 TI 的 AM335X 為例子(不同廠家的arm芯片的燒錄軟件方法會有一些不同,這個跟MCU的類似,不同的MCU廠家燒錄軟件也不一樣),把你做好的鏡像文件復制出來,在window系統上使用Win32DiskImager工具,執行下圖操作制作,這樣你的SD卡就會變成你上面做的鏡像大小的帶boot屬性的SD卡了:

 

  最后插入TF卡,boot開關撥到0,連接好串口線,上電,開始燒錄,燒錄情況可以通過串口助手查看。

  注意:不同廠家有各種的燒錄工具,后續很多廠家新的CPU大多用USB燒錄,這種就不用制作TF卡,用廠家提供的燒錄工具直接燒錄即可,跟不同廠家MCU燒錄HEX文件同理,因為MCU也算是一個arm的CPU。還有現在很多廠家,其實都會把一些編譯操作,自己編寫了腳本文件,這樣更加方便用戶操作,這種時候可以直接用廠家的腳本即可,這里的方法是比較接近於初始的編譯步驟,可做參考了解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM