大家好,今天小编我又要来水一波了(linux大神们请绕道,勿喷,在此谢过大神们的不喷之恩)。本人是linux小白,但是渐渐地对ZYNQ的linux产生了及其浓厚的兴趣,因为脑子不好使,经常记不住东西,所以希望通过博客的形式记录一下,以后忘记了方便回过头来看看。前面都是废话,可以不用看。。。(回到正题)今天我们要水的就是ZYNQ 的uboot生成、编译;内核的下载,生成,编译;文件系统的制作。
首先我们搞linux必备的除了工具就是源码,我的工具就是一台装有Ubuntu14.04的PC机,一块矿机板卡(号:EBAZ4205)/(我暂时先用的z7035),一张TF卡(容量最好大于4G,因为我用的文件系统比较大)(我暂时用z7035的QSPI和EMMC),一个读卡器,一个USB转TTL,电源12V,上位机软件puTTY,当然最重要的还有源码(本人用的不是petalinux,不是petalinux,不是petalinux,重要的事情说3遍。用的Xilinx官方github的原生态:
uboot:https://github.com/Xilinx/u-boot-xlnx/tree/xilinx-v2018.3
内核kernel:https://github.com/Xilinx/linux-xlnx
设备树库devicetree:https://github.com/Xilinx/device-tree-xlnx/tree/xilinx-v2019.2
(文件系统制作源码)busybox:https://busybox.net/
(或者使用git下载busybox源码):git clone git://git.busybox.net/busybox
(由于最新的busybox不支持mkfs.ext4,所以需要下载文件系统制作工具的源码e2fsprogs)http://e2fsprogs.sourceforge.net/
1:下载,编译u-boot
(1)下载uboot源码(https://github.com/Xilinx/u-boot-xlnx/tree/xilinx-v2018.3)
修改uboot源码目录下的设备树,主要修改网络这块,我的是Marvell的88E1512,PHY地址是0,所以我把设备树下面
的PHY地址修改为0(因为我们要通过网络来加载内核kernel和文件系统ramdisk还有设备树)
$:cd u-boot-2018.3/u-boot-xlnx/arch/arm/dts
$:vim
$:cd u-boot-2018.3/
$:cd u-boot-xlnx/
$:export ARCH=arm
$:export CROSS_COMPILE=arm-linux-gnueabihf-
$:make zynq_zc7100_defconfig
$:make menuconfig
直接选择退出,暂时可以什么不用修改
$:make
uboot源码会编译出一个u-boot.elf文件,拷贝出来,结合vitis IDE,创建出BOOT.bin/BOOT.mcs文件即可。
使用vitis IDE直接将BOOT.mcs文件下载到QSPI FLASH中即可。
$:
$:
$:
$:
$:
$:
$:
$:
$:
$:
$:
$:
2:下载,编译内核kernel
3:下载busybox,制作文件系统(https://busybox.net/)
(1):在工作目录下创建rootfs文件夹
$:mkdir rootfs
$:tar -zxvf busybox-1.31.1.tar.bz2
(2):配置编译busybox
$:cd busybox-1.31.1
$:make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- defconfig
$:make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- menuconfig
弹出menuconfig图形界面后的配置如下:
Settings --> [ ]Don't use /usr (不选中)
Settings --> What kind of applet links to install (as soft-links) --> (/home/XXXX/XXXX/rootfs) Destination path for 'make install'(填写busybox生成文件的安装路径)
选中对flash可以操作的工具
Miscellaneous Utilities --> [*] fbsplash (26 kb) \
[*] flash_eraseall (5.9 kb) \
[ ] flash_lock (2.1 kb) \
[ ] flash_unlock (1.3 kb) \
[*] flashcp (5.3 kb)
Linux System Utilities --> [ ] nsenter (6.5 kb)(不选中)
Coreutils --> [ ] sync (3.8 kb)(不选中)
到此,busybox配置完成,选中“Exit”退出,会提示是否保存,选择“Yes”。
(3):安装busybox工具(上面我们配置了busybox的安装目录:/home/XXXX/XXXX/rootfs),busybox会自动安装到rootfs文件夹
$:make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- install
进入rootfs目录
$:cd rootfs
创建文件系统目录
$:mkdir dev etc etc/init.d mnt opt proc root sys tmp var var/log var/www lib
(很重要)将交叉编译工具链的库文件拷贝到rootfs目录下
我的交叉编译工具链安装路径:/opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin
$:cp /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/* lib/ -r
$:cp /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/sbin/* sbin/ -r
$:cp /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/bin/* usr/bin/ -r
编译文件系统文件
$:gedit etc/fstab
LABEL=/ / tmpfs defaults 0 0
none /dev/pts devpts gid=5,mode=620 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
none /tmp tmpfs defaults 0 0
$:gedit etc/inittab
::sysinit:/etc/init.d/rcS
#/bin/ash
#
# Start an askfirst shell on the serial ports
ttyPS0::respawn:-/bin/ash
#What to do when restarting the init process
::restart:/sbin/init
# What to do before rebooting
::shutdown:/bin/umount -a –r
$:gedit etc/init.d/rcS
#!/bin/sh
echo "Starting rcS..."
echo "++ Mounting filesystem"
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
echo "++ Setting up mdev"
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir -p /dev/pts
mkdir -p /dev/i2c
mount -t devpts devpts /dev/pts
echo "++ Starting telnet daemon"
telnetd -l /bin/sh
echo "++ Starting http daemon"
httpd -h /var/www
echo "++ Starting ftp daemon"
tcpsvd 0:21 ftpd ftpd -w /&
/sbin/ifconfig lo 127.0.0.1
/sbin/ifconfig eth0 192.168.31.230 netmask 255.255.255.0 up
/bin/hostname –F /etc/hostname
echo "rcS Complete"
$:chmod 755 etc/init.d/rcS
$:sudo chown root:root etc/init.d/rcS
$:gedit hostname
GTM
$:gedit profile
HOSTNAM='/bin/hostname'
PS1='[\u@\h \w]\#'
export PS1 HOSTNAME
到此,我们的根文件系统基本配置完毕。
4:下载e2fsprogs,手动添加mkfs.ext4文件系统制作工具(http://e2fsprogs.sourceforge.net/)
(1):解压e2fsprogs源码
$:tar -xvf e2fsprogs-1.45.5.tar
(2):进入e2fsprogs目录,创建install文件夹
$:mkdir install
(3):(很重要)进行configure配置
$:./configure --host=arm-linux --prefix=$PWD/install CC=/opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-gcc
$:make
$:sudo make install
(4):进入install目录下面会产生如下文件
这时候我们只需要bin文件夹里面的所有文件和sbin文件夹里面的mkfs.ext4文件即可,具体操作如下:
将install/bin目录下的所有文件复制到rootfs/bin目录下面
将install/sbin目录下的mkfs.ext4文件复制到rootfs/sbin目录下面
将install/lib目录下的所有文件复制到rootfs/lib目录下面
OK,到此我们的文件系统已经支持mkfs.ext4文件系统制作工具了。
5:制作ramfs.gz或者叫ramdisk.gz
(1):首先看一下我们的rootfs文件夹占用的内存大概是118MB,所以我们要在DDR中给我们的文件系统开辟至少118MB的内存空
间,这里我直接分配256MB的空间出来,因为我的DDR是1GB的。
特别说明:
《
如果DDR空间内存不够的话,还有一个解决办法,那就
是在配置busybox的时候在menuconfig界面,选择如下配置:
Settings --> [*]Build static binary (no shared libs)
这样就可以极大地减小了文件系统的体积,减少了文件占用的空间内存。
然后再重新开始第3步的操作即可。(别嫌麻烦,谁让咱们都是小白呢)
》
进入内核kernel源码目录:
$:make menuconfig
内核默认的文件系统大小是16384KB == 16MB大小,这里我改成了262144KB == 256MB
Linux/arm 4.19.0 Kernel Configuration --> Device Drivers --> Block devices --> (262144) Default RAM disk size (kbytes)
$:make uImage LOADADDR=0x8000
(2):退回到rootfs的上级目录
(3):开始制作ramdisk.gz
$:dd if=/dev/zero of=ramdisk256M.image bs=1024 count=262144
$:mke2fs -F ramdisk256M.image -L "ramdisk" -b 1024 -m 0
$:tune2fs ramdisk256M.image -i 0
$:chmod 777 ramdisk256M.image
$:mkdir ramdisk
$:sudo mount -o loop ramdisk256M.image ramdisk/
$: sudo cp -R ./rootfs/* ramdisk
$:sudo umount ramdisk/
$:gzip -9 ramdisk256M.image
$:mkimage -n 'uboot ext2 ramdisk' -A arm -O linux -T ramDisk -C gzip -d ramdisk256M.image.gz uramdisk.image.gz
6:在DDR中验证内核kernel和文件系统ramfs
(1):通过vitis IDE将uboot.bin烧录到板卡的QSPI FLASH中,修改uboot源码目录下的configs/zynq_zc7100_defconfig
屏蔽掉图中的 # CONFIG_ENV_IS_IN_SPI_FLASH=y (禁止从QSPI FLASH中读取环境变量文件,否则会因为找不到
Env.txt而死机)
(4):DDR访问存储空间0x100000 ~ 0x3FF00000
通过tftp将内核kernel,文件系统ramdisk.gz,设备树文件烧录到指定地址
设备树: devicetree.dtb ==== 0x800000
内核: kernel ==== 0x810000
文件系统: ramdisk.gz ==== 0xE10000
设置板卡IP和服务器IP
$:set ipaddr 192.168.xxx.xxx
$:set serverip 192.168.xxx.xxx
$:tftpboot 800000 devicetree.dtb
$:tftpboot 810000 uImage
$:tftpboot e10000 ramdisk.gz
启动uboot加载内核和ramdisk
$:bootm 810000 e10000 800000
到此我们的系统就完成了在DDR中的启动(注意,断电或重启后内核kernel和文件系统会被刷掉)。
7:制作EMMC分区,分别用于存放(fat32)内核kernel和(ext4)rootfs
系统起来以后,我们就要开始给EMMC分区了。
$:cd /dev
$:ls
使用fdisk查看emmc的当前分区信息
$:fdisk mmcblk0
查看帮助信息
$:m
查看分区信息,可以看到当前EMMC设备的存储信息和分区信息(当前并没有分区,所以没有显示分区信息)
$:p
(1)创建内核kernel和设备树的分区(分区1)
①创建分区
$:n
②选择分区类型 p:主分区 e:扩展分区
$:p
③设置分区号(范围1-4,习惯性的从1开始)
$:1
④设置起始扇区(默认即可,直接回车)
提示设置Last sector or +size{,K,M.G, T} (16-15269887,default 15269887):
然后我们直接输入:+64M
意思就是给刚刚创建的分区1分配64MB的内存空间。
⑤写入,保存创建的分区信息并且退出fdisk工具
$:w
⑥查看分区信息
$:fdisk mmcblk0
$:p
由此可以看到分区表里面已经有了刚刚创建的分区1了,这个分区将来用来存放我们的内核kernel镜像和设备树镜像文件。
下面就开始制作我们的文件系统分区,方法和上面创建分区1的步骤是一模一样的。
(2)创建文件系统分区(分区2)
①创建分区
$:n
②选择分区类型 p:主分区 e:扩展分区
$:p
③设置分区号(范围1-4,习惯性的从1开始)
$:2
④设置起始扇区(默认即可,直接回车)
提示设置Last sector or +size{,K,M.G, T} (131088-15269887,default 15269887):
然后我们直接直接回车(什么也不需要输入)
意思就是给刚刚创建的分区2分配剩余的所有内存空间。
⑤写入,保存创建的分区信息并且退出fdisk工具
$:w
⑥查看分区信息
$:fdisk mmcblk0
$:p
由此可以看到分区表里面已经有了刚刚创建的分区2了,这个分区将来用来存放我们的文件系统rootfs。
⑦退出fdisk工具
$:q
到此我们的EMMC分区操作完成。
(3)配置EMMC分区的文件系统类型
分区1:格式化成 fat32 文件系统类型
分区2:格式化成 ext4 文件系统类型
①使用fdisk工具格式化分区1的文件系统类型(fat32)
$:fdisk mmcblk0
查看帮助信息
$:m
列出已知的分区类型
$:l
改变一个分区的系统类型
$:t
选择分区1
$:1
选择文件系统类型(b Win95 FAT32)
$:b
写入,保存创建的分区信息并且退出fdisk工具
$:w
使用mkfs.vfat工具格式化分区1(mmcblk0p1)
$:mkfs.vfat mmcblkop1
②使用fdisk工具格式化分区2的文件系统类型(ext4)
$:fdisk mmcblk0
查看帮助信息
$:m
列出已知的分区类型
$:l
改变一个分区的系统类型
$:t
选择分区2
$:2
选择文件系统类型(Linux)
$:83
写入,保存创建的分区信息并且退出fdisk工具
$:w
使用mkfs.ext4工具格式化分区2(mmcblk0p2)
$:mkfs.ext4 mmcblkop2
因为我的之前操作过,所以分区2已经是ext4文件系统类型了,这里我又重新格式化了一下,所以红方框里面的内容不需要关
心。
OK,至此我们的分区算是彻底完成了。
然后就将我们之前编译好的内核kernel镜像,设备树和文件系统压缩包上传到我们的分区1和分区2。
开始!!!!!!!!!
①新建boot和rootfs两个文件夹,用于挂载分区1和分区2
$:mkdir /mnt/boot /mnt/rootfs
$:mount /dev/mmcblk0p1 /mnt/boot
$:mount /dev/mmcblk0p2 /mnt/rootfs
$:cd /mnt/boot/
$:tftp -l uImage -g 192.168.xxx.xxx
$:tftp -l devicetree.dtb -g 192.168.xxx.xxx
$:cd /mnt/rootfs/
$:tftp -l linaro-precise-developer-20120723-267.tar.gz -g 192.168.1.100
$:tar -zxvf linaro-precise-developer-20120723-267.tar.gz
$:rm linaro-precise-developer-20120723-267.tar.gz
$:cp -rf binary/boot/filesystem.dir/* ./
$:rm -rf binary/
$:umount /mnt/boot
$:umount /mnt/rootfs
$:reboot
重启系统后发现,系统可以起来了,就说明我们的操作成功了!!!