提供邯郸手机网站建设/网站seo优化方案设计
文章目录
- 1、AB分区镜像制作
- 2、uboot修改
- 3、镜像启动
在上一篇 Qemu开发ARM篇-5、buildroot制作根文件系统并挂载启动中,我们通过buildroot制作了根文件系统,并通过
SD
卡的形式将其挂载到设备并成功进行了启动,但上一章中,我们的做法非常简单粗暴,并且没有进行分区,在本章中我们将对对
SD
镜像进行分区,并制作
AB
分区的镜像。
1、AB分区镜像制作
uboot环境变量镜像制作:
1、在工程目录新建etc文件,并在里面新建uboot_env.txt
文件,该文件用来描述所使用的环境变量,后续我们将会将其制作为uboot_env的环境变量镜像,并将其写入emmc(SD)分区中,uboot将从这里面去读取环境变量。
mkdir etc && cd etc && touch uboot_env.txt
并在uboot_env.txt
中输入如下内容:
bootcmd=mmc read 0x60003000 0x3800 0x10000;mmc read 0x60500000 0x1800 0x400;bootm 0x60003000 - 0x60500000
bootargs=root=/dev/mmcblk0p9 init=/usr/sbin/init console=ttyAMA0
上面参数以及地址什么意思?别急,我们先将整个镜像制作出来在来说明上述参数含义,因为上面的参数都是根据我们制作的镜像进行计算的.
2、在script目录使用touch make_AB_img.sh && chmod 777 make_AB_img.sh
命令创建AB分区镜像制作脚本,并在制作脚本输入如下内容:
#!/bin/bash
ROOT_PATH=$(pwd)
OUT_PATH=$ROOT_PATH/out/ab_img
if [ -e $OUT_PATH ]
thenrm -rf $OUT_PATH
fi
mkdir $OUT_PATH -p
cd $OUT_PATH
# 磁盘总大小为8G
dd if=/dev/zero of=vexpress_ab.img bs=1M count=8192
# msic part 512K
sgdisk -n 0:0:+512k -c 0:misc vexpress_ab.img
# ubootenv part 512K 环境变量存放位置
sgdisk -n 0:0:+512k -c 0:ubootenv vexpress_ab.img
# dtb_a 512k 设备树
sgdisk -n 0:0:+512k -c 0:dtb_a vexpress_ab.img
# dtb_b 512k 设备树
sgdisk -n 0:0:+512k -c 0:dtb_b vexpress_ab.img
# vbmeta_a part 512K 安全校验
sgdisk -n 0:0:+512k -c 0:vbmeta_a vexpress_ab.img
# vbmeta_b part 512K
sgdisk -n 0:0:+512k -c 0:vbmeta_b vexpress_ab.img
# boot_a partition 32M kernel分区
sgdisk -n 0:0:+32M -c 0:boot_a vexpress_ab.img
# boot_b partition 32M kernel分区
sgdisk -n 0:0:+32M -c 0:boot_b vexpress_ab.img
# rootfs_a partition 512M
sgdisk -n 0:0:+512M -c 0:rootfs_a vexpress_ab.img
# rootfs_b partition 512M
sgdisk -n 0:0:+512M -c 0:rootfs_b vexpress_ab.img
# userdata partition 剩余所有大小分配给userdata分区
sgdisk -n 0:0:0 -c 0:userdata vexpress_ab.imgsync
# 显示分区信息
sgdisk -p vexpress_ab.img# 读取分区信息并挂载到回环设备
LOOPDEV=`losetup -f`
echo $LOOPDEV
sudo losetup $LOOPDEV vexpress_ab.img
sudo partprobe $LOOPDEV
sudo losetup -l
ls -l $LOOPDEV*# 将userdata格式化为ext4格式
# sudo mkfs.ext4 ${LOOPDEV}p9
# sudo mkfs.ext4 ${LOOPDEV}p10
sudo mkfs.ext4 ${LOOPDEV}p11# 拷贝rootfs、kernel
mkdir tem_file
cp $ROOT_PATH/out/kernel-arm/arch/arm/boot/uImage tem_file/kernel
cp $ROOT_PATH/out/kernel-arm/arch/arm/boot/dts/vexpress-v2p-ca9.dtb tem_file/vexpress-v2p-ca9.dtb
cp $ROOT_PATH/out/rootfs-arm/images/rootfs.ext4 tem_file/rootfs.ext4
# 制作环境变量
mkenvimage -s 524288 -o tem_file/env.img $ROOT_PATH/etc/uboot_env.txt# 将对应分区数据写入对应分区
sudo dd if=tem_file/env.img of=${LOOPDEV}p2 conv=notrunc
sudo dd if=tem_file/kernel of=${LOOPDEV}p7 conv=notrunc
sudo dd if=tem_file/vexpress-v2p-ca9.dtb of=${LOOPDEV}p3 conv=notrunc
sudo dd if=tem_file/rootfs.ext4 of=${LOOPDEV}p9 conv=notrunc# rootfs是ext4格式,为了能让磁盘空间占满,这里我们进行resize
sudo resize2fs -f ${LOOPDEV}p9# 可以使用下面挂载copy的方式进行rootfs的创建,这里我们采用上面的dd方式
# # 创建临时挂载目录,用来像分区中copy数据
# mkdir tem_rootfs_a
# mkdir tem_userdata
# # 挂载rootfs_a和userdata分区
# sudo mount -t ext4 ${LOOPDEV}p7 ./tem_rootfs_a -o loop
# sudo mount -t ext4 ${LOOPDEV}p9 ./tem_userdata -o loop
# sudo cp -rf rootfs-arm/* ./tem_rootfs_a
# sudo umount ./tem_rootfs_a
# sudo umount ./tem_userdata# 取消回环设备
sudo losetup -d $LOOPDEV
# rmdir ./tem_rootfs_a ./tem_userdata
上面其他命令对应都在代码中进行了相应的注释,这里不在过多的阐述,我们来解释一下上面 mkenvimage -s 524288 -o tem_file/env.img $ROOT_PATH/etc/uboot_env.txt
这条制作uboot镜像的命令的含义:
其中-s
用来指定制作的uboot环境变量分区的大小(env.img),因为我们在进行分区划分的时候划分的为512k(sgdisk -n 0:0:+512k -c 0:ubootenv vexpress_ab.img)
,512k=512*1024=524288字节,因此在这里我们制作的uboot环境变量的大小也为512k。
注意:上面镜像中未包含uboot,这是因为我们qemu需要重uboot启动,需要手动指定uboot镜像,因此在AB分区中,我们不制作uboot镜像,另外vbmeta用作安全的,目前我们还未使用到,因此这里暂做保留。
然后运行./script/make_AB_img.sh
制作AB分区镜像。
运行完成之后,会在out/ab_img/
目录下生vexpress_ab.img
镜像文件。
使用sgdisk查看镜像文件:
可以看到,和我们制作时候指定镜像大小是一致的。
3、uboot_env.txt
中环境变量的含义
现在我们已经将镜像制作出来了,现在我们就可以来深究一下上面uboot_env.txt
中环境变量的含义了,为什么这么设置,以及为什么要设置为这些值。
首先是boot_cmd
:我们设置的值为:bootcmd=mmc read 0x60003000 0x3800 0x10000;mmc read 0x60500000 0x1800 0x400;bootm 0x60003000 - 0x60500000
在uboot运行时候,会自动运行bootcmd的值命令进行内核启动,我们在bootcmd中也就是设置启动参数。
mmc read 0x60003000 0x3800 0x10000
解释
这条命令的意思是从emmc的0x3800
块地址处读取0x10000
块数据到0x60003000
内存中。这里其实就是读取kernel的镜像,为什么呢?
使用sgdisk -p
命令可以看到制作分区情况,也就是在上面图中,我们可以看到,boot_a的起始块地址为14336
,注意这是块地址,每块是512字节,而我们mmc read命令中需要的就是块地址,因此我们这里在使用mmc read读取地址就是14336
,将其转换为16进制就是0x3800
,
从上图分区情况我们还可以知道,boot_a分区大小为:32M=321024k=3210241024=33554432字节=321024*1024/512=65,536块,转换为16进制为:0x1 0000块,所以上面最后一个参数为0x1 0000
。
至于为什么将kernel内容读到内存0x60003000
这个地址出,这是因为我们在编译kernel的时候指定了其链接地址为0x60003000
,忘记了的可以参考之前的文章:Qemu开发ARM篇-4、kernel交叉编译运行演示
mmc read 0x60500000 0x1800 0x400
解释
这条命令意思和上面kernel差不多,这里就快速过一下:
dtb_a起始块地址:6144=0x1800
dtb_a分区大小:512k=5121024字节=5121024/512块=1024块=0x400块
0x60500000 :这里不将kernel覆盖掉的地址理论都可以,这里设置为:0x60500000
bootm 0x60003000 - 0x60500000
解释
这条命令是启动kernel的标准命令,前面是内核的地址,后面的dtb的地址,都是上面我们进行指定的。
然后是boot_args:bootargs=root=/dev/mmcblk0p9 init=/usr/sbin/init console=ttyAMA0
bootargs的参数会传递给内核,用于挂载根文件系统以及指定系统初始化程序,这里根文件系统位于
/dev/mmcblk0p9
分区,初始化程序选择/usr/sbin/init
,这个其实就是systemd,我们在制作根文件系统选择的,如果忘记的可以参考之前的文章:Qemu开发ARM篇-5、buildroot制作根文件系统并挂载启动
2、uboot修改
因为我们将环境变量设置在了分区2,因此我们需要对uboot进行配置,告诉uboot在哪里去获取环境变量:
运行我们之前编译uboot的脚本:./script/build_uboot.sh
进入到图形配置界面:
1、找到环境变量配置选项
选项配置如下:
取消掉in flash
选项,选中in mmc
选项,然后修改环境变量偏移为:0x200000
,这是因为我们环境变量起始块地址为:4096块=4096512=2,097,152字节=0x200000,因此偏移为:0x200000
环境变量size设置为0x80000
这是因为我们环境变量大小为512k=5121024=524,288字节=0x80000,因此大小为:0x80000
下面分区设备以及分区号都填0,因为我们上面偏移都是从0开始计算的。
设置好之后,保持配置,为了不用每次都进行配置,我们将该配置进行保存,并替换原配置文件,这样我们就不用每次都进行配置了,使用如下命令保存该配置:
cp ./src/uboot/u-boot-2022.07-rc3/configs/vexpress_ca9x4_defconfig ./src/uboot/u-boot-2022.07-rc3/configs/vexpress_ca9x4_defconfig_bak
cp ./out/u-boot-arm/.config ./src/uboot/u-boot-2022.07-rc3/configs/vexpress_ca9x4_defconfig
这样我们下次再编译的时候就会使用我们刚刚配置的配置了。
3、镜像启动
1、uboot信息确认
编译完新的uboot以及制作完分区镜像之后,我们在script目录使用touch run_uboot_with_img.sh && chmod 777 run_uboot_with_img.sh
命令创建启动脚本,并在启动脚本输入如下内容:
#!/bin/bash
qemu-system-arm -M vexpress-a9 -m 512M -kernel ~/project/qemu/out/u-boot-arm/u-boot -nographic -no-reboot -sd out/ab_img/vexpress_ab.img
然后运行./script/run_uboot_with_img.sh
启动uboot: 启动是按下回车先看看uboot内部情况。
可以看到环境变量加载成功,使用printenv
查看一下环境变量是不是我们刚才设置的:
了可以看到环境变量和我们上面设置的一致,在看看其他内容。
在uboot中使用mmcinfo
查看磁盘情况:
可以看到容量为8G和我们制作大小一致,使用mmc part
查看分区情况:
可以看到分区信息也和我们指定的一致:
使用ls mmc 0:9
查看rootfs_a内容情况:
可以看到里面内容正是我们制作的根文件系统。
2、启动
当上面一切都正常后,使用run bootcmd
启动内核,看能否正常进入系统:
可以看到已经成功启动了内核并成功挂载了根文件系统并进入了系统。
下一次uboot启动时,不要按回车,uboot就会自动运行bootcmd命令,并启动内核进入系统。
相关文章:

Qemu开发ARM篇-6、emmc/SD卡AB分区镜像制作并通过uboot进行挂载启动
文章目录 1、AB分区镜像制作2、uboot修改3、镜像启动 在上一篇 Qemu开发ARM篇-5、buildroot制作根文件系统并挂载启动中,我们通过buildroot制作了根文件系统,并通过 SD卡的形式将其挂载到设备并成功进行了启动,但上一章中,我们的…...

Spring Boot中使用ThreadPoolTaskScheduler实现轻量级多线程定时任务
引言 在Java开发中,Spring Boot提供了多种方式来执行定时任务,如Scheduled注解和TaskScheduler。当需要执行多线程定时任务时,ThreadPoolTaskScheduler是一个轻量级的解决方案。本文将通过一个具体的业务场景,介绍如何使用Thread…...

完全二叉树的节点个数 C++ 简单问题
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。 示例 1ÿ…...

每日一题学习笔记
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1: 输入&#…...

从事人工智能学习Python还是学习C++?
人工智能(Artificial Intelligence,简称AI)是当今科技领域最热门的研究方向之一。AI 涉及多个学科和技术,特别是机器学习、神经网络、深度学习等技术的应用。在AI的开发过程中,编程语言的选择对于开发效率和项目实现至…...

博客摘录「 CNN中的感受野和有效感受野会对模型产生怎样的影响?」2024年9月29日
,中心像素受影响较大,离中心越远梯度信号越弱。梯度信号的衰减是指数级的,这意味着应用于感受野的大多数像素的梯度将是可忽略的(如果有的话)。 有效感受野的定义...

