新唐NUC980使用记录:U-Boot & Linux 编译与烧录(基于SPI NAND)

2023-11-01

目的

这篇文章中将测试在 NUC980 中运行Linux系统(基于SPI NAND)。

本文相关的开发环境准备请查看下面这篇文章:
《新唐NUC980使用记录:开发环境准备与编译配置基础说明》

这篇文章中内容均在下面的开发板上进行测试(理论上也可以在新唐官方NUMAKER NUC980 IIOT开发板中进行测试):
《新唐NUC980使用记录:自制开发板(基于NUC980DK61YC)》

开发板上在QSPI上接了型号为W25N01GVZEIG的SPI NAND。

开始前请将将开发板的USB0和UART0都接到Windows电脑上,电脑上使用终端工具连接UART0。另外拨动拨动开关将PG[9:8]设置为01,以使用SPI NAND 4-bit模式。

U-Boot编译

NUC980 U-Boot针对不同启动源的修改调整具体参考BSP包中的文档《NUC980 U-Boot v2016_11 User Manual》。

我这里使用自制的开发板所以从nuc980_evb.h和nuc980_defconfig这对最基础的配置上进行修改:

cd ~/nuc980-sdk/ 
cd NUC970_U-Boot_v2016.11/

修改配置文件:

# cp include/configs/nuc980_evb.h include/configs/nuc980_evb.h.original
gedit include/configs/nuc980_evb.h

配置文件中找到对应位置进行修改:

#define CONFIG_SYS_USE_SPIFLASH // 47行 启用SPI FLASH
#define CONFIG_SYS_USE_NANDFLASH
#define CONFIG_ENV_IS_IN_NAND
/*#define CONFIG_ENV_IS_IN_SPI_FLASH */
/*#define CONFIG_ENV_IS_IN_MMC */

/****************************************/

#ifdef CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET       0x80000
#define CONFIG_ENV_SIZE         0x20000 // 129行 调整uboot环境变量存储区域大小

// include/configs/nuc980_evb.h 这个文件中还定义了很多位置和大小的参数
// 比如bootm命令启动的内核最大尺寸、NAND的分区设置等,可以按照需求调整

修改配置选项:

# make distclean
make nuc980_defconfig
make menuconfig

配置选项中找到对应位置进行设置:
在这里插入图片描述
在这里插入图片描述

进行编译:

export PATH=$PATH:/home/nx/nuc980-sdk/arm_linux_4.8/bin
make

编译完成后u-boot.bin位于当前目录下,对于NAND而言还需要spl目录下的u-boot-spl.bin。将其拷贝至Windows中进行烧录。比如我的 /media/sf_common/ 是和Windows共享的目录,拷贝到这里即可:

# 拷贝至Windows电脑上
# sudo cp u-boot.bin /media/sf_common/
# sudo cp spl/u-boot-spl.bin /media/sf_common/

拨动拨动开关将PG[1:0]设置为00,按下复位键。在Windows中使用NuWriter进行烧录:
在这里插入图片描述
在这里插入图片描述

烧录完成后拨动拨动开关将PG[1:0]设置为11,按下复位键。可以在终端界面中看到启动信息:
在这里插入图片描述

U-Boot环境变量

U-Boot最重要的是用来启动 Linux Kernel 的,比较常用的做法是使用U-Boot环境变量中设置的参数来读取内核镜像,然后启动内核。

环境变量可以写死在U-Boot程序中,可以使用U-Boot命令来设置,也可以通过烧录工具烧录到保存环境变量的存储区域。下面是最后一种方式的演示:

拨动拨动开关将PG[1:0]设置为00,按下复位键。在Windows中使用NuWriter进行烧录(如果选择时看不到文件,弹窗右下角选择All Files):
在这里插入图片描述
烧录完成后拨动拨动开关将PG[1:0]设置为11,按下复位键。可以在终端界面中看到启动信息:
在这里插入图片描述

上面烧录的环境变量如下:

bootdelay=3
baudrate=115200
stderr=serial
stdin=serial
stdout=serial
loadkernel=nand read 0x7fc0 0x200000 0x1000000
bootcmd=run loadkernel;bootm 0x7fc0

