祝各位道友念头通达
GitHub Gitee 语雀 打赏

petalinux笔记

1. petalinux 指令笔记

包含非国产zynq和国产zynq生成镜像流程

1.1 镜像文件构成方式

使用 u-boot 中的 mkimage 工具,可以将 zImage 制作为 uImage。uImage 是 u-boot 专用的镜像文件,它在 zImage 的前边加上一个 64 Byte 的“头”,描述了该内核的版本、加载位置、生成时间、大小等信息,除此以外和 zImage 没有区别

image.ub文件
 1.zImage, 内核镜像
 2.rootfs, 根文件系统
 3.system.dtb, 设备树
BOOT.BIN
 1. zynq_fsbl.elf, fsbl镜像-上电启动的第一个程序,后面才启动uboot裸机程序
 2. u-boot, 镜像
 3. system.bit, PL端的 bit文件

1.2 常用命令

petalinux-create --type project --template zynqMP --name zynqMP_nvme	## 在当前目录下生成 zynqMP_nvme 项目
petalinux-config --get-hw-description [./]                             ## 包含 .hdf 或者是 .dsp的目录
petalinux-config -c kernel                                              ## 配置内核
petalinux-config -c rootfs						#配置文件系统
petalinux-build						                ## 构建u-boot
## 打包: 参数说明, 可以根据 petalinux-package --boot --help 查看各个参数说明
## --boot意思打包BOOT.BIN, --fsbl 指向zynq_fsbl.elf, --fpga指向bitstream文件system.bit, --u-boot 指向 u-boot.elf, --kernel 指向image.ub, --force意思生成文件覆盖旧文件
petalinux-package --boot --fsbl --fpga --u-boot --force			##(SD卡启动)
petalinux-package --boot --fsbl --fpga --u-boot --kernel --force	##(FLASH启动)

1.3 配置nvme

  1. 配置内核
petalinux-config -c kernel

Check: Bus options->PCI support should 
Check: Bus options->PCI support->Message Signaled Interrupts (MSI and MSI-X) 
Check: Bus options->PCI support->Enable PCI resource re-allocation detection 
Check: Bus options->PCI support->PCI host controller drivers->Xilinx AXI PCIe host bridge support 
Enable: Device Drivers->Block devices->NVM Express block device
  1. 配置根文件系统
petalinux-config -c rootfs

Filesystem Packages->console/utils->pciutils->pciutils
Filesystem Packages->base->util-linux->util-linux  
Packages->base->util-linux->util-linux-blkid  
Packages->base->util-linux->util-linux-fdisk 
Packages->base->util-linux->util-linux-mkfs  
Packages->base->util-linux->util-linux-mount  
Packages->base->e2fsprogs->e2fsprogs  
Packages->base->e2fsprogs->e2fsprogs-mke2fs

1.4 uboot下 启动image方式

uboot主要就是用来加载内核镜像等相关文件, 以下指令都在printenv 中可以查看到相关指令的使用方式

1.4.1 从flash中启动

flash 通过地址读取, 这个地址是提前写入的, 通过网络或者tf卡将镜像读取到内存,然后直接持久化到flash中,不过需要设置相关环境

sf probe             #初始化flash
sf read 0x1000000 0x02394a80 0x1600000 #从flash中读取指定长度的系统文件到内存0x1000000中,这里读取的是 image.ub
bootm 0x1000000  # 从指定内存中启动程序

1.4.2 从tf卡的FAT32分区启动

mmc list #查看mmc设备(会显示当前tf卡的分区)
mmc dev [mmc序号] [分区] #mmc序号可以通过 mmc list 查看
mmcinfo  #查看当前mmc设备详细信息
fatload mmc 0 0x1000000 image.ub #将某个文件从mmc设备中读取到内存 0x1000000
md 0x1000000 [长度] #查看内存值是否读取正确
bootm 0x1000000  #然后通过 bootm从内核加载内核

1.5 tftp 启动