AURIX单片机示例:开发入门与点亮LED
文章目录 目的模板工程Blinky_LED示例链接总结 目的 这个例程比较简单,主要通过这个例程来介绍 AURIX™ Development Studio(ADS) 和 iLLD 库来开发 AURIX 系列单片机一些入门的内容。一些更为基础的资料等内容可以参考下面文章: 《英飞凌 AURIX TriCo…...

MySQL字符串函数与操作
在编程领域中,字符串操作是数据处理中至关重要的一部分。无论是文本分析、日志处理,还是格式化输出,字符串的操作技能都能极大提高工作效率。在 Python 中,字符串相关的函数和方法为开发者提供了强大的工具,帮助完成各种任务。了解如何灵活运用这些工具,能够有效提升编程…...

HTML+CSS 水滴登录页
文章目录 一、效果演示二、Code1.HTML2.CSS 三、实现思路拆分 一、效果演示 实现了一个水滴登录页的效果。页面包含一个水滴形状的登录框和两个按钮,登录框包括用户名、密码和登录按钮,按钮分别为忘记密码和注册。整个页面的设计非常有创意,采…...

基于Next.js和TailwindCss的TailwindCss
最近在研究 Next.js 和 TailwindCss ,这两天没事的时候就搞了一个 c。 目前工具部署在 Vercel ,欢迎各位体验(能提出意见更好嘿嘿) 体验地址: https://icon.999872.xyz/ 图片预览 👇...

