Linux 系统的编译、镜像制作、以及烧录

1.    获取Loader、Kernel、File System

  这里不同CPU厂家的有些许差异,如果厂家没有提供可以获取基础版,新建立几个文件夹,分别用来保存获取到的文件便于后续的编译管理,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文件的路径),保存退出即可。

 

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的文件夹,配置对应的项目的配置文件,然后执行 make ***deconfig 指令编译它的配置文件,该指令会让make自动到下层文件寻找defconfig文件执行配置,然后直接执行make指令系统会直接编译该文件夹里的loader,如果需要开多线程编译,可以执行 make -j** 指令(**是指你需要开启的线程数),编译后会生成一个MLO文件和一个 ***.img文件,这两个文件后续做系统镜像的时候需要用到

       编译Kernel先跳转到保存Kernel文件夹,后续步骤跟编译Loader步骤一样编译后会在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文件系统镜像转换成可直接在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。还有现在很多厂家,其实都会把一些编译操作,自己编写了脚本文件,这样更加方便用户操作,这种时候可以直接用厂家的脚本即可,这里的方法是比较接近于初始的编译步骤,可做参考了解。

原文地址:https://www.cnblogs.com/xingboy/p/14858853.html