setenv serverip 192.168.1.15   ##设置ftfp服务器的地址
md 0x1000000                 # 查看内存地址 0x1000000 是否有数据,如果有可以换个地址
tftpboot 0x1000000 image.ub    # 将image.ub 从服务器加载到地址为0x1000000的内存中
bootm 0x1000000                # 启动镜像

1.6 将程序固化到flash中

//将内存地址mem_addr开始起后面 data_len 的数据长度, 写入flash偏移 flash_offset, flash_offset也可以理解flash的地址
sf write [mem_addr] [flash_offset] [data_len]

1.7 petalinux 免登录

petalinux-config --get-hw-description [./]
Yocto Settings->Enable Debug Tweaks  # 选中该选项

1.8 jtag和串口冲突,导致串口使用不了

petalinux-config -c kernel
CPU Power Management->CPU Idle->CPU idle PM support ##取消该选项

1.9 进口zynq, ARM linux 驱动开发,对设备树和kernel,rootfs的生成笔记

# 1.使用petalinux 创建工程并编译配置文件生成BOOT.BIN
petalinux-create -t project --template zynq -n ALIENTEK-ZYNQ
cd ALIENTEK-ZYNQ
petalinux-config --get-hw-description ../hdf/ #选择以下配置选择存放 .hdf 的存放目录
 > 1. image storage media(选择tf) # 配置设备树从image.ub独立开来, 从tf卡中启动
 > 2. Root filesystem type (选择tf) # 配置根文件系统放到tf卡的EXT4分区中
petalinux-build -c u-boot #会重新生成设备树, 如果生成不了,可以直接用 petalinux-build 全部编译,在image/linux *.dtsi和*.dts
petalinux-package --boot --fsbl --u-boot --force #生成BOOT.BIN,只包含zynq_fsbl.elf 和 u-boot.elf(平常还会包含system.bit)

# 2. 根据device-tree仓库生成设备树文件(和petalinux-build -c uboot相比, 该方法速度快,不需要重新编译BOOT.BIN)
2.1 下载设备树仓库: https://github.com/Xilinx/device-tree-xlnx/releases, 下载 xilinx-v2018.3
2.2 解压到 /home/hgx/tools/liunx_project/tools/device-tree
2.3 输入指令 hsi,进入 hsi指令行,并输入以下指令
open_hw_design /home/hgx/tools/liunx_project/hdf_dir/navigator_7010_wrapper.hdf
set_repo_path /home/hgx/tools/liunx_project/tools/linux-2018.3/linux-xlnx-xilinx-v2018.3
create_sw_design device-tree -os device_tree -proc ps7_cortexa9_0
generate_target -dir /home/hgx/tools/liunx_project/tools/dts #最后生成的设备树相关文件都在该目录下,可以自己指定
exit #退出

# 3. 使用官方2018.3版本的linux编译kernel
3.1 下载源码: https://github.com/Xilinx/linux-xlnx/tags, 并解压在linux目录下
3.2 将前面用设备树仓库生成的设备树: /home/hgx/tools/liunx_project/tools/dts,目录下的 pcw.dtsi, pl.dtsi, system-top.dts,zynq-7000.dtsi 直接拷贝到 arch/arm/boot/dts下
3.3 对 system-top.dts 修改,修改内容如下有介绍
3.4 在 arch/arm/boot/dts 目录下的 Makefile, 中修改如下
		zynq-zybo.dtb \
		system-top.dtb #(新添加的)
3.5 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig #根据defconfig配置.config,"./arch/arm64/configs/defconfig->./.config"
3.6 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage -j8 #编译内核zImage,在目录arch/arm/boot/下
3.7 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- system-top.dtb -j8 #编译设备树

# 4.编译 rootfs
4.1 在1中生成的petalinux 项目中,使用指令 petalinux -c rootfs
 >在debug-tweaks 选择账号登录
4.2 petalinux-build -c rootfs

