新唐NUC980使用记录:U-Boot & Linux 编译与烧录(基于SD1位置SD卡)

2023-11-03

目的

这篇文章中将测试在 NUC980 中运行Linux系统(基于SD1位置SD卡)。

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

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

开始前请将将开发板的USB0和UART0都接到Windows电脑上,电脑上使用终端工具连接UART0。另外拨动拨动开关将PG[9:8]设置为非11的状态(比如01),以配合PG[1:0]=01使用SD1

SD卡分区

嵌入式Liunx系统通常分为Bootloader、Linux Kernel、RootFS三个部分,三个部分分别存储在三个位置中。具体对于SD卡而言存储分布如下:

  • Bootloader放在开头1M以内位置上(这部分空间通常分区工具分区时会自动跳过);
    通常还需跳过开头至少512Bytes,这部分用于保存SD卡分区信息;
  • Linux Kernel放在第一个分区上,通常使用FAT32(vfat)格式分区,通常不需要太大;
  • RootFS放在第二个分区上,分区文件系统可以根据需求选择,这个可以大点,甚至分配剩下所有的空间;

SD卡可以通过读卡器在电脑上进行分区。Ubuntu上可以使用 GParted 工具进行分区:
安装方式: sudo apt install gparted
在这里插入图片描述
上面分区中唯一需要注意的是必须有一个fat32格式的分区(通常是第一个分区),用来存放内核和设备树等,不需要很大。

当然Ubuntu上也可以选择使用命令行方式进行分区:

# 先将SD卡插入Ubuntu中
# 使用 lsblk 查看SD卡设备号sdX
# 我这里显示为sdb,下面均以此进行说明

# 如果已经分过区了那么Ubuntu可能会自动挂载
# 逐条使用 sudo umount /dev/sdbn 进行卸载

# 对SD(TF)卡进行分区
sudo fdisk /dev/sdb
# 如果有分区的话可以输入 d 回车依次删除
# 输入 n 新建分区,分区大小根据需要设置即可
# 下面是我新建的两个分区的输入情况
# n回车  回车(p)  回车(1)  回车(2048)  +32M回车  (如果有额外提示则Y回车)
# n回车  回车(p)  回车(2)  回车(67584) +200M回车  (如果有额外提示则Y回车)
# 输入 w 回车保存退出,输入使用 lsblk 查看分区情况

# 格式化分区建立文件系统
sudo mkfs.vfat /dev/sdb1
sudo mkfs.ext4 /dev/sdb2

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 */
/*#define CONFIG_SYS_USE_NANDFLASH */ // 屏蔽
/*#define CONFIG_ENV_IS_IN_NAND */ // 屏蔽
/*#define CONFIG_ENV_IS_IN_SPI_FLASH */
#define CONFIG_ENV_IS_IN_MMC // 51行 启用MMC

// include/configs/nuc980_evb.h 这个文件中还定义了很多位置和大小的参数

修改配置选项:

# make distclean
make nuc980_defconfig
make menuconfig

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

进行编译:

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

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

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

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

完成后拨动拨动开关将PG[1:0]设置为01,按下复位键。可以在终端界面中看到启动信息:
在这里插入图片描述
在这里可以识别到SD卡的分区情况,可以用fat系列指令查看或读取SD卡上的fat32格式分区中内容,后面U-Boot就是从这个分区中读取内核镜像到内存中执行的。

U-Boot环境变量

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

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

烧录U-Boot环境变量需要将SD卡插在开发板上。拨动拨动开关将PG[1:0]设置为00,按下复位键。在Windows中使用NuWriter进行烧录(如果选择时看不到文件,弹窗右下角选择All Files):
在这里插入图片描述

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

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

bootdelay=3
baudrate=115200
stderr=serial
stdin=serial
stdout=serial
loadkernel=fatload mmc 0:1 0x7fc0 980uimage
bootcmd=run loadkernel;bootm 0x7fc0

