我的docker随笔46:在x86平台构建龙芯镜像
本文介绍在x86服务器上构建龙芯平台的docker镜像。
前言
去年11月,在龙芯机器上安装了docker工具,并开始尝试研究如何构建龙芯的文件系统。断断续续搞了2个月后,有点结果出来了。前面有文章介绍了如何用debootstrap构建龙芯编译运行环境,本文将进一步,将构建好的文件做成镜像,方便使用。
环境及依赖文件
本文使用的软硬件说明如下。
- x86服务器一台,CentOS7系统。
- 安装docker 20.10.21版本。
- 已配置好qemu。
依赖文件如下。
- 前文构建好的运行环境,压缩包文件为
loong-runfs-gcc-8.3.0-20241202.tar.gz。 - 最新构建的编译环境,压缩包文件为
loong-buildfs-20250213.tar.gz。
docker镜像制作
经研究,除在龙芯机子上构建docker镜像外,还可以在其它平台上构建,再使用qemu-loongarch64-static即可运行。如此一来,运行简单的程序就可以不再依赖龙芯硬件机器了(当然,复杂的还得上硬件)。本节介绍如何制作。
制作压缩包
将前面文章构建好的rootfs做成压缩包,以当前日期打包:
cd loong-buildfs
time tar zcf ../loong-buildfs-$(date "+%Y%m%d").tar.gz .
本次得到的文件为loong-buildfs-20250213.tar.gz,制作压缩包耗时约8分钟。
构建镜像
由于压缩包是完整的文件系统,因此用FROM scratch,即从头开始构建,不需要依赖其它的基础镜像了。在与上述压缩包同一目录添加Dockerfile文件,如下
# 定义当前日期变量
export TODAY=$(date +%Y%m%d)cat << EOF > Dockerfile
FROM scratchADD loong-buildfs-$TODAY.tar.gz /
LABEL version="1.0"
LABEL release="Loongnix GNU/Linux 20 (DaoXiangHu)"
LABEL maintainer="Late Lee"
LABEL buildtime="2025-02-13 23:46"CMD ["/bin/bash"]
EOF
构建镜像:
docker build -t registry.cn-shenzhen.aliyuncs.com/hxr/buildloong:$TODAY .# 顺便打上latest标签
docker tag registry.cn-shenzhen.aliyuncs.com/hxr/buildloong:$TODAY registry.cn-shenzhen.aliyuncs.com/hxr/buildloong
查看镜像:
# docker images | grep loong
registry.cn-shenzhen.aliyuncs.com/hxr/buildloong 20250213 91cbd3e0f843 31 minutes ago 2.7GB
registry.cn-shenzhen.aliyuncs.com/hxr/buildloong latest 91cbd3e0f843 31 minutes ago 2.7GB
运行测试
在x86上先注册qemu-loongarch64-static:
echo ":qemu-loongarch64-static:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01:\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-loongarch64-static:" > /proc/sys/fs/binfmt_misc/register
再启动容器:
docker run -itd --rm --name buildloong -v /etc/localtime:/etc/localtime -v /home/:/home -v /root:/root -v /usr/bin/qemu-loongarch64-static:/usr/bin/qemu-loongarch64-static registry.cn-shenzhen.aliyuncs.com/hxr/buildloong bash
进入容器,查看内核版本:
# docker run -itd --rm --name buildloong -v /etc/localtime:/etc/localtime -v /home/:/home -v /root:/root -v /usr/bin/qemu-loongarch64-static:/usr/bin/qemu-loongarch64-static registry.cn-shenzhen.aliyuncs.com/hxr/buildloong bash
a5de8b323cf3541c788b3c446e05a21cfced5990df6e381f3363ed2c63edf46e[root@localhost tools]# docker exec -it buildloong bashroot@a5de8b323cf3:/# uname -a
Linux a5de8b323cf3 5.16.0 #1 SMP Mon Oct 19 16:18:59 UTC 2020 loongarch64 loongarch64 loongarch64 GNU/Linux
说明:输出loongarch64表示已是龙芯架构了。由于本次运行的服务器系统版本不是很新,因此内核时间是2020年。
下面看一些文件属性:
root@a5de8b323cf3:/# file /bin/ls
/bin/ls: ELF 64-bit LSB executable, LoongArch-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld.so.1, for GNU/Linux 4.15.0, BuildID[sha1]=8fa6f44877798e250e12ef4493b0dc9e329f6893, strippedroot@a5de8b323cf3:/# file /bin/qemu-loongarch64-static
/bin/qemu-loongarch64-static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e776c991b0409cd7bc955a7d6d0616411ca7040b, with debug_info, not stripped
说明:ls文件为LoongArch-64架构。/bin/qemu-loongarch64-static 为x86-64架构,这属正常现象。
退出容器,看一下镜像信息:
# docker inspect registry.cn-shenzhen.aliyuncs.com/hxr/buildloong
[{"Id": "sha256:91cbd3e0f843c8133135396f3df772949178387be2292c8faa7dfe9304d5d62c","RepoTags": ["registry.cn-shenzhen.aliyuncs.com/hxr/buildloong:20250213","registry.cn-shenzhen.aliyuncs.com/hxr/buildloong:latest"],"RepoDigests": [],"ContainerConfig": {"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/sh","-c","#(nop) ","CMD [\"/bin/bash\"]"],"Image": "sha256:c59803d555c9476750c87e012ad396986145ce27266409eb8a4d22c04bb3e961","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"buildtime": "2025-02-13 23:46","maintainer": "Late Lee","release": "Loongnix GNU/Linux 20 (DaoXiangHu)","version": "1.0"}},"DockerVersion": "20.10.21","Author": "","Config": {"Hostname": "","Domainname": "","Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash"],
...},"Architecture": "amd64","Os": "linux",
..."RootFS": {"Type": "layers","Layers": ["sha256:d5e53cf29937d8df0c0945e4f191bb09889c13d10b23a988138d5941a82d54f2"]},"Metadata": {"LastTagTime": "2025-02-13T23:50:24.163418785+08:00"}}
]
输出信息能与构建信息对应,符合预期。
维护思路
由于用debootstrap已经能生成了可跨平台运行的rootfs,如要更新软件或库,使用chroot切换,安装即可。接着将rootfs做成压缩包。再制作成镜像。最后提交远程镜像仓库备用。
另一种制作维护方法
笔者构建的镜像,包括编译环境、运行环境两种。前者体积较大,用于编译场景,后者用于运行测试场景。此处以运行环境为例给出另一种制作维护方法。
运行环境构建Dockerfile内容如下:
FROM scratchADD loong-runfs-gcc-8.3.0-20241202.tar.gz /
LABEL version="1.0"
LABEL release="Loongnix GNU/Linux 20 (DaoXiangHu)"
LABEL maintainer="Late Lee"
LABEL mark="just for loongarch64 running env, not build env."CMD ["/bin/bash"]
构建命令:
time docker build -t registry.cn-shenzhen.aliyuncs.com/hxr/loongrun:20241202 .
同样,在x86平台上运行容器。
docker run -itd --rm --name loongrun -v /etc/localtime:/etc/localtime -v /home/:/home -v /root:/root -v /usr/bin/qemu-loongarch64-static:/usr/bin/qemu-loongarch64-static registry.cn-shenzhen.aliyuncs.com/hxr/loongrun:20241202 bash
如果发现缺少库,则在容器安装好库或软件后,使用docker commit将容器保存为镜像,再提交镜像仓库,如此一来,只针对镜像这一种类型文件操作,无须再用chroot切换环境了。
保存镜像示例命令:
docker commit -m "<这是注释>" <容器名> <镜像名>:<标签名>
如:
docker commit -m "<这是注释>" loongrun registry.cn-shenzhen.aliyuncs.com/hxr/loongrun:20241202
小结
通过本文的实践,可以成功在非龙芯机器上构建并运行龙芯docker镜像。
相关文章:
我的docker随笔46:在x86平台构建龙芯镜像
本文介绍在x86服务器上构建龙芯平台的docker镜像。 前言 去年11月,在龙芯机器上安装了docker工具,并开始尝试研究如何构建龙芯的文件系统。断断续续搞了2个月后,有点结果出来了。前面有文章介绍了如何用debootstrap构建龙芯编译运行环境&…...
移动端测试的挑战与解决方案:兼容性、网络问题及实战策略
引言 移动应用已成为用户触达服务的核心入口,但移动端测试面临设备多样性、网络波动、用户场景复杂等多重挑战。据Statista统计,2023年全球活跃移动设备超180亿台,操作系统(Android/iOS)版本碎片化率超30%,这对测试工程师提出了极高要求。本文深度解析移动端测试的核心痛…...
STM32 I2C通信协议说明
目录 背景 I2C协议 数据的有效性 I2C通信开始和停止条件 I2C数据传输 发送 响应 正常情况: 异常情况: 主机结束接收 写寄存器的标准流程 读寄存器的标准流程 仲裁机制 时钟同步 SDA线的仲裁 程序 背景 对单片机的三大通信中的I2C通信进…...
DeepSeek v3 技术报告阅读笔记
注 本文参考 DeepSeek-v3 / v2 / v1 Technical Report 及相关参考模型论文本文不包括基础的知识点讲解,为笔记/大纲性质而非教程,建议阅读技术报告原文交流可发送至邮箱 henryhua0721foxmail.com 架构核心 核心: MLA 高效推理DeepSeekMOE 更…...
HCIA项目实践(网络)---NAT地址转化技术
十三 NAT网络地址转换技术 13.1 什么是NAT NAT(Network Address Translation)地址转换技术,是一种将内部网络的私有 IP 地址转换为外部网络的公有 IP 地址的技术。其主要作用是实现多个内部网络设备通过一个公有 IP 地址访问外部网络&#x…...
VS studio报错cmake version 3.29.5-msvc4,但是没有其他信息问题解决
背景: windows电脑用VS studio 2022打开一个cmake项目,编译cmake通过,但是没有产生exe文件,IDE也没有打印其他错误信息提示,只有下图: cmake version 3.29.5-msvc4 一开始以为是编译器等问题,…...
免费deepseek的API获取教程及将API接入word或WPS中
免费deepseek的API获取教程: 1 https://cloud.siliconflow.cn/中注册时填写邀请码:GAejkK6X即可获取2000 万 Tokens; 2 按照图中步骤进行操作 将API接入word或WPS中 1 打开一个word,文件-选项-自定义功能区-勾选开发工具-左侧的信任中心-信任中心设置…...
langchain学习笔记之小样本提示词Few-shot Prompt Template
langchain学习笔记之小样本提示词 引言 Few-shot Prompt Templates \text{Few-shot Prompt Templates} Few-shot Prompt Templates简单介绍示例集创建创建 ExamplePrompt \text{ExamplePrompt} ExamplePrompt与 ExampleSelector \text{ExampleSelector} ExampleSelector创建 Fe…...
【CS.SE】优化 Redis 商户号池分配设计:高并发与内存管理
优化 Redis 商户号池分配设计:高并发与内存管理 背景 在分布式交易系统中,商户号池管理是核心模块之一。传统的商户号生成方式,依赖数据库预分配号段,导致大量号段浪费,并且在高并发请求下,性能难以满足需…...
5、《Spring Boot自动配置黑魔法:原理深度剖析》
Spring Boot自动配置黑魔法:原理深度剖析 一、引言:为什么Spring Boot能“开箱即用”? Spring Boot的核心理念是**“约定优于配置”,开发者只需引入一个spring-boot-starter-web依赖,就能直接编写RESTful API…...
稀土抑烟剂——为纺织品安全加持,保护您的每一寸触感
一、稀土抑烟剂的基本概念 稀土抑烟剂是基于稀土元素(如稀土氧化物和稀土金属化合物)研发的一类新型阻燃材料。它能够有效提高纺织品的阻燃性,抑制火灾发生时产生的烟雾和有害气体,减少火灾对人体的危害。稀土抑烟剂具有更强的稳…...
如何使用CSS画一个三角形,原理是什么?
如何用 CSS 画一个三角形?原理和实战指南 一、核心原理 CSS 画三角形的本质是利用边框(border)的叠加特性。当一个元素的宽高为 0 时,其边框会以对角线形式相交,形成四个独立的三角形区域。通过控制某一边的边框颜色为…...
Docker拉不下来镜像问题解决法案
打开docker的设置界面 配置如下: vi /etc/docker/daemon.json {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["…...
DeepSeek 多模态大模型Janus-Pro本地部署教程
1.部署环境配置 我个人用的是Mac的m1pro 16512配置,我跑了1B的版本很流畅,7B的也可以跑起来,稍微感觉有一些卡顿。 需要安装Git-lfs,访问官网下载安装包安装,这个工具是用于下载大型文件必备的软件,这里用…...
笔记8——模式匹配 match语句(仅在Python 3.10及以上版本中可用)
文章目录 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用)基本语法基本匹配操作应用场景 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用) Python 3.10 及以上版本中才引入了 match 语句用于简化复杂的条件判断和数据解构;类似于其他语言中的 swit…...
maven-antrun-plugin插件的用法
maven-antrun-plugin 是 Maven 中一个非常强大的插件,它允许你在 Maven 构建过程中运行 Apache Ant 任务。通过这个插件,你可以在 Maven 构建的各个阶段(如 compile、package 等)中执行自定义的 Ant 任务,比如复制文件…...
iOS主要知识点梳理回顾-4-运行时类和实例的操作
类和实例的操作 iOS 运行时(Objective-C Runtime)提供了丰富的 API 来对类进行动态操作,包括创建类、修改类的结构、添加方法、替换方法等。这对于实现动态特性、AOP(面向切面编程)、方法拦截等功能非常重要。以下举例…...
vue2和vue3生命周期的区别通俗易懂
用最直白的对比帮你理解 Vue2 和 Vue3 生命周期的区别,就像对比手机系统的升级: 一、生命周期阶段对比表(老手机 vs 新手机) 阶段Vue2(老系统)Vue3(新系统)变化说明初始化beforeCre…...
使用 meshgrid函数绘制网格点坐标的原理与代码实现
使用 meshgrid 绘制网格点坐标的原理与代码实现 在 MATLAB 中,meshgrid 是一个常用函数,用于生成二维平面网格点的坐标矩阵。本文将详细介绍如何利用 meshgrid 函数生成的矩阵绘制网格点的坐标,并给出具体的代码实现和原理解析。 实现思路 …...
postgresql源码学习(59)—— 磁盘管理器 SMGR
一、 定义及作用 PostgreSQL 的磁盘管理器(Storage Manager,简称 SMGR)是数据库系统中负责管理底层存储的核心模块。磁盘管理器并非直接操作磁盘上的文件,而是通过VFD(虚拟文件描述符,将在后续学习…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