# 5.拷贝SD卡,并启动
5.1 将SD卡分区,如下,使用指令 sudo fdisk /dev/tfb 制作分区,并将两个分区挂载
Disk /dev/tfb: 29.1 GiB, 31293702144 bytes, 61120512 sectors
Device     Boot  Start      End  Sectors  Size Id Type
/dev/tfb1  *      2048   206847   204800  100M  c W95 FAT32 (LBA)
/dev/tfb2       206848 61120511 60913664   29G 83 Linux
5.2 将如下文件拷贝到tf卡的FAT分区
arch/arm/boot/zImage
arch/arm/boot/dts/system-top.dtb
images/linux/system.bit
images/linux/BOOT.BIN
5.3 然后将根文件系统解压到tf卡的 EXT4分区
sudo tar -xvf images/linux/rootfs.tar.gz -C ${挂载的EXT4盘目录}
5.4 将卡查到开发板上

# 6. 修改 env环境,设置自动启动
env default -a
setenv bitstream_load_address 0x100000
setenv bitstream_image system.bit
setenv bitstream_size 0x300000
setenv kernel_img zImage
setenv dtbnetstart 0x2000000
setenv netstart 0x2080000
setenv cp_dtb2ram 'mmcinfo && fatload mmc 0:1 ${dtbnetstart} ${dtb_img}'
setenv default_bootcmd 'if mmcinfo; then run uenvboot; echo Copying Linux from SD to RAM... && load mmc 0 ${bitstream_load_address} ${bitstream_image} && fpga loadb 0 ${bitstream_load_address} ${bitstream_size} && run cp_kernel2ram && run cp_dtb2ram && bootz ${netstart} - ${dtbnetstart}; fi'

saveenv #将环境变量保存
boot/reset #启动开发板,然后会自动进入系统

最后修改的 system-top.dts

/*
 * CAUTION: This file is automatically generated by Xilinx.
 * Version: HSI
 * Today is: Thu Dec 15 17:28:45 2022
 */


/dts-v1/;
#include "zynq-7000.dtsi"
#include "pl.dtsi"
#include "pcw.dtsi"
/ {
        model = "Alientek ZYNQ Development Board";
        chosen {
                bootargs = "console=ttyPS0,115200 earlyprintk root=/dev/mmcblk0p2 rw rootwait";
                stdout-path = "serial0:115200n8";
        };
        aliases {
                ethernet0 = &gem0;
                i2c0 = &i2c2;
                i2c1 = &i2c0;
                i2c2 = &i2c1;
                serial0 = &uart0;
                serial1 = &uart1;
                spi0 = &qspi;
        };
        memory {
                device_type = "memory";
                reg = <0x0 0x20000000>;
        };
};

&gem0 {
        local-mac-address = [00 0a 35 00 1e 53];
};

&qspi {
        #address-cells = <1>;
        #size-cells = <0>;
        flash0: flash@0 {
                compatible = "n25q512a","micron,m25p80";
                reg = <0x0>;
                #address-cells = <1>;
                #size-cells = <1>;
                spi-max-frequency = <50000000>;
                partition@0x00000000 {
                        label = "boot";
                        reg = <0x00000000 0x00500000>;
                };
                partition@0x00500000 {
                        label = "bootenv";
                        reg = <0x00500000 0x00020000>;
                };
                partition@0x00520000 {
                        label = "kernel";
                        reg = <0x00520000 0x00a80000>;
                };
                partition@0x00fa0000 {
                        label = "spare";
                        reg = <0x00fa0000 0x00000000>;
                };
        };
};

2 国产zynq 对 FSBL、设备树、uboot、系统镜像生成流程

2.1 设备树 和 FSBL的生成

1.新建 procise 工程
2.点击 "Create Block Design" -> 输入新创建名 "system" -> 回车
3.在 tab页面"system.bd" 处右击 "Add IP" -> 选中 "processing_system7:1.0" -> 回车添加即可
4.双击"IP核"设置对应的外设管脚, 一般有 "flash", "以太网", "uart"等。
5.在 source 标签栏下右击 "system_i" -> 选择 "Generate Output Products" -> 双击即可
6.在工具栏中点击 "PSOC" -> 选中 "Repositories" -> 其中 "Local Repositorie" 中只能有一个仓库 -> 点击退出
7.在 source 标签栏下右击 "system_i" -> 选择 "Export Hardware ..." -> 选择 "FSBL" 和 "DeviceTree"
8.然后打开项目的位置, 打开"../SDK/system_platform"
9.然后双击 "system_platform.eww", 然后, 用IAR 编译"Make", 生成 "FSBL.out" 即可生成 FSBL程序
10.其中DeviceTree就是生成的设备树, 直接拷贝到linux环境下用于编译 uboot
补充:
11.如果JTAG的线是在PL连的话, 第一次烧写使用IAR需要线烧写bit
12.在步骤3中, 如果是从 vivadio 导入的文件 "system.bd" 和 "system_processing_system7_0_0.xci", 就可以不用去自己设置IP核