上面环境变量中使用 nand 命令从nand的0x200000位置读取0x1000000大小(16M)的数据到内存0x7fc0位置;然后启动位于内存0x7fc0开始的程序。当然因为现在还没有烧录内核所以启动会失败。

Linux编译

默认设置

NUC980 U-Boot针对不同启动源的修改调整具体参考BSP包中的文档《NUC980 Linux 4.4 BSP User Manual》。

我这里使用自制的开发板所以以nuc980_defconfig这个最基础的配置进行使用:

cd ~/nuc980-sdk/ 
cd NUC980-linux-4.4.y/

套用配置:

# make distclean
make nuc980_defconfig

进行编译:

export PATH=$PATH:/home/nx/nuc980-sdk/arm_linux_4.8/bin
make uImage

注意默认配置下编译时会将 NUC980-linux-4.4.y 同级的 rootfs 目录打包进内核(作为ramfs启动),同时会将编译出的镜像 980uimage 放到 NUC980-linux-4.4.y 同级的 image 目录中。

将其拷贝至Windows中进行烧录。比如我的 /media/sf_common/ 是和Windows共享的目录,拷贝到这里即可:

# 拷贝至Windows电脑上
# sudo cp ../image/980uimage /media/sf_common/

拨动拨动开关将PG[1:0]设置为00,按下复位键。在Windows中使用NuWriter进行烧录(如果选择时看不到文件,弹窗右下角选择All Files):
在这里插入图片描述
烧录完成后拨动拨动开关将PG[1:0]设置为11,按下复位键。可以在终端界面中看到启动信息:
在这里插入图片描述

使用SPI NAND剩余分区

前面U-Boot配置文件中对NAND的分区设置中除去U-Boot、环境变量、内核等需要的空间,剩余空间都被分配为user分区。但是上面默认编译出来的内核并没有把这个分区用起来,如果想用的话需要进行调整。

首先内核要支持对应的 SPI NAND 芯片型号:

# 我这里使用的W25N01GV已经默认包含了,所以不需要调整
# gedit drivers/mtd/nand/nand_ids.c

接着要确保相关芯片驱动:

gedit arch/arm/mach-nuc980/dev.c

找到对应位置进行修改:

// SPI NAND使用驱动为mt29f

static struct flash_platform_data nuc980_qspi0_flash_data = {
// 下面838行加上默认配置中对应开发板CONFIG_BOARD_NUC980
#if defined(CONFIG_BOARD_IOT) || defined(CONFIG_BOARD_ETH2UART) || defined(CONFIG_BOARD_LORAG) || defined(CONFIG_BOARD_NUC980)
	.name = "mt29f",
#else
	.name = "m25p80",
#endif
	.parts = nuc980_qspi0_flash_partitions,
	.nr_parts = ARRAY_SIZE(nuc980_qspi0_flash_partitions),
	.type = "mx66l51235l",

};

/****************************************/

// 下面854行加上默认配置中对应开发板CONFIG_BOARD_NUC980
#if defined(CONFIG_BOARD_IOT) || defined(CONFIG_BOARD_ETH2UART) || defined(CONFIG_BOARD_LORAG) || defined(CONFIG_BOARD_NUC980)
		.modalias = "mt29f",
#else
		.modalias = "m25p80",
#endif

修改配置选项:

# make distclean
make nuc980_defconfig
make menuconfig

配置选项中找到对应位置进行设置:
在这里插入图片描述
上面mode也可以设置为 Quad mode ,使用时读写速度会更快些。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

重新编译烧录内核就可以看到效果了:

# export PATH=$PATH:/home/nx/nuc980-sdk/arm_linux_4.8/bin
# make uImage
# sudo cp ../image/980uimage /media/sf_common/

在这里插入图片描述

使用SPI NAND YAFFS2作为rootfs

前面的使用中根据默认配置,用的是ramfs,这个对嵌入式设备来说是挺不错的,可以有效防止断电引起的文件系统出错的问题,缺点就是无法在烧录后运行时对rootfs修改保存。通常直接使用flash上多余的分区存放rootfs是更加常见的做法。