上面环境变量中使用 fatload 命令从SD卡的第一个分区中读取 980uimage 文件到内存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 目录中。将其拷贝至SD卡的第一个分区中即可。

我这里先将其拷贝至Windows中再拷贝到SD卡中。比如我的 /media/sf_common/ 是和Windows共享的目录,先拷贝到这里:

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

使用读卡器在Windows中将内核镜像拷贝到SD卡第一分区后,把SD卡插回开发板,重启后可以在终端界面中看到启动信息:
在这里插入图片描述

除了将内核镜像拷贝到Windows上后再拷贝到SD卡中,也可以直接在Ubuntu中拷贝到SD卡中:
在这里插入图片描述
可以在文件管理器中拷贝,也可以在终端中通过命令拷贝:

# cp ../image/980uimage /media/nx/BOOT/

使用SD卡剩余分区

上面默认编译出来的内核并没有使用SD卡的功能,没有把SD卡空间利用起来,如果想用的话需要进行调整。

修改配置选项:

# make distclean
make nuc980_defconfig
make menuconfig

开启内核对SD卡的支持:
在这里插入图片描述
因为第二分区文件系统使用的了EXT4格式,所以还需要开启内核相关支持:
在这里插入图片描述

重新编译拷贝内核就可以看到效果了:

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

在这里插入图片描述

使用SD卡分区存放rootfs

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

在上节的基础上取消ramfs,然后设置从SD卡第二分区启动rootfs:
在这里插入图片描述
在这里插入图片描述
上面启动命令如下:
console=ttyS0,115200n8 noinitrd rootfstype=ext4 root=/dev/mmcblk0p2 rw rootwait mem=64M

重新编译拷贝内核:

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

接着需要把rootfs内容拷贝到SD卡第二分区:

