前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux NOR 开发指南

Linux NOR 开发指南

作者头像
韦东山
发布2023-02-24 09:17:23
1.3K0
发布2023-02-24 09:17:23
举报
文章被收录于专栏:韦东山嵌入式

Linux NOR 开发指南

1 简介

  • 编写目的

此文档描述Sunxi NOR 模块的使用方法,为相关人员调试提供指导

  • 适用范围
    • boot0: 适用于brandy-2.0
    • u-boot: 适用于u-boot-2018
    • kernel: 适用于linux-4.9/linux-5.4 内核

BSP 的开发人员、测试人员

2 模块介绍

2.1 模块功能介绍

Linux 中SPINOR 体系结构如下图所示:

image-20221216110030034
image-20221216110030034

SPI NOR Framework:这层主要是处理不同厂家的NOR 物理特色差异,初始化SPINOR的工作状态,如工作线宽(1 线、2 线、4 线、8 线)、有效地址位(16M 以上的NOR 需要使用4 地址模式),为上层MTD 提供读写擦接口。

代码语言:javascript
复制
对应代码目录:drivers/mtd/spi-nor/spi-nor.c
M25P80(generic SPI NOR controller driver):这层主要对SPI NOR Framework
层传下来的数据封装成msg,传递给SPI framework 层。
对应代码目录:drivers/mtd/devices/m25p80.c
SPI Framework:这层主要是将msg 加入ctl 的工作队列中,启动内核线程队列,处理队列
中的msg。
对应代码目录:drivers/spi/spi.c
SPI controller driver:这层初始化SPI 控制器频率、时钟模式、cs 有效电平、大小端等
配置,同时处理上层传下来的msg,通过CPU/DMA 方式传输数据到FIFO,再传输给外设
SPINOR。
对应代码目录:drivers/spi/spi-sunxi.c

2.2 相关术语介绍

术语

解释说明

Sunxi

指Allwinner 的一系列SOC 硬件平台

SPI

Serial Peripheral Interface,同步串行外设接口

NOR Flash

NOR Flash 是一种非易失闪存技术,是Intel 在1988 年创建

MTD

MTD(memory technology device 内存技术设备) 是用于访问memory 设备(ROM、flash)的Linux 的子系统

2.3 模块配置介绍

2.3.1 longan 的配置和打包
代码语言:javascript
复制
./build.sh config
All available platform:
	0. android
	1. linux
Choice [linux]: 1
... //配置根据需求选择
All available flash: //flash类型,只区分nor和非nor方案,Android方案无此选项,默认非nor
	0. default
	1. nor
Choice [default]: 1
  1. 打包普通固件
代码语言:javascript
复制
#./build.sh clean
#./build.sh
#./build.sh pack
  1. 打包卡打印固件
代码语言:javascript
复制
#./build.sh clean
#./build.sh
#./build.sh pack_debug

在配置的过程中会把平台目录下的BoardConfig.mk 的信息拷贝到.buildconfig 中。

2.3.2 sys_config 配置

SPINOR 的boot0 启动阶段,部分参数是从boot0 头部获取的,而这些参数是我们在打包固件时,通过工具update_boot0 将sys_config.fex 中[spinor_para],更新到boot0 头部的,sys_config.fex 的[spinor_para] 配置参数如下:

代码语言:javascript
复制
[spinor_para]
;readcmd =0x6b
;read_mode =4
;write_mode =4
;flash_size =16
;delay_cycle =1
;frequency =100000000
;erase_size =64
;lock_flag =0
;sample_delay =0
;sample_mode =2
spi_sclk = port:PC00<4><0><2><default>
spi_cs = port:PC01<4><1><2><default>
spi0_mosi = port:PC02<4><0><2><default>
spi0_miso = port:PC03<4><0><2><default>
spi0_wp = port:PC04<4><0><2><default>
spi0_hold = port:PC05<4><0><2><default>

其中:

代码语言:javascript
复制
readcmd:boot0 用于读取数据的命令,不填默认用uboot 传递过来的readcmd
read_mode、write_mode:boot0 的工作线宽(1、2、4),不填默认更加readcmd 决
定线宽
flash_size:flash 的大小
delay_cycle:boot0 的采样延时配置,大于60MHZ 配置为1,小于24MHZ 配置为2,
大于24MHZ 小于60HZ 配置为3
frequency:boot0 的SPI 工作频率,不填使用默认值50M
erase_size:boot0 的擦除单位
lock_flag:锁功能是否打开
sample_delay:boot0 的细调采样的采样延时,uboot、kernel 也会用到,默认不填等于
0xaaaaffff
sample_mode:boot0 的细调采样的采样模式,uboot、kernel 也会用到,默认不填等于
0xaaaaffff
spi_sclk、spi_cs、spi0_mosi、spi0_miso、spi0_wp 和spi0_hold 用于配置相应的GPIO。
2.3.3 UBOOT 配置
2.3.3.1 编译和配置
代码语言:javascript
复制
#make clean
#make sun8iw19p1_nor_config ----启动的uboot (#make sun8iw19p1_config----烧写uboot)
#make -j32
2.3.3.2 Menuconfig 配置
代码语言:javascript
复制
#cd brandy/brandy-2.0/u-boot-2018
#make menuconfig

进入Device Drivers

代码语言:javascript
复制
Device Drivers ---->
[*]SPI Suppport ---->
[*]Sunxi flash support ---->
image-20221216110954138
image-20221216110954138

进入SPI Support

代码语言:javascript
复制
Device Drivers ---->
[*]SPI Suppport ---->
[*]Sunxi SPI driver
image-20221216111017858
image-20221216111017858

进入sunxi_flash_support

代码语言:javascript
复制
Device Drivers ---->
[*]Sunxi flash support ---->
[*]Support sunxi spinor devices
image-20221216111039312
image-20221216111039312
2.3.4 KERNEL 配置
2.3.4.1 SPINOR-驱动配置
代码语言:javascript
复制
#cd kernel/liunx-4.9
#make ARCH=arm menuconfig

进入Device Drivers

代码语言:javascript
复制
Device Drivers ---->
<*>Memory Technology Device (MTD) support ---->
[*]SPI support ---->
image-20221216111201111
image-20221216111201111

进入Menory Technology Device(MTD) support

代码语言:javascript
复制
Device Drivers ---->
<*>Memory Technology Device (MTD) support ---->
<*>SUNXI partitioning support
<*>Direct char device access to MTD devices
<*>Caching block device access to MTD devices
Self-contained MTD device drivers ---->
SPI-NOR device support ---->
image-20221216111231797
image-20221216111231797

进入Self-contained MTD device drivers(5.4 内核不需要选择此项)

代码语言:javascript
复制
Device Drivers ---->
<*>Memory Technology Device (MTD) support ---->
Self-contained MTD device drivers ---->
<*>Support most SPI Flash chips (AT16DF, M25P.....)
image-20221216111301751
image-20221216111301751
2.3.4.2 cmdline 方式选择
代码语言:javascript
复制
Boot opttions ---->
image-20221216111354759
image-20221216111354759

进入Boot options

代码语言:javascript
复制
Boot opttions ---->
Kernel command line type ---->
image-20221216111427021
image-20221216111427021

进入kernel command line type

代码语言:javascript
复制
Boot opttions ---->
Kernel command line type ---->
(X)Use bootloade kernel arguments if available
image-20221216111454068
image-20221216111454068
2.3.4.3 文件系统配置

进入File systems

代码语言:javascript
复制
File system ---->
[*]Miscellaneous filesystems ---->
image-20221216111527624
image-20221216111527624

• 进入Miscellaneous filesystems • Incluede support for ZLIB compressed file systems (NEW) • Incluede support for LZ4 compressed file systems (NEW) • Incluede support for LZO compressed file systems (NEW) • Incluede support for XZ compressed file systems (NEW)

代码语言:javascript
复制
File system ---->
[*]Miscellaneous filesystems ---->
[*]Incluede support for XZ compressed file systems (NEW)(压缩方式选择如下)
image-20221216111604498
image-20221216111604498