在上节的基础上取消ramfs,然后设置从flash分区启动rootfs:
在这里插入图片描述
在这里插入图片描述
上面启动命令如下:
noinitrd root=/dev/mtdblock2 rootfstype=yaffs2 rootflags=inband-tags console=ttyS0,115200n8 rdinit=/sbin/init mem=64M

修改后重新编译内核并烧录:

# export PATH=$PATH:/home/nx/nuc980-sdk/arm_linux_4.8/bin
# make uImage
# sudo cp ../image/980uimage /media/sf_common/

要使用SPI NAND YAFFS2作为rootfs,还需要制作可供烧录到flash中的rootfs数据。新唐的NUC980_Linux_Applications项目中的yaffs2utils套件工具可以将rootfs目录转化为可供烧录的数据。

cd ~/nuc980-sdk/ 
cd NUC980_Linux_Applications/yaffs2utils/

make
# 编译生成的 mkyaffs2 就是我们需要的工具了
# 把工具临时添加到环境变量
export PATH=$PATH:/home/nx/nuc980-sdk/NUC980_Linux_Applications/yaffs2utils

cd ~/nuc980-sdk/ 
# 将当前目录下的rootfs目录打包成数据文件
mkyaffs2 --inband-tags -p 2048 rootfs rootfs_yaffs2.img
# --inband-tags:yaffs2的tag儲存在DATA區塊 / -p:設定NAND Flash頁的大小(Page Size)
# 当前目录下的 rootfs_yaffs2.img 就是需要的数据了
# sudo cp rootfs_yaffs2.img /media/sf_common/

在这里插入图片描述
修改后的内核和文件系统烧录完成后就可以测试了:
在这里插入图片描述

打包镜像

上面烧录过程都是分块一个个进行的,烧录不同的内容还需要设置不同的参数,开发中这样没问题,但是批量烧录时这样并不方便。使用NuWriter工具可以将所有需要的内容打包成一个镜像,烧录时也只要烧录这一个镜像即可。

下面是打包生成镜像演示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

镜像使用非常方便,并不需要关系地址参数等:
在这里插入图片描述

如果觉得镜像文件存放占空间的话可以镜像压缩(使用前需要解压):
在这里插入图片描述

更多内容可以参考BSP包中的文档《NUC980 NuWriter User Manual》。

总结

根据上面的内容基本可以基于SPI NAND在NUC980上运行起系统来了。接下来使用中更多的是根据需求对kernel、rootfs、application的调整编写等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