# sudo rm -rf /media/nx/rootfs/*
sudo cp -r ../rootfs/* /media/nx/rootfs/

启动测试:
在这里插入图片描述

制作系统镜像

SD卡方式下制作系统镜像最简单的方式就是直接拷贝现成可用的SD卡数据。当然这种方式下SD卡分区建议不要设置太大,因为制作出来的原始镜像大小和SD卡上有用分区大小差不多。一般boot分区有个十几二十兆就够用了,rootfs分区可以根据需求来设置。
在这里插入图片描述

下面是制作镜像的过程(在Ubuntu中进行):

# 先将SD卡插入Ubuntu中
# 使用 lsblk 查看SD卡设备号sdX
# 我这里显示为sdb,下面均以此进行说明

# 如果已经分过区了那么Ubuntu可能会自动挂载
# 逐条使用 sudo umount /dev/sdbn 进行卸载

# 创建镜像文件
touch nuc980-system-image.bin
# 将SD卡中有用的数据写入到镜像文件中
# 大小为 1M(uboot) + 40M(bootfs) + 160M(rootfs) + 2M(多拷贝点,防止不明意外)
# 数据比较大会花点时间
sudo dd if=/dev/sdb of=nuc980-system-image.bin bs=1M count=203

# 压缩镜像文件
# zip nuc980-system-image.zip nuc980-system-image.bin

# sudo cp nuc980-system-image.zip /media/sf_common/

镜像文件使用时推荐用 BalenaEtcher ,这个工具支持windos、macos、linux,其官方页面和项目地址分别如下:
https://www.balena.io/etcher/
https://github.com/balena-io/etcher

BalenaEtcher可以将系统镜像(.zip或是.bin格式都行)直接烧录到SD卡上。

总结

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

基本上使用这种方式开发的话后期要调整kernel、rootfs等,只需要通过拷贝修改后的内容到SD卡对应分区中,不需要再通过NuWriter工具了。

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

新唐NUC980使用记录:U-Boot & Linux 编译与烧录(基于SD1位置SD卡) 的相关文章

  • platform.linux_distribution() 已弃用 - 有哪些替代方案?

    从 Python 3 5 开始platform linux distribution https docs python org 3 5 library platform html platform linux distribution已弃
  • IPC:在两个程序之间使用 C++ 中的命名管道

    我试图在同一台机器上运行的两个不同程序之间实现IPC 在我的例子中是CentOS7 为了实现一种松散耦合 我决定对 IPC 使用命名管道 因此 我正在使用以下示例并遇到了不同的问题 创建并写入管道 include
  • Linux 在崩溃时自动重新启动应用程序 - 守护进程

    我有一个运行嵌入式 Linux 的系统 它的持续运行至关重要 基本上 它是一个与传感器通信并将数据中继到数据库和 Web 客户端的过程 如果发生崩溃 如何自动重启应用程序 此外 还有多个线程进行轮询 例如套接字和 uart 通信 如何确保没
  • “原子”系统调用是什么意思?

    我知道atomic通常在以下上 下文中使用竞争条件意思是类似一致性 and 根据多线程 多处理环境确定结果 没关系 但最近我读到了Linux中的原子系统调用 但不明白什么是atomic实际上这里的意思是 即how this 原子性 is 实
  • posix 和 linux 特定函数的 C++ 包装器 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您知道有什么好的库将 posix 和 linux 函数和结构 例如套接字或文件描述符 包装到 C 类中
  • 如何使用Python distutils?

    我用 python 编写了一个快速程序 将 gtk GUI 添加到 cli 程序中 我想知道如何使用 distutils 创建安装程序 因为它只是命令行应用程序的 GUI 前端 所以它只能在 nix 中工作 所以我不担心它是跨平台的 我的主
  • PHP 使用 LetsEncrypt 验证失败

    尝试读取流时遇到问题 result file get contents url false stream context create http gt timeout gt float this gt options timeout SSL
  • C++向量数组运算符计算成本高?

    我一直都知道 C 的丰富抽象会带来一定的计算开销 但我的印象是 一旦应用了正确的编译器优化 这种开销几乎可以忽略不计 我很好奇这种开销到底有多大 所以我编写了一个简单的测试来确定这一点 该测试是一个模板化函数 它接受一个容器变量 为容器中的
  • 如何在每个 xargs 命令之间休眠 1 秒?

    例如 如果我执行 ps aux awk print 1 xargs I echo 我想让 shell 在每次之间休眠 1 秒echo 如何更改我的 shell 命令 您可以使用以下语法 ps aux awk print 1 xargs I
  • 如何更改解释器路径并将命令行参数传递给 Linux 上的“可执行”共享库?

    这是 可执行 共享库的最小示例 假设文件名 mini c Interpreter path is different on some systems definitely different for 32 Bit machines cons
  • c - 后台运行的程序的退出状态

    我有一个任务 其中我必须创建一个迷你 shell 它能够执行很多操作 包括作业控制 我设法使用 fork 和 execvp 创建新的工作 但我还想获取 execvp 运行的程序的退出代码 根据我从其他帖子中查找到的内容 我可以使用以下方法来
  • 如何配置和采样英特尔进程内性能计数器

    简而言之 我试图在用户级基准测试进程中实现以下目标 伪代码 假设 x86 64 和 UNIX 系统 results for iteration 0 iteration lt num iterations iteration pctr sta
  • 当我执行 pip --version 时,它显示错误为 ImportError:没有名为 pyparsing 的模块

    我尝试安装 卸载py解析以及它不起作用 我被这个问题困住了 我还必须安装额外的库 这是错误消息 Traceback most recent call last File usr bin pip line 5 in
  • Zip 实用程序在 Linux 中每次都给我不同的 md5sum

    当我在 Linux 中压缩 Zip 2 31 同一个文件时 每次都会得到不同的校验和 如何保持上次的 md5sum 相同 我正在使用 yum 提供的最新 zip 更新 生成的存档不仅包含压缩文件数据 还包含 额外的文件属性 如参考zip 文
  • Glassfish 4 服务器意外停止

    我是 GlassFish 和一般应用程序服务器的新手 我有一个运行 Ubuntu 的 Amazon EC2 实例 并安装了 GlassFish 4 它启动时没有问题 但过了一会儿 GlassFish 服务器就自行关闭了 我查看了 serve
  • top命令的CPU使用率计算

    我正在尝试使用 GNU coreutil top 的公式来计算 CPU 使用率的百分比 但 top 正在使用一些 half total 来计算百分比 即在百分比上添加 0 5 在top的utils c中 以下行 在 3 8 beta1 中
  • 32 位 x86 汇编中堆栈对齐的职责

    我试图清楚地了解谁 调用者或被调用者 负责堆栈对齐 64 位汇编的情况相当清楚 它是由caller 请参阅系统 V AMD64 ABI 第 3 2 2 节栈帧 输入参数区域的末尾应按 16 对齐 32 如果 m256 在堆栈 字节边界上传递
  • 检测目录中是否有某些内容被修改,如果是,则备份 - 否则不执行任何操作

    我有一个 数据 目录 我通过 shell 脚本定期同步到远程 NAS 但是 我想让这变得更有效率 我想在运行 rsync 之前检测 数据 中是否发生了变化 这样我就不会不必要地唤醒 NAS 上的驱动器 我正在考虑修改 shell 脚本以获取
  • 如何在不需要设置 LD_LIBRARY_PATH shell 变量的情况下输入“cargo run”?

    我构建了一个 Rust 程序 通过 C 接口调用 C 函数 为了执行该程序 我必须运行 export LD LIBRARY PATH
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也

随机推荐

  • HIVE beeline使用shell 批量执行sql语句

    shell脚本如图所示 principal 代表的是认证方式 bin sh Date Author etc profile bash profile sql14 pc insert into table uv daybyday bylimi
  • PHP小皮使用

    PHP小皮基本使用方法 本人新手一枚开始涉猎PHP了 下次有空补个Apache2 4 php7 2的安装教程 小皮使用 官网下载小皮 https www xp cn 选择好对应版本的小皮 本人电脑是windows10 64位的 2 下载好之
  • python知识复习一

    文章目录 前言 一 变量和简单数据类型 1 命名和使用 2 字符串 2 1 修改字符串大小写 2 2 字符串中使用变量 2 3 使用制表符或者换行符添加空白 2 4 删除空白 3 标准数据类型 4 数据类型转变 5 常量 二 数 1 常量
  • sql语句的复习

    sql语句的复习 说来惭愧 写了这么多年代码 sql语句都忘记差不多了 基础 CREATE DATABASE database name drop datebase dbname 备份数据库 mysqldump u 用户名 p 数据库名 g
  • 一步一步理解大模型:模型量化技术3 - GPTQ

    本文介绍专门为生成式预训练模型设计的量化技术GPTQ GPTQ是一种一次性权重量化方法 专为生成预训练Transformer GPT 模型设计 该方法基于近似二阶信息 旨在实现高度准确和高效 关于GPTQ的关键点 GPTQ可以在大约四个GP
  • Redis数据持久化——快照RDB、AOF、主从复制

    redis 本地持久化到硬盘有两种方式 一是快照 snapshotting 二是只追加文件 append only file AOF 快照 快照 顾名思义可以理解为拍照一样 把整个内存数据映射到硬盘中 保存一份到硬盘 因此恢复数据起来比较快
  • STM32输入捕获原理与配置

    目录 一 输入捕获原理 二 输入捕获过程 1 设置输出捕获滤波器 通道1为例 2 设置输入捕获极性 3 设置输入捕获映射通道 4 设置输入捕获分频器 5 捕获到有效信号可以开启中断 6 工作工程 三 输入捕获编程流程 HAL库 四 程序要求
  • 先验概率、后验概率、似然估计、条件概率

    此为Bayesian先生 敬仰吧 同志们 先验 A priori 又译 先天 在拉丁文中指 来自先前的东西 或稍稍引申指 在经验之前 近代西方传统中 认为先验指无需经验或先于经验获得的知识 它通常与后验知识相比较 后验意指 在经验之后 需要
  • JAVA中注解

    注解入门 注解 Annotation 的发展 注解是从JDK5 0开始引入的新技术 注解 Annotation 的作用 不属于程序本身 可以对程序作出解释 这一点跟注释没什么区别 可以被其他程序 如编译器 读取 注解 Annotation
  • mac电脑无法读取移动硬盘

    mac电脑插上硬盘或U盘后不正常断开 会导致读取不到 一 方式1 1 插上硬盘 2 查看硬盘信息 在列表中找到自己的硬盘名称 找到自己的硬盘挂载路径 我的是 dev disk4 diskutil list 3 重新挂载指令 此处我的路径是
  • Java-JDK8下载

    文章目录 一 JDK选择 二 JDK下载 三 JDK安装 四 JDK环境变量配置 五 JDK运行代码测试 六 结尾 一 JDK选择 对于Java开发者而言 选择一个稳定且生态好的开发环境 是最好不过的了 在Java JDK中 JDK8就是相
  • Windows10下安装Mysql

    下载地址 https dev mysql com downloads windows installer 5 7 html 双击安装文件 勾上勾选框 点击Next gt 选择安装类型 这里我选择 Server only 仅安装MySQL数据
  • 激光SLAM入门笔记(三)——传感器数据处理之激光雷达运动畸变去除

    激光雷达运动畸变去除 主要内容 概念介绍 1 激光雷达传感器介绍 两种原理 三角测距 A2 EAI等等 10m内基本为三角测距原理 2 激光雷达数学模型介绍 AMCL采用该模型 3 运动畸变的介绍 相比平移运动 旋转运动 产生的运动畸变比较
  • Response.sendRedirect()

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 一 用sendRedirect方法实现请求重定向 sendRedirect方法用于生成302响应码和Location响应头 从而通知客户端去重新访问Location响应头中
  • Android中添加CallStack打印

    Android 打印调用堆栈 内核 添加头文件 include
  • [Vue warn]: Failed to mount component: template or render function not defined.解决方案

    命名视图 vue router 里有一个 模式叫做 命名视图 本来一个页面里面只能有一个路由视图 对应 一个组件 现在可以多个路由视图 对应 多个组件 出错点 点击标签之后
  • 关于android:configChanges的属性

    一般在AndroidManifest xml文件中都没有使用到android configChanges keyboardHidden orientation 配置 当然还是很有用的 就是如果配置了这个属性 当我们横竖屏切换的时候会直接调用
  • spark题目整理

    1 driver的功能是什么 1 一个Spark作业运行时包括一个Driver进程 也是作业的主进程 具有main函数和SparkContext的实例 是程序的人口点 2 功能 负责向集群申请资源 向master注册信息 负责了作业的调度
  • Gamemaker studio2经验(3)——昼夜更替效果实现

    问题概述 在一些知名引擎 如unity godot cocos等 中 天空盒概念的引入使得场景中的天空丰富多彩 但是gm就吃了这个大亏 由于动态天空制作麻烦 没有对口的天空盒系统 导致很少有开发者在gm中制作昼夜交替效果 昨天因为被千字大论
  • 新唐NUC980使用记录:U-Boot & Linux 编译与烧录(基于SD1位置SD卡)

    文章目录 目的 SD卡分区 U Boot编译 U Boot环境变量 Linux编译 默认设置 使用SD卡剩余分区 使用SD卡分区存放rootfs 制作系统镜像 总结 目的 这篇文章中将测试在 NUC980 中运行Linux系统 基于SD1位