若依开源系统多数据源整合clickhouse数据库详细步骤
1.添加依赖【pom.xml文件】 <!-- clickhouse数据源依赖--><dependency><groupId>ru.yandex.clickhouse</groupId>...

Subdominator:一款针对漏洞奖励计划的子域名安全枚举工具
关于Subdominator Subdominator是一款针对漏洞奖励计划的子域名安全枚举工具,可用于在漏洞搜寻和侦察过程中进行被动子域名枚举。它旨在通过高效枚举子域名和各种免费被动资源来帮助研究人员和网络安全专业人员发现潜在的安全漏洞。 Subdominator 与各种免费和付费…...

[leetcode]516_最长回文子序列
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。示例 1: 输入:s "bbbab" 输出&a…...

电子相册|智能化电子相册|基于java的电子相册管理系统设计与实现(源码+数据库+文档)
电子相册管理系统 目录 基于java的电子相册管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&…...

linux项目_c语言:Makefile编写、动态库生成、添加动态库路径
一直想搞懂Linux中Makefile是怎么管理项目的,知识积累到一定程度后,我就做了一个自己的缩小项目去把剩下的细节搞清楚 代码: Service.c: #include <stdio.h> #include "lib_sevr.h" int main(){printf("输入a, b的值…...

Python学习(1):字典、DataFrame的创建方法
1. 字典的创建方法 1.1 直接创建 # 创建一个包含姓名和年龄的字典 person {"name": "Alice", "age": 25}print(person) # 输出:{name: Alice, age: 25} 1.2 使用 dict() 函数 # 使用键值对列表创建字典 person dict(name"…...

async await 介绍 从0手动实现async await
1 async await介绍 async 和 await 是用于处理异步编程的语法糖,它们简化了异步操作的编写,使其看起来像同步代码。通过 async 标记一个函数为异步函数,返回的是一个 Promise 对象,而 await 用来暂停执行,直到 Promise…...