新唐NUC980使用记录:U-Boot & Linux 编译与烧录(基于SPI NAND) 的相关文章

  • 从 csv 文件中删除特定列,保持输出上的相同结构[重复]

    这个问题在这里已经有答案了 我想删除第 3 列并在输出文件中保留相同的结构 输入文件 12 10 10 10 10 1 12 23 1 45 6 7 11 2 33 45 1 2 1 2 34 5 6 I tried awk F 3 fil
  • nginx 上的多个网站和可用网站

    通过 nginx 的基本安装 您的sites available文件夹只有一个文件 default 怎么样sites available文件夹的工作原理以及如何使用它来托管多个 单独的 网站 只是为了添加另一种方法 您可以为您托管的每个虚拟
  • Jenkins中找不到环境变量

    我想在詹金斯中设置很多变量 我试过把它们放进去 bashrc bash profile and profile of the jenkins用户 但 Jenkins 在构建发生时找不到它们 唯一有效的方法是将所有环境变量放入Jenkinsf
  • 如何根据 HTTP 请求使用 Python 和 Flask 执行 shell 命令并流输出?

    下列的这个帖子 https stackoverflow com questions 15092961 how to continuously display python output in a webpage 我能够tail f网页的日志
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 为什么 Linux perf 使用事件 l1d.replacement 来处理 x86 上的“L1 dcache misses”?

    在英特尔 x86 上 Linux用途 https stackoverflow com a 52172985 149138事件l1d replacements来实施其L1 dcache load misses event 该事件定义如下 计数
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • 我可以从命令行打印 html 文件(带有图像、css)吗?

    我想从脚本中打印带有图像的样式化 html 页面 谁能建议一个开源解决方案 我使用的是 Linux Ubuntu 8 04 但也对其他操作系统的解决方案感兴趣 你可以给html2ps http user it uu se jan html2
  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • 如何在apache 2.4.6上安装apxs模块

    我刚刚用过apt get update我的 apache 已更新为2 4 6 我想安装 apxs 来编译模块 但收到此错误 The following packages have unmet dependencies apache2 pre
  • Linux:如何从特定端口发送TCP数据包?

    如何打开原始套接字以从特定 TCP 端口发送 我希望所有连接始终来自临时端口以下的一系列端口 如果您正在使用raw套接字 然后只需在数据包标头中填写正确的 TCP 源端口即可 相反 如果您使用 TCP 套接字接口 socket connec
  • 安装J语言的JQt IDE,出现错误

    我一直按照这里的说明进行操作 http code jsoftware com wiki System Installation Linux http code jsoftware com wiki System Installation L
  • docker容器大小远大于实际大小

    我正在尝试从中构建图像debian latest 构建后 报告的图像虚拟大小来自docker images命令为 1 917 GB 我登录查看尺寸 du sh 大小为 573 MB 我很确定这么大的尺寸通常是不可能的 这里发生了什么 如何获
  • 多处理:仅使用物理核心?

    我有一个函数foo它消耗大量内存 我想并行运行多个实例 假设我有一个有 4 个物理核心的 CPU 每个核心有两个逻辑核心 我的系统有足够的内存来容纳 4 个实例foo并行但不是 8 个 此外 由于这 8 个核心中的 4 个是逻辑核心 我也不
  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • ftrace:仅打印trace_printk()的输出

    是否可以只转储trace printk 输出于trace文件 我的意思是过滤掉函数跟踪器 或任何其他跟踪器 中的所有函数 一般来说 您可以在选项目录中关闭选项 sys kernel debug tracing options Use ls显
  • 如何确保应用程序在 Linux 上持续运行

    我试图确保脚本在开发服务器上保持运行 它会整理统计数据并提供网络服务 因此它应该会持续存在 但一天中有几次 它会因未知原因而消失 当我们注意到时 我们只需再次启动它 但这很麻烦 并且某些用户没有权限 或专有技术 来启动它 作为一名程序员 我
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute

随机推荐

  • 综述如何开展代码审计

    目录 1 大体流程 1 1审计准备阶段 1 2审计实施阶段 1 3审计报告阶段 1 4改进跟踪阶段 2 审计准备工作 2 1明确审计目的 2 2签署保密协议 2 3熟悉应用程序 2 4制定检查列表 3 审计实施过程 3 1信息收集 3 2安
  • stm32按键上拉或者下拉输入的设置

    当K 1表示按下时 均采用下拉输入 不接信号时是低电平 用来检测是否有高电平信号输入 相反则上拉
  • opencv-实现双线性插值

    双线性源码 https blog csdn net love image xie article details 87969405 五个都有的 https blog csdn net carson2005 article details 2
  • 【C语言进阶】 指针进阶(一)

    博客主页 小王又困了 系列专栏 C语言 人之为学 不日近则日退 感谢大家点赞 收藏 评论 目录 一 字符指针 二 指针数组 通过类比的方法来认识指针数组 2 1指针数组的一般形式 2 2指针数组模拟实现二维数组 三 数组指针 通过类比的方法
  • 微分方程和向量场

    文章目录 自治的 时间齐次的 一阶微分方程 里普菲茨连续性 picard lindelof定理 解的存在性与唯一性 解的全局性 微分方程解的特殊情况 微分方程解法 自治的 时间齐次的 一阶微分方程 x
  • 迪文串口屏幕DMG10600T101_01WTR实现图片切换并和串口通讯

    1 我用的迪文屏幕 型号为DMG10600T101 01WTR 分辨率为1024 600 基本参数是10寸的 12V供电的电阻触摸屏 带两个串口通讯 产品背面有一个电平切换的电阻 如下图 如果是用于TTL电平 就需要和我一样用锡短接或者接0
  • 基于Kubeadm部署Kubernetes1.13.3 HA 高可用集群

    Table of Contents 目录 基于Kubeadm部署Kubernetes1 13 3 HA 高可用集群 01 部署目的 1 1 Kubernetes的特性 1 2 贴微服务 开发环境快速部署 02 环境说明 2 1 集群说明 0
  • 为什么插入buffer能够增加驱动能力?

    1 buffer是什么 所谓增加buffer buffer一般是几级器件尺寸逐步增大的反相器或类似结构的电路 以使得电阻在获得所需的驱动能力时 在功耗延时积上也达到最优 前后级的最佳驱动比例在2 718左右 buffer实际就是两个串联的反
  • 【环境】ceres库在ubantu的qt上配置

    一直没找到比较好的解决静态库的问题 最后还是投降使用了动态库 记录一下 1 版本信息 安装的是1 4 够用而且不会出现2 1版本的奇怪问题 2 安装教程 wget c https github com ceres solver ceres
  • 简易版炸金花

    import java util ArrayList import java util Iterator import java util List import java util Random public class Poker 创扑
  • mybatis与表对应的对象中忽略某些指定的字段

    最近在开发的时候遇到了一个特殊的需求 在与表对应的对象中需要添加几个该表中没有的字段 刚开始一听懵逼了 后来缕了一下 恍然大悟 其实说白了就是在和数据库进行映射的时候 对象中有的字段不必要去映射 看下面的例子 TableName A pub
  • exp远程导出oracle数据,本地导入的方法(实测通过)

    一 单表导出和导入 1 单表导出数据 其中10 10 xxx xx是远程数据库的ip db是数据库用户名 work是数据库用户密码 invt head 是表名 远程导出表数据 进口 exp db work 10 10 xxx xx 1521
  • deepin 15.11 安装nvidia driver和cuda 10

    最近看新闻华为的笔记本在适配deepin系统 所以特地安装试玩 确实比ubuntu漂亮些 且适配了大量常用应用 感觉可以不用切windows了 由于要用显卡开发deep learning相关应用 所以首先得安装闭源驱动和cuda 下面是具体
  • 如何创建自己的SeetaFace Identification工程

    如何创建自己的SeetaFaceIdentification工程 不重点说明的流程和SeetaFace Alignment的教程是一样的 只是将相应的东西改为Identification文件下下面的东西 一 如何创建FaceIdentifi
  • BUCK同步整流

    图一 buck电路 开关电源相对于LDO来说具有输出电流大以及效率高等优点 由图一可以看到buck电路的损耗除了电感内阻 以及开关管SW的损耗 开关损耗 导通损耗 外还有二极管存在一定的损耗 在电压输入输出电压较大的情况下可以暂时不进行考虑
  • nvue页面的text标签显示多行文本

    uniapp中的nvue页面文本必须放在text标签里面 否则不能设置字体大小和颜色 且只能显示一行 如果想显示多行 则需要使用rich text标签 text和rich text如果需要显示省略号 可以使用lines和text overf
  • crontab定时任务执行未成功,手动执行却可以的问题解决

    Linux里定时任务crontab执行脚本未成功 手动在shell行执行可以成功 在工作中 我们在liunx的服务器环境上去用脚本来跑一些程序和服务 大部分在需要多次或者持续性 间断性的去跑 通过手动人为的方式去执行比较繁琐 比如在遇到程序
  • Win10 + C++ + Paddle进行OCR文字识别 Cmake编译

    1 下载文件并保存到D盘 1 1 PaddleOCR 项目文件下载1 1 2 下载推理模型 PaddleOCR 项目文件下载2 1 4 下载推理库 1 5 下载Opencv3 4 1 6 解压到指定目录 在系统变量 Path 的末尾添加 C
  • java压缩解压文件工具类

    controller中使用 PostMapping value importZip public Result
  • 新唐NUC980使用记录:U-Boot & Linux 编译与烧录(基于SPI NAND)

    文章目录 目的 U Boot编译 U Boot环境变量 Linux编译 默认设置 使用SPI NAND剩余分区 使用SPI NAND YAFFS2作为rootfs 打包镜像 总结 目的 这篇文章中将测试在 NUC980 中运行Linux系统