原始镜像:即raw image,完整的ext4分区镜像,包含很多全零的无效填充区 稀疏镜像:即sparse image,将raw ext4进行稀疏描述,因此尺寸比较小,制作目录有多少文件就计算多少,没有全零填充
case WRITE_SPARSE:{std::make_unique(partitionName));return std::move(writer);}
.aseupdateupdaterservicesapplypatch
aw_writer.h
typedef struct sparse_header { uint32_t magic; /* 0xed26ff3a */ uint16_t major_version; /* (0x1) - reject images with higher major versions */ uint16_t minor_version; /* (0x0) - allow images with higer minor versions */ uint16_t file_hdr_sz; /* 28 bytes for first revision of the file format */ uint16_t chunk_hdr_sz; /* 12 bytes for first revision of the file format */ uint32_t blk_sz; /* block size in bytes, must be a multiple of 4 (4096) */ uint32_t total_blks; /* total blocks in the non-sparse output image */ uint32_t total_chunks; /* total chunks in the sparse input image */ uint32_t image_checksum; /* CRC32 checksum of the original data, counting "don't care" *//* as 0. Standard 802.3 polynomial, use a Public Domain *//* table implementation */} sparse_header_t;#define SPARSE_HEADER_MAGIC 0xed26ff3a#define CHUNK_TYPE_RAW 0xCAC1#define CHUNK_TYPE_FILL 0xCAC2#define CHUNK_TYPE_DONT_CARE 0xCAC3#define CHUNK_TYPE_CRC32 0xCAC4typedef struct chunk_header { uint16_t chunk_type; /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */ uint16_t reserved1; uint32_t chunk_sz; /* in blocks in output image */ uint32_t total_sz; /* in bytes of chunk input file including chunk header and data */} chunk_header_t;class SparseWriter : public DataWriter {public: virtual bool Write(const uint8_t *addr, size_t len, WriteMode mode, const std::string &partitionName); explicit SparseWriter(const std::string partitionName) : offset_(0), fd_(-1), partitionName_(partitionName) {} virtual ~SparseWriter() { offset_ = 0;if (fd_ > 0) { fsync(fd_);close(fd_); } fd_ = -1; }private:int WriteInternal(int fd, const uint8_t *data, size_t len, const std::string &partitionName); SparseWriter(const SparseWriter&) = delete;const SparseWriter& operator=(const SparseWriter&) = delete; off64_t offset_;int fd_; std::string partitionName_;};
.aseupdateupdaterservicesapplypatch
aw_writer.cpp
bool SparseWriter::Write(const uint8_t *addr, size_t len, WriteMode mode, const std::string &partitionName)
{
if (addr == nullptr) {
LOG(ERROR) << "SparseWriter: invalid address.";
return false;
}
if (len == 0) {
LOG(INFO) << "SparseWriter: write length is 0, skip.";
return false;
}
if (fd_ < 0) {
fd_ = OpenPartition(partitionName_);
if (fd_ < 0) {
return false;
}
}
UPDATER_CHECK_ONLY_RETURN(WriteInternal(fd_, addr, len, partitionName_) >= 0, return false);
return true;
}
int SparseWriter::WriteInternal(int fd, const uint8_t *data, size_t len, const std::string &partitionName)
{
uint32_t written = 0;
sparse_header_t *sparse_header;
chunk_header_t *chunk_header;
unsigned int chunk;
void *membuf = NULL;
uint32_t *fill_buf = NULL;
uint32_t fill_val;
uint32_t bytes_written = 0;
uint32_t total_bytes = 0;
uint32_t blk = 0;
uint32_t chunk_data_sz = 0;
uint32_t blkcnt = 0;
uint32_t blks = 0;
uint32_t total_blocks = 0;
uint32_t addr_offset = 0;
uint32_t fill_buf_num_blks = 0;
uint32_t block_size = 4096;
uint32_t block_count = 524288;
uint32_t i;
uint32_t j;
int ret = lseek64(fd, offset_, SEEK_SET);
UPDATER_FILE_CHECK(ret != -1, "RawWriter: failed to seek file to " << offset_, return -1);
fill_buf_num_blks = CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE / block_size;
LOG(INFO) << "WriteInternal offset_ " << offset_;
/* Read and skip over sparse image header */
sparse_header = (sparse_header_t *)data;
data += sparse_header->file_hdr_sz;
if (sparse_header->file_hdr_sz > sizeof(sparse_header_t)) {
/*
* Skip the remaining bytes in a header that is longer than
* we expected.
*/
data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
}
LOG(INFO) << "=== Sparse Image Header ===";
LOG(INFO) << "magic: " << sparse_header->magic;
LOG(INFO) << "major_version: " << sparse_header->major_version;
LOG(INFO) << "minor_version: " << sparse_header->minor_version;
LOG(INFO) << "file_hdr_sz: " << sparse_header->file_hdr_sz;
LOG(INFO) << "chunk_hdr_sz: " << sparse_header->chunk_hdr_sz;
LOG(INFO) << "blk_sz: " << sparse_header->blk_sz;
LOG(INFO) << "total_blks: " << sparse_header->total_blks;
LOG(INFO) << "total_chunks: " << sparse_header->total_chunks;
LOG(INFO) << "Flashing Sparse Image";
blk = 0;
for (chunk = 0; chunk < sparse_header->total_chunks; chunk++) {
/* Read and skip over chunk header */
chunk_header = (chunk_header_t *)data;
data += sizeof(chunk_header_t);
if (chunk_header->chunk_type != CHUNK_TYPE_RAW)
{
LOG(INFO) << "=== Chunk Header ===";
LOG(INFO) << "chunk_type: " << chunk_header->chunk_type;
LOG(INFO) << "chunk_sz: " << chunk_header->chunk_sz;
LOG(INFO) << "total_sz: " << chunk_header->total_sz;
}
if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t)) {
/*
* Skip the remaining bytes in a header that is longer
* than we expected.
*/
data += (sparse_header->chunk_hdr_sz -
sizeof(chunk_header_t));
}
chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
blkcnt = chunk_data_sz / block_size;
switch (chunk_header->chunk_type) {
case CHUNK_TYPE_RAW:
if (chunk_header->total_sz !=
(sparse_header->chunk_hdr_sz + chunk_data_sz)) {
LOG(ERROR) << "Bogus chunk size for chunk type Raw";
return -1;
}
if (blk + blkcnt > 0 + block_count) {
LOG(ERROR) << "Request would exceed partition size!";
return -1;
}
addr_offset = blk * block_size;
ret = lseek64(fd, offset_ + addr_offset, SEEK_SET);
if (ret < 0) {
LOG(ERROR) << "failed to seek file to " << addr_offset << " error=" << strerror(errno);
return -1;
}
written = write(fd, data, blkcnt * block_size);
if (written < 0) {
LOG(ERROR) << "SparseWriter: failed to write data of len ";
return -1;
}
total_bytes = total_bytes + blkcnt * block_size;
blks = written / block_size;
blk += blks;
bytes_written += blkcnt * block_size;
total_blocks += chunk_header->chunk_sz;
data += chunk_data_sz;
break;
case CHUNK_TYPE_FILL:
if (chunk_header->total_sz !=
(sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
LOG(ERROR) << "Bogus chunk size for chunk type FILL total_sz err " << chunk_header->total_sz << "
";
return -1;
}
ret = posix_memalign (&membuf, 64,
ROUNDUP(
block_size * fill_buf_num_blks,
64));
if (ret) {
LOG(ERROR) << "posix_memalign:" << strerror (errno);
return -1;
}
fill_buf = (uint32_t *)membuf;
if (!fill_buf) {
LOG(ERROR) << "Malloc failed for: CHUNK_TYPE_FILL";
return -1;
}
fill_val = *(uint32_t *)data;
data = data + sizeof(uint32_t);
for (i = 0;
i < (block_size * fill_buf_num_blks /
sizeof(fill_val));
i++)
fill_buf[i] = fill_val;
if (blk + blkcnt > 0 + block_count) {
LOG(ERROR) << "Request would exceed partition size!";
return -1;
}
for (i = 0; i < blkcnt;) {
j = blkcnt - i;
if (j > fill_buf_num_blks)
j = fill_buf_num_blks;
addr_offset = blk * block_size;
ret = lseek64(fd, offset_ + addr_offset, SEEK_SET);
if (ret < 0) {
LOG(ERROR) << "failed to lseek file to " << addr_offset << " error=" << strerror(errno);
return -1;
}
written = write(fd, fill_buf, j * block_size);
if (written < 0) {
LOG(ERROR) << "SparseWriter: failed to write data of len ";
return -1;
}
total_bytes = total_bytes + j * block_size;
blks = written / block_size;
if (blks < j) {
LOG(ERROR) << "Write failed, block";
free(fill_buf);
return -1;
}
blk += blks;
i += j;
}
bytes_written += blkcnt * block_size;
total_blocks += chunk_data_sz / sparse_header->blk_sz;
free(fill_buf);
break;
case CHUNK_TYPE_DONT_CARE:
blk += blkcnt;
total_blocks += chunk_header->chunk_sz;
break;
case CHUNK_TYPE_CRC32:
if (chunk_header->total_sz !=
sparse_header->chunk_hdr_sz) {
LOG(ERROR) << "Bogus chunk size for chunk type CRC32 total_sz err " << chunk_header->total_sz;
return -1;
}
total_blocks += chunk_header->chunk_sz;
data += chunk_data_sz;
break;
default:
LOG(INFO) << __func__ << ": Unknown chunk type: " << chunk_header->chunk_type;
return -1;
}
}
LOG(INFO) << "Wrote "<< chunk <<"blocks, expected to write " << sparse_header->total_blks << "blocks
";
LOG(INFO) << "........ wrote "<< bytes_written <<"bytes to " << partitionName << "
";
LOG(INFO) << "total_bytes=" << total_bytes;
return 0;
}
DevEco Studio新特性分享-跨语言调试,让调试更便捷高效 基于 OpenHarmony 的智联北斗海防系统 玩转OpenHarmony智能家居:如何实现树莓派“碰一碰”设备控制 玩转OpenHarmony社交场景:即时通讯平台 HarmonyOS多媒体框架介绍
提示:本文由电子发烧友社区发布,转载请注明以上来源。如需社区合作及入群交流,请添加微信EEFans0806,或者发邮箱liuyong@huaqiu.com。
原文标题:稀疏镜像在 OpenHarmony 上的探索
文章出处:【微信公众号:电子发烧友开源社区】欢迎添加关注!文章转载请注明出处。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
电子发烧友
+关注
关注
33文章
546浏览量
32359 -
开源社区
+关注
关注
0文章
92浏览量
342
原文标题:稀疏镜像在 OpenHarmony 上的探索
文章出处:【微信号:HarmonyOS_Community,微信公众号:电子发烧友开源社区】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
【飞腾派4G版免费试用】从官方的镜像开始--->烧录SD镜像
下载!!!
资料杠杠的,
速度找到想刷的镜像,品种挺多的,热门的OpenHarmony、RT-Thread 、OpenKylin。
果断选择飞腾基于Debian的OS。顺手把交叉编译环境必须搞下来
发表于 12-07 19:57
【限量门票】繁荣生态,人才先行︱首届OpenHarmony人才生态大会即将在上海召开
单位代表等,介绍OpenHarmony社区生态及人才进展、展示OpenHarmony操作系统的技术革新、分享阶段性技术成果,围绕OpenHarmony人才生态发展中面临的各种问题、挑战与实践,一同
发表于 12-04 16:30
【报名开启】繁荣生态,人才先行︱首届OpenHarmony人才生态大会即将在上海召开
探索交流。
产业发展离不开人才培养,为培养更多创新型人才,壮大OpenHarmony生态新兴力量,生态伙伴联合高校共同打造人才培养闭环生态链。本次大会大咖云集,将邀请高校教师、共建单位伙伴、社区专家
发表于 12-04 16:23
如何使用dockerfile创建镜像
Docker是一个开源的平台,用于快速构建、打包、部署应用程序的容器化工具。而Dockerfile是一个文本文件,包含了一组可自动化构建Docker镜像的指令。本文将详细介绍
构建docker镜像应该遵循哪些原则
构建 Docker 镜像时,应遵循以下原则: 单一职责:每个镜像应只包含一个应用或服务,避免将多个应用或服务放在同一个镜像中。这样可以确保镜像的易用性、可维护性和可复用性。 最小化
资讯速递 | OpenHarmony竞赛训练营重磅启动,邀您共享OpenHarmony探索与创新之旅!
OpenHarmony竞赛训练营聚焦帮助实现行业需求和三方库补齐。 9月15日,OpenHarmony竞赛训练营正式开启!期待各位同学加入,一起探索OpenHarmony的更多创新与
OpenHarmony竞赛训练营正式启动
,一起探索OpenHarmony的创新与可能! OpenHarmony竞赛训练营活动旨在引导高校学生进行OpenHarmony产学研用,培养更多应用型人才和产业需求有效链接,吸引更多的
诚迈科技6大模块通过OpenHarmony兼容性测评
教育是ICT技术最重要的实践场景之一,科技创新则驱动着教育高质量发展。诚迈科技正在积极探索OpenHarmony产业生态与教育的深度融合,着力开发了一系列OpenHarmony教学信息化设备和方案。
开源图形驱动在OpenHarmony上的使用和落地
本文转载自 OpenHarmony TSC 官方《峰会回顾第10期 | 开源图形驱动在OpenHarmony上的使用和落地》
演讲嘉宾 | 黄然
回顾整理 | 廖涛
排版校对 | 李萍萍
嘉宾简介
发表于 08-31 18:07
移动应用高级语言开发——并发探索
);在IOS上,Swift 5.5实现了结构化编程和Actor,Swift整体并发的演进思路是默认安全的编程模型。
04►OpenHarmony高级语言的并发探索
在JS世界的并发中,如前文所提到的JS
发表于 08-28 17:08
Windows搭建OpenHarmony编译环境
由于OpenHarmony的编译工具链主要是建立在Linux操作系统下,如需要编译OpenHarony内核则需要搭建虚拟机等工序,相对比较繁琐。那么,是否可以在Windows操作系统上实现
发表于 08-16 16:07
docker 搜索镜像,docker查看镜像详细信息(docker下载镜像命令)
Docker Hub是集中管理的Docker镜像注册中心。通过Docker 用户可以在注册中心搜索、下载和使用CLI命令行工具中的镜像。以下是常用的Docker命令搜索镜像: docker
什么是稀疏阵列天线 稀疏相控阵天线优点
稀疏阵列天线(Sparse Array Antenna)是一种天线系统,其中天线元件按照非均匀、稀疏的方式进行排列。相比于传统的密集阵列天线,稀疏阵列天线可以在保持较高性能的同时减少天线的数量。
评论