UDP校验和计算及网络中的校验和机制
UDP (User Datagram Protocol) 是一种无连接的传输层协议,它不像 TCP 那样提供可靠的传输保证。虽然 UDP 不保证数据可靠性,但它仍然提供了一个可选的校验和机制来检测数据在传输过程中出现的错误。 理解UDP校验和的计算过程和其在网络中的作用至关重要。…...

如何使用C语言接入Doris数据库
如何使用C语言接入Doris数据库 一、环境准备1. 安装MySQL C API2. Doris数据库环境二、编写C语言接入代码1. 包含必要的头文件2. 编写连接和查询函数3. 编译和运行程序三、注意事项1. 安全性2. 错误处理3. 性能优化4. 兼容性5. 调试和日志记录四、结论Doris(之前称为Palo或Apa…...

DarkLabel 2.4 目标追标注工具介绍
DarkLabel介绍 https://github.com/darkpgmr/DarkLabel 官方地址 视频/图像标注工具,很适合用于目标追踪任务 DarkLabel可以在视频和图像中标注物体的边界框,并附上 ID 和name。还可以用于裁剪视频、从视频中采样训练图像以及对图像区域进行马赛克处理…...

uniapp设置从右上角到左下角的三种渐变颜色
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...

Python 解析 html
一、场景分析 假设有如下 html 文档: 写一段 python 脚本,解析出里面的数据,包括经度维度。 <div classstorelist><ul><li lng"100.111111" lat"10.111111"><h4>联盟店1</h4><p>…...

“大数据+高职”:VR虚拟仿真实训室的发展前景
随着信息技术的迅猛发展,大数据技术与虚拟现实(VR)的融合正在为高等教育,尤其是高等职业教育(高职)带来革命性的变革。VR虚拟仿真实训室作为这一技术融合的典型应用,正逐步展现其在提升教育质量…...

Pygame中Sprite实现逃亡游戏4
在《Pygame中Sprite实现逃亡游戏3》中实现了玩家跳跃飞火的效果,接下来通过精灵类的碰撞检测来判断飞火是否击中玩家、飞火是否击中飞龙以及飞龙是否抓住玩家。 1 飞火是否击中玩家的判断 判断飞火是否击中玩家的代码如图1所示。 图1 判断飞火是否击中玩家的代码 …...

sentinel原理源码分析系列(一)-总述
背景 微服务是目前java主流开发架构,微服务架构技术栈有,服务注册中心,网关,熔断限流,服务同学,配置中心等组件,其中,熔断限流主要3个功能特性,限流,熔断&…...

创建数据/采集数据+从PI数据到PC+实时UI+To PLC
Get_Data ---------- import csv import os import random from datetime import datetime import logging import time # 配置日志记录 logging.basicConfig(filename=D:/_Study/Case/Great_Data/log.txt, level=logging.INFO, format=%(asctime)s - %(l…...

Linux基础入门 --12 DAY(SHELL脚本编程基础)
shell脚本编程 声明:首行shebang机制 #!/bin/bash #!/usr/bin/python #!/usr/bin/perl 变量 变量类型 变量类型: 内置变量 : 如 PS1 , PATH ,HISTSIZE 用户自定义变量 不同变量存放数据不同,决定了以下 1.数据存储方式 2.参与的运算 3.表示…...

关于frp Web界面-----frp Server Dashboard 和 frp Client Admin UI
Web 界面 官方文档:https://gofrp.org/zh-cn/docs/features/common/ui/ 目前 frpc 和 frps 分别内置了相应的 Web 界面方便用户使用。 客户端 Admin UI 服务端 Dashboard 服务端 Dashboard 服务端 Dashboard 使用户可以通过浏览器查看 frp 的状态以及代理统计信…...

Hive数仓操作(一)
Hive 介绍 Hive 是一个基于 Hadoop 的数据仓库工具,旨在简化大规模数据集的管理和分析。它将结构化数据文件映射为表,并提供类似 SQL 的查询功能。Hive 的数据存储在 Hadoop 分布式文件系统(HDFS)中,使用 Hive 查询语…...

什么是NAND Flash?
什么是NAND Flash? NAND闪存是一种非易失性存储器技术,它彻底改变了数字时代的数据存储。它是闪存的一种形式,这意味着它可以被电擦除和重新编程。NAND闪存以NAND(NOT-AND)逻辑门命名,该逻辑门用于其基本架构。术语“…...