2.2 设备树的编译 和 uboot 生成

1.将文件 "FMQL-Linux-SDK_20201022.tar.bz2" 拷贝到 具有"petalinux" 环境的linux系统, 然后解压
2.将生成设备树的步骤"10"中,将生成的设备树拷贝到linux中
3.然后 进入"FMQL-Linux-SDK_20201022",输入"source env.sh"
4.编辑 "SDK_20201022/device-tree/xlnx-dts/openhdf.sh" 文件第"8"行, 添加"petalinux"安装目录
5.输出指令 "./build.sh --hw /home/{user_name}/Downloads/DeviceTree/ --nofpga dtb", 其中 "--nofpga" 是忽略"PL"部分, 如果包含fpga部分,则需要输入 "./build.sh --hw /home/{user_name}/Downloads/DeviceTree/ --hdf xxx/xxx.hdf dtb"
6.就会生成在"FMQL-Linux-SDK_20201022/images"目录下生成 "system-top.dtb"
7.然后进入"FMQL-Linux-SDK_20201022/u-boot-2018.07-fmsh"目录下
8.输入指令 "make fmql_common_defconfig" 生成 ".config" 配置文件
9.输入指令 "make EXT_DTB=../images/system-top.dtb -j4" 编译 "uboot"
10.在 "FMQL-Linux-SDK_20201022/u-boot-2018.07-fmsh"目录中会出现 "u-boot.bin" 和 "u-boot.elf" 文件, "u-boot.bin" 用于制作 "BOOT.bin"

2.3 根文件系统的生成

1.进入"FMQL-Linux-SDK_20201022/buildroot-2018.02.3" 目录下
2.输入"make fmsh_tiny_defconfig" 生成 ".config"文件
3.输入"make busybox-dirclean" 和 "make initscripts-dirclean" 清除之前编译的
4.然后输入 "make" 进行编译
5.编译完成后 "FMQL-Linux-SDK/buildroot-2018.02.3/output/images"目录下将生成多种格式的 "rootfs" 文件
6. 进入目录 output/images
mkdir rootfs && cd rootfs
sudo cpio -i < ../rootfs.cpio      #使用root解压 rootfs.cpio
sudo find . | sudo cpio -H newc -o| gzip -9 > ../rootfs.cpio.gz #使用root权限打包
cd ../ && sudo cp roofs.cpio.gz ../../../images
7. "rootfs.cpio.gz" 将用于制作 "image.ub"

2.4 uImage 系统镜像生成

1)Image 内核镜像文件
2)zImage 压缩的内核镜像文件
3)uImage 是 u-boot 专用镜像, 相比 zImage 多了 64Byte 的头,用来描述内核版本,加载位置, 生成时间,大小位置等信息

1.进入 "FMQL-Linux-SDK_20201022/ linux-4.14.55-fmsh" 目录中
2.输入 "make fmsh_fmql_defconfig" 生成 ".config" 配置文件, 然后输入 "make -j4" 开始执行编译
3.生成的镜像位于 "arch/arm/boot" 目录下, "ZImage" 格式的镜像用于制作 "image.ub"

2.5 image.ub 镜像的生成

1.选择制作的类型, 编辑"FMQL-Linux-SDK_20201022/env.sh" 中的 "IMAGE_TYPE"为 "ramdisk"
2.需要上述生成的文件"system-top.dtb","zImage","rootfs.cpio.gz","Image" 拷贝到目录"FMQL-Linux-SDK_20201022/images" 下
3."FMQL-Linux-SDK_20201022" 目录下, 输入 "./build.sh image", 开始制作 "image.ub" 镜像
4."FMQL-Linux-SDK_20201022/image" 目录下会生成 "image.ub"文件

image

2.6 BOOT.bin 生成

BOOT.binFSBL.out, system.bit, u-boot/u-boot.elf 合并而成, 烧进去之后, 直接烧镜像 "image.ub" 即可

1.打开 "Star Procise", 点击 工具栏中的 "PSOC" -> "Create Boot Image"
2.点击add, 添加"FSBL.out", "system.bit"(如果有PL需要加), "u-boot"/"u-boot.elf", 然后点击 "Create Image" 即可生成

image

碰见的问题

1. uboot下和liunx环境下, flash 识别不到和分区创建

通过电路图可知, "flash" 存储器型号为 XM25QH256CXIQT08S, 大小为 250Mb(32MB),
通过设备树修改, 将flash 最后的4MB大小创建分区, 用于系统挂载,存放文件
在 "uboot" 源码下 u-boot-2018.07-fmsh/drivers/mtd/spi/spi_flash_ids.cspi_flash_ids[]数组中添加对应flash型号
linux-4.14.55-fmsh/drivers/mtd/spi-nor/spi-nor.cspi_nor_ids[]数组中添加对应flash id
eg: { "n25q256abcd", INFO(0x204019, 0, 64*1024, 512, SECT_4K) },, 其中 0x204019 需要在手册中查看

2. 自启动脚本设置

buildroot-2018.02.3/package/initscripts/init.d 目录下创建脚本

#!/usr/bin/env sh
echo -e "---------------------------\n"
# 挂载盘
# 执行挂载盘中的脚本或者程序

然后在 重新走下 2.3 步骤,生成跟文件系统

petalinux 驱动开发笔记

设备号

  1. 设备号的类型为 unsigned int, 其中高12bit为主设备号(0~4095), 低20位为 次设备号
#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)

#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

宏 MINORBITS 表示次设备号位数,一共是 20 位。
宏 MINORMASK 表示次设备号掩码。
宏 MAJOR 用于从 dev_t 中获取主设备号,将 dev_t 右移 20 位即可。
宏 MINOR 用于从 dev_t 中获取次设备号,取 dev_t 的低 20 位的值即可。
宏 MKDEV 用于将给定的主设备号和次设备号的值组合成 dev_t 类型的设备号。
2. 设备号分配, 静态分配和动态分配
静态设备容易起冲突, 在注册前可以动态申请设备号

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name); //申请动态设备号
void unregister_chrdev_region(dev_t from, unsigned count); //释放设备号

LICENSE 和作者信息

LICENSE 是必须添加的

MODULE_LICENSE("GPL");  //LICENSE 采用 GPL 协议。
MODULE_AUTHOR("alientek");

printk输出级别

include/linux/kern_levels.h 中包含了 prink输出的级别
include/linux/printk.h CONSOLE_LOGLEVEL_DEFAULT 默认输出级别

编译驱动并加载

1. 设置 Makefile

KERN_DIR:=/home/hgx/tools/liunx_project/tools/linux-2018.3/linux-xlnx-xilinx-v2018.3
obj-m := driver_char.o #要编译的driver_char.c文件

all:
	make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERN_DIR) M=`pwd` modules

clean:
	make -C $(KERN_DIR)=`pwd` clean

2. 加载 驱动

  1. 将 xx.ko 直接拷贝到开发板中的linux中
  2. 然后使用 insmod/modprobe xxx.ko 加载驱动
  3. cat /proc/devices 查看设备号`
  4. mknod /dev/chrdevbase c 200 0 根据设备号创建节点文件
  5. 在ubuntu中编写用户态代码对/dev/chrdevbase文件进行读写测试, 并使用 arm-linux-gnueabihf-gcc xxx.c -o xxx
  6. 然后将编译完的文件直接拷贝到开发板上直接 运行即可
posted @ 2022-04-08 10:12  韩若明瞳  阅读(1459)  评论(0编辑  收藏  举报