以上的压缩方式(ZLIB/LZ4/LZO/XZ)具体选择哪一种需要根据longan/build/mkcmd.sh 中如下代码使用的压缩方式而定,如下代码使用的是gzip 压缩方式,则内核File systems 中配置需选择LZO 压缩方式,若使用的是xz, 则需选择XZ 压缩方式。

代码语言:javascript
复制
${ROOTFS} ${LICHEE_PLAT_OUT}/rootfs.squashfs -root-owned -no-progress -comp gzip -noappend

2.4 源码目录介绍

2.4.1 UBOOT 源码目录
代码语言:javascript
复制
\u-boot-2018\drivers
├──sunxi_flash ---sunxi_flash的初始化/退出/读/写/擦除等flash接口
├─mmc ---mmc接口代码
├─nand ---nand接口代码
├─spinor ---spi nor接口代码
├─sunxi_flash.c ---sunxi_flash操作接口
└──其他
├── spi --sunxi_spi的接口代码
├─sunxi_spi.c ---具体代码的实现
├──mtd
├─spi
├─sf_probe.c ---nand接口代码
├─spinor ---spi nor接口代码
├─sunxi_flash.c ---sunxi_flash
2.4.2 KERNEL 源码目录
代码语言:javascript
复制
\longan\kernel\linux-4.9\drivers\
├── mtd
├─spi-nor
├─spi-nor.c ---spi nor驱动代码
└──其他
├── spi --spi的接口代码
└── makefile ---编译文件
版

3 接口描述

3.1 驱动物理层接口

3.1.1 spi_nor_erase
代码语言:javascript
复制
static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)

description:mtd erase interface @mtd: MTD device structure @instr: erase operation descrition structure return:success return 0,fail return fail code**

3.1.2 spi_nor_read
代码语言:javascript
复制
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)

description:mtd read interface @mtd:MTD device structure @from: offset to read from MTD device @len: data len @retlen: had read data len @buf: data buffer return:success return max_bitflips,fail return fail code**

3.1.3 spi_nor_write
代码语言:javascript
复制
static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)

description:mtd write data interface @to: offset to MTD device @len: want write data len @retlen:return the writen len @buf: data buffer return: success return 0, fail return code fail

3.1.4 spi_nor_lock
代码语言:javascript
复制
static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
description:check block is badblock or not

@mtd:MTD device structure @ofs: offset the mtd device start (align to simu block size) @len:The length of the operating return: success return 0, fail return code fail

3.1.5 spi_nor_unlock
代码语言:javascript
复制
static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
description:check block is badblock or not

@mtd:MTD device structure @ofs: offset the mtd device start (align to simu block size) @len:The length of the operating return: success return 0, fail return code fail

3.1.6 spi_nor_is_locked
代码语言:javascript
复制
static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
description:check block is badblock or not

@mtd:MTD device structure @ofs: offset the mtd device start (align to simu block size) @len:The length of the operating return: Is lock return 1, else return 0

3.1.7 spi_nor_has_lock_erase
代码语言:javascript
复制
static int spi_nor_has_lock_erase(struct mtd_info *mtd, struct erase_info *instr)

description:mtd has lock erase interface,First unlock to operate space, after the completion of the flash lock up @mtd: MTD device structure @instr: erase operation descrition structure return:success return 0,fail return fail code

3.1.8 spi_nor_has_lock_write
代码语言:javascript
复制
static int spi_nor_has_lock_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)

description:mtd has lock write data interface,First unlock to operate space, after the completion of the flash lock up @to: offset to MTD device @len: want write data len @retlen:return the writen len @buf: data buffer return: success return 0, fail return code fail

3.2 Uboot 应用接口

3.2.1 sunxi_flash_spinor_probe
代码语言:javascript
复制
static int sunxi_flash_spinor_probe(void)

description:SPINOR initialization,Set the storage type。 return:zero on success, else a negative error code.

3.2.2 sunxi_flash_spinor_init
代码语言:javascript
复制
static int sunxi_flash_spinor_init(int boot_mode, int res)

description:SPINOR initialization。 @boot_mode:Working mode @res:The default is 0 return:zero on success, else a negative error code.

3.2.3 sunxi_flash_spinor_exit
代码语言:javascript
复制
int sunxi_flash_spinor_exit(void)

description:Release registration is a resource for applications. return:zero on success, else a negative error code.

3.2.4 sunxi_flash_spinor_write
代码语言:javascript
复制
static int sunxi_flash_spinor_write(uint start_block, uint nblock, void *buffer)

description:mtd write data interface. @start_block:want write start sector @nblock:want write sectorcount @buffer:data buffer

return:zero on success, else a negative error code.

3.2.5 sunxi_flash_spinor_write
代码语言:javascript
复制
static int sunxi_flash_spinor_write(uint start_block, uint nblock, void *buffer)

description:mtd readdata interface. @start_block:want read start sector @nblock:want read sector count @buffer:data buffer return:zero on success, else a negative error code.

3.2.6 sunxi_flash_spinor_erase
代码语言:javascript
复制
static int sunxi_flash_spinor_erase(int erase, void *mbr_buffer)

description:erase boot || partition data. @erase:erase flag @buffer:The default is NULL return:zero on success, else a negative error code.

3.2.7 sunxi_flash_spinor_force_erase
代码语言:javascript
复制
int sunxi_flash_spinor_force_erase(void)

description:erase boot & partition data. return:zero on success, else a negative error code.

3.2.8 sunxi_flash_spinor_flush
代码语言:javascript
复制
int sunxi_flash_spinor_flush(void)

description:Flush physical cache data to flash.

return:zero on success, else a negative error code.

3.2.9 sunxi_flash_spinor_download_spl
代码语言:javascript
复制
static int sunxi_flash_spinor_download_spl(unsigned char *buf, int len, unsigned int ext)

description:write boot0. @buf:boot0 data buffer @len:boot0 data len @ext:storage type return:zero on success, else a negative error code.

3.2.10 sunxi_flash_spinor_download_toc
代码语言:javascript
复制
static int sunxi_flash_spinor_download_toc(unsigned char *buf, int len, unsigned int ext)

description:write uboot. @buf:uboot data buffer @len:uboot data len @ext:storage type return:zero on success, else a negative error code.

4 使用例子

4.1 uboot shell 使用

4.1.1 sunxi_flash

mem_addr:内存地址,0x40000000 之后可以随便选取如:0x45000000,0x46000000 part_name:分区文件名,boot-resource、env、boot、rootfs size:可以省略,默认读取整个分区文件

  1. sunxi_flash read [size] 读取flash 中的分区文件到内存中 例:使用sunxi_flash read 命令将boot 分区读入到0x49000000 中,然后使用md 命令读取 0x49000000 中的内容。
image-20221216112650227
image-20221216112650227

验证方法:

  1. 0x49000000 读入前与读入后数据有没有发生变化
  2. 在out/pack_out 目录下找到对应的分区文件,使用hexdump -Cv boot.fex -n 500 命 令输出分区文件的数据,对比一致即读入成功。
image-20221216112713299
image-20221216112713299
  1. sunxi_flash write [size] 将内存中的数据,写入到分区中 例: 1)使用mm 命令修改内存内容
image-20221216112743939
image-20221216112743939

2)使用sunxi_flash write 0x44000000 env 将内存中的数据写入env 分区

image-20221216112759532
image-20221216112759532

3)重新将env 分区读入内存中,对比一致表示写入成功

image-20221216112809980
image-20221216112809980
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Linux NOR 开发指南
    • 1 简介
      • 2 模块介绍
        • 2.1 模块功能介绍
        • 2.2 相关术语介绍
        • 2.3 模块配置介绍
        • 2.4 源码目录介绍
      • 3 接口描述
        • 3.1 驱动物理层接口
        • 3.2 Uboot 应用接口
      • 4 使用例子
        • 4.1 uboot shell 使用
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档