使用Docker启动Linux Riscv版
目标:使用Docker启动Linux Riscv版
以前主要是使用qemu来启动RISCV系统,比如在Linux和FreeBSD系统下,都可以安装QEMU,然后用QEMU仿真RISCV环境。
这回,就用Docker来启动RISCV系统。跟qemu相比,Docker更加简单方便!(事实上并不是)
安装Docker
在Ubuntu等Linux系统下安装docker,直接使用apt install即可:
sudo apt install docker-ce docker-ce-cli containerd.io
安装好后,docker -v看看版本:
Docker version 26.1.3, build 26.1.3-0ubuntu1~24.04.1
这是Windows10里的版本:
docker -v
Docker version 27.3.1, build ce12230
docker search查找镜像(可忽略)
安装好docker,可以使用docker search来查找需要的系统镜像,比如查找关键字nginx、ubuntu、riscv64、riscv32等。
因为直接search会网络报错,所以加上镜像服务器地址参数:register.liberx.info
docker search register.liberx.info/riscv32
NAME DESCRIPTION STARS OFFICIAL
gxrao/riscv32 0
skynesser/riscv32 0
dockcross/linux-riscv32 0
maxxing/riscv32-toolchain 0
ayumiuki/ubuntu riscv32 compiler with spike and pk 0
renefonseca/riscv32-toolchain RISC-V 32-bit toolchain with QEMU based on U… 0
panqinglin/rcore_toolchain a toochain for rcore-riscv32 0
renefonseca/base-ubuntu-riscv32 0
iroazh/clang-riscv32 0
joanbm/riscv32-tools RISC-V 32-bit Tools (GNU Toolchain, ISA Simu… 0
y0n3uchy/riscv-qemu QEMU for riscv32-softmmu 0
kper1337/riscv32-spike-lcb-test 0
renefonseca/qemu-riscv32 QEMU RISC-V 32-bit 0
russkikhmax90/kernelbuild Dev env RISCV32 RISCV64 0
rpirea/build-riscv32-unknown-elf 0
jcaporossi/linux-riscv32 0
siliconbootcamp/verilator-cocotb-riscv32 0
rpirea/riscv32-unknown-elf 0
cccollection/riscv32-ilp32d-glibc 0
tonycrane/riscv32-toolchain 0
kper1337/tc_embench_spike_riscv32 0
smotocel69/riscv32-unknown-elf 0
chinyikming/buildroot-x-riscv32linux-and-riscv32-unknown-elf 32-bit RISC-V GNU toolchains for RV32IMAF an… 0
trmckay/rust-riscv Rust, GNU, and QEMU toolchains for riscv64 a… 0
mmicko/cross-linux-riscv32 0
以下为docker search踩坑经历,可忽略
先上结论:search服务器不通,官方就是不通,所以刚开始直接search都是报错,这个问题耽搁了很久。是一天晚上睡觉的时候,突然想是不是searh就是不通,pull应该通? 结果第二天一早,一试,果然pull是通的,定位到search的问题后,再回过头来解决,发现加上search的镜像地址即可。
踩坑记录:
装好docker后,用docker search查找系统镜像,顺便测试服务器是否装好。
docker search riscv64
发现报错:
Error response from daemon: Get "https://index.docker.io/v1/search?q=riscv32&n=25": dialing index.docker.io:44
3 container via direct connection because has no HTTPS proxy: connecting to index.docker.io:443: dial tcp [2a
03:2880:f10a:83:face:b00c:0:25de]:443: connectex: A connection attempt failed because the connected party did
not properly respond after a period of time, or established connection failed because connected host has faile
d to respond.
应该是docker服务器不通导致的(其实search和pull是两套加速镜像),添加加速镜像地址
到“Docker Engine” 里,修改配置文件,在文件里"experimental": false 后面,加入
,
"registry-mirrors": ["https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"]
还是不行。
因为是在windows10的Ubuntu虚拟机里进行的测试,所以还专门到windows下进行了调试:
到windows目录: C:\Users\Admin\.docker看,有这些文件:
-a---- 2024/12/25 10:47 265 config.json
-a---- 2024/12/25 10:43 714 daemon.json
-a---- 2024/12/25 9:18 34 features.json
-a---- 2024/12/25 10:43 28 windows-daemon.json
其中daemon.json有镜像,但是 windows-daemon.json这个文件里没有,于是在里面也加上镜像:
,
"registry-mirrors": ["https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"]
还是不行。
到Ubuntu24.04,升级docker
sudo apt upgrade docker.io
重启服务
sudo service docker restart
查看一下,应该是生效了:
docker info | grep -A1 "Registry Mirrors"
WARNING: Plugin "/usr/local/lib/docker/cli-plugins/docker-scan" is not valid: failed to fetch metadata: fork/exec /usr/local/lib/docker/cli-plugins/docker-scan: no such file or directory
WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
Registry Mirrors:
https://docker.registry.cyou/
但是还是报错说
docker search nginx
Error response from daemon: Get "https://index.docker.io/v1/search?q=nginx&n=25": dial tcp 202.160.128.238:443: i/o timeout
算了,先搁置。
继续调试
使用docker的时候,直接使用docker命令,发现提示:
Global Options:
--config string Location of client config files (default "/home/skywalk/.docker")
于是到"/home/skywalk/.docker"这个目录里,生成一个daemon.json文件,看看效果
不行....
后来发现,是windows10里的docker配置起决定作用。修改配置,发现docker info也相应修改,但是docker search的时候,还是报错:
docker search nginx
Error response from daemon: Get "https://index.docker.io/v1/search?q=nginx&n=25": dialing index.docker.io:443 container via direct connection because has no HTTPS proxy: connecting to index.docker.io:443: dial tcp 67.230.169.182:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
最终结论:
柳暗花明,发现原来只是search的时候报错,pull的时候是正常的。也就是search是到官网https://index.docker.io/ 去查询,当前是无法连通的,所以会报错。而pull的时候是去加速镜像站下载的,可以正常加速下载。这么个问题困扰了2天,总算弄明白了。
而且知道问题后,直接定点查询,就查到了search 加速的方法,命令里面直接加上镜像服务器地址参数:register.liberx.info 即可。也就是:
docker search register.liberx.info/riscv32
pull 32位riscv镜像(失败)
查找合适的riscv32镜像
可以查找到很多riscv64位的镜像,那都不算啥:
docker search register.liberx.info/riscv64
NAME DESCRIPTION STARS OFFICIAL
riscv64/ubuntu Ubuntu is a Debian-based Linux operating sys… 9
riscv64/debian Debian is a Linux distribution that's compos… 6
riscv64/buildpack-deps A collection of common build dependencies us… 0
riscv64/hello-world Hello World! (an example of minimal Dockeriz… 0
riscv64/rabbitmq RabbitMQ is an open source multi-protocol me… 0
riscv64/alpine A minimal Docker image based on Alpine Linux… 4
riscv64/busybox Busybox base image. 0
riscv64/drupal Drupal is an open source content management … 0
riscv64/php While designed for web development, the PHP … 0
riscv64/bash Bash is the GNU Project's Bourne Again SHell 0
riscv64/wordpress The WordPress rich content management system… 0
riscv64/haproxy HAProxy - The Reliable, High Performance TCP… 0
riscv64/postgres The PostgreSQL object-relational database sy… 0
riscv64/joomla Joomla! is an open source content management… 0
riscv64/nextcloud Nextcloud manual docker image 0
riscv64/composer Composer is a dependency manager written in … 0
riscv64/golang Go (golang) is a general purpose, higher-lev… 0
riscv64/ruby Ruby is a dynamic, reflective, object-orient… 0
riscv64/redis Redis is the world’s fastest data platform f… 0
riscv64/hylang Hy is a Lisp dialect that translates express… 0
riscv64/python Python is an interpreted, interactive, objec… 0
riscv64/tomcat Apache Tomcat is an open source implementati… 0
riscv64/redmine Redmine is a flexible project management web… 0
riscv64/traefik Traefik, The Cloud Native Edge Router 0
riscv64/caddy Caddy 2 is a powerful, enterprise-ready, ope… 0
今天的目标是找到riscv32位的镜像
docker search register.liberx.info/riscv32
NAME DESCRIPTION STARS OFFICIAL
gxrao/riscv32 0
skynesser/riscv32 0
dockcross/linux-riscv32 0
maxxing/riscv32-toolchain 0
ayumiuki/ubuntu riscv32 compiler with spike and pk 0
renefonseca/riscv32-toolchain RISC-V 32-bit toolchain with QEMU based on U… 0
panqinglin/rcore_toolchain a toochain for rcore-riscv32 0
renefonseca/base-ubuntu-riscv32 0
iroazh/clang-riscv32 0
joanbm/riscv32-tools RISC-V 32-bit Tools (GNU Toolchain, ISA Simu… 0
y0n3uchy/riscv-qemu QEMU for riscv32-softmmu 0
kper1337/riscv32-spike-lcb-test 0
renefonseca/qemu-riscv32 QEMU RISC-V 32-bit 0
russkikhmax90/kernelbuild Dev env RISCV32 RISCV64 0
rpirea/build-riscv32-unknown-elf 0
jcaporossi/linux-riscv32 0
siliconbootcamp/verilator-cocotb-riscv32 0
rpirea/riscv32-unknown-elf 0
cccollection/riscv32-ilp32d-glibc 0
tonycrane/riscv32-toolchain 0
kper1337/tc_embench_spike_riscv32 0
smotocel69/riscv32-unknown-elf 0
chinyikming/buildroot-x-riscv32linux-and-riscv32-unknown-elf 32-bit RISC-V GNU toolchains for RV32IMAF an… 0
trmckay/rust-riscv Rust, GNU, and QEMU toolchains for riscv64 a… 0
mmicko/cross-linux-riscv32 0
下载并进入镜像交互模式
下载镜像使用docker pull命令,如:
docker pull docker renefonseca/riscv32-toolchain
可以直接下载、运行并进入交互模式:
docker run -t -i renefonseca/riscv32-toolchain /bin/bash
看看系统
uname -a
Linux e50dc072192d 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
哦,原来还是amd64位系统啊。
再试试这个:
docker run -t -i renefonseca/qemu-riscv32 /bin/bash
最后试的是这个:
docker run -t -i --privileged renefonseca/riscv32-toolchain /bin/bash
然后执行:
cd /riscv32/bin
./qemu-riscv32.sh hello
Hello from RISC-V 32-bit
可见riscv32-toolchain 交叉编译环境是ok了!
docker使用riscv64位系统
退而求其次,先进入riscv64位系统看看
按理说直接使用下面语句就行了:
docker run -t -i riscv64/ubuntu /bin/bash
发现riscv即使64位系统都很少,更不必说32位了。
安装qemu库
发现这个64位系统报错,说不兼容啥的。
原来docker没法像qemu那样支持各种系统,所以要支持riscv64,需要系统安装qemu-riscv64支持:
sudo apt install --no-install-recommends qemu-user-static binfmt-support
sudo update-binfmts --enable qemu-riscv64
sudo update-binfmts --display qemu-riscv64
sudo chmod a+x /usr/bin/qemu-*
下载 riscv64/ubuntu
下载riscv64/ubuntu:21.04
docker pull riscv64/ubuntu:21.04
docker run -it -v /usr/bin/qemu-riscv64-static:/usr/bin/qemu-riscv64-static riscv64/ubuntu:21.04 /bin/bash
运行的时候,增加了-v参数:
-v挂载卷
-v /usr/bin/qemu-riscv64-static:/usr/bin/qemu-riscv64-static
:
- 这是Docker的卷(Volume)挂载功能。
-v
或--volume
标志用于挂载一个主机目录或文件到容器内的指定路径。- 在这个例子中,它将主机系统上的
/usr/bin/qemu-riscv64-static
文件挂载到容器内的相同路径。这意味着容器将使用主机上的qemu-riscv64-static
二进制文件,而不是容器内可能存在的任何版本。
进入系统后,就可以使用/usr/bin/qemu-riscv64-static 啦!
本来想编译一个hello world进去试试呢,但本机实在没法编译成功。
docker虚拟系统里连apt都没有,也就不去刻意去装gcc了。
总结:
本来想安装docker下的32位riscv系统,结果64位riscv都这么难装.....
总体使用下来,感觉如果测试riscv64或32位系统,docker还没有qemu使用起来方便。
学到了docker几招:
1 docker search带加速镜像:
docker search register.liberx.info/riscv32
2 docker pull加速镜像
写在/etc/docker/daemon.json里,格式如:
{
"registry-mirrors": ["https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"]
}
调试
pull报错 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request
docker run -t -i riscv64/debian /bin/bash
Unable to find image 'riscv64/debian:latest' locally
docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
不明白为什么,难道是有些镜像加速服务器里没有,所以去官方服务器去找?
将原来docker加速服务器去掉的两个地址加上。
run报错The requested image's platform (linux/riscv64) does not match the detected host
docker run -it -v /usr/bin/qemu-riscv64-static:/usr/bin/qemu-riscv64-static riscv64/ubuntu:21.04 /bin/bash
WARNING: The requested image's platform (linux/riscv64) does not match the detected host platform (linux/amd64/v2) and no specific platform was requested
exec /bin/bash: exec format error
好像没找到解决的方法....
再找
docker run -t -i ubuntu:12.04 /bin/bash,下载失败。
后来使用docker pull riscv64/ubuntu:21.04 下载成功,后面run也成功了。
riscv64交叉编译失败
写了最简单的helloworld程序:
#include <stdio.h>
void main(){
printf("hello skywalk!\r\n");
// return 0;
}
交叉编译报错:
riscv64-unknown-elf-gcc hello.c
hello.c:1:10: fatal error: stdio.h: No such file or directory
1 | #include <stdio.h>
| ^~~~~~~~~
compilation terminated.
未解决...
安装这些库试试:
apt-get install gcc-multilib g++-multilib
未解决。