本机环境:Ubuntu 22.04.1 LTS
目标环境:Openwrt
mips 是32位大端字节序
mipsel 是32位小端字节序
mips64el 是64位小端字节序
换源:
有些包在新源里头
编辑/etc/apt/sources.list
文件, 在文件最前面添加以下条目(操作前请做好相应备份):
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
然后执行命令:
sudo apt-get update
sudo apt-get upgrade
- 输入lsb_release -a查看Ubuntu代号名称:
- 修改sources文件:
sudo vim /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
Openwrt安装:
- 下载openwrt包:
wget https://downloads.openwrt.org/releases/22.03.0/targets/ramips/mt7620/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64.tar.xz
- 解压openwrt包:
tar -Jxf openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64.tar.xz
- 配置环境变量:
PATH=$PATH:~/Openwrt/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/bin
export PATH
export LC_ALL=C.UTF-8
- 编译源码:完了后会在
staging_dir
目录下生成工具链。sudo make menuconfig
sudo make V=s
- 将
SDK
的staging_dir
存到PATH
中使用并查看:PATH=$PATH:/home/kondl/Openwrt/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/bin
export PATH
echo $PATH
- 修改用户目录下的
~/.bashrc
进行配置:export PATH=$PATH:/home/kondl/Openwrt/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/bin
export STAGING_DIR=$STAGING_DIR:/home/kondl/Openwrt/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl
source ~/.bashrc
验证工具链:
- 设置
STAGING_DIR
环境变量为上面工具链目录:export STAGING_DIR=/home/kondl/Openwrt/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64/staging_dir
。 - 写一个
hello world
程序a.c
:
#include <stdio.h>
int main() {
printf("Hello, c!\n");
}
- 使用工具链编译该文件:
$STAGING_DIR/toolchain-mipsel_24kc_gcc-11.2.0_musl/bin/mipsel-openwrt-linux-gcc -o a-c a.c
Rust交叉编译:
- 安装rust环境:
curl https://sh.rustup.rs -sSf | sh
- 设置环境变量:
source $HOME/.cargo/env
- 查看安装结果:
rustc --version
- 安装nightly版本的rust环境:并设置到当前目录
rustup install nightly
rustup override set nightly
- 查看当前支持的target-cpus:
rustc --print target-list
- 安装目标支持环境:
rustup target add mips-unknown-linux-musl
- 交叉编译后目标平台CPU架构是mips、厂商unknown、操作系统linux、运行时库musl。
- 安装rust源码,供交叉编译rust std:
rustup component add rust-src
- 安装xargo工具,该工具方便rust进行交叉编译:
cargo install xargo
- 配置交叉编译的文件:
$ cat .cargo/config
[build]
target = "mipsel-unknown-linux-uclibc"
[target.mipsel-unknown-linux-uclibc]
linker = "$STAGING_DIR/bin/mipsel-openwrt-linux-gcc"
$ cat Xargo.toml
[target.mips-unknown-linux-uclibc.dependencies.std]
features = []
- 配置交叉编译的文件:
[target.mipsel-unknown-linux-musl]
linker = "mipsel-openwrt-linux-gcc"
ar = "mipsel-openwrt-linux-ar"
- 编译
cargo build --target=mipsel-unknown-linux-musl
- 在环境下运行:
以上所述过程简述如下:首先在官网上选择符合你硬件平台的openwrt的固件。在这里我的目标平台的硬件是mt7620a所以选择的包是该平台下的,将固件烧录进硬件中。其次选择下载该平台对应的SDK,编译SDK后可以通过里面的tools目录下的工具来执行我们的代码。
问题1:
目前使用的交叉编译工具链为mipsel,所以可以直接编译对应于硬件为MIPSEL的硬件,但是如果将编译修改成mips,则会报如下所示错误。
/home/kondl/Openwrt/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/bin/../lib/gcc/mipsel-openwrt-linux-musl/11.2.0/../../../../mipsel-openwrt-linux-musl/bin/ld: /home/kondl/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-musl/lib/libcompiler_builtins-40fafdb6a2d34c43.rlib(compiler_builtins-40fafdb6a2d34c43.compiler_builtins.3ff2b44e-cgu.91.rcgu.o): compiled for a big endian system and target is little endian
/home/kondl/Openwrt/openwrt-sdk-22.03.0-ramips-mt7620_gcc-11.2.0_musl.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/bin/../lib/gcc/mipsel-openwrt-linux-musl/11.2.0/../../../../mipsel-openwrt-linux-musl/bin/ld: /home/kondl/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/mips-unknown-linux-musl/lib/libcompiler_builtins-40fafdb6a2d34c43.rlib(compiler_builtins-40fafdb6a2d34c43.compiler_builtins.3ff2b44e-cgu.92.rcgu.o): endianness incompatible with that of the selected emulation
大部分的MIPS和网络字节序一样,为大端模式
ubuntu的虚拟机和arm开发板上都是小端模式
想法:我所对应的网关的openwrt是大端模式,但是我现在使用的openwrt是小端模式,我把我的固件重新烧录后岂不是可以将目标文件改为小端模式就好啦 😃
通过刷新固件的方式发现可以运行之前编译好的程序,但是发现硬件cpu属于大端模式,我们的交叉编译结果为小端模式。两者虽然不符,但是仍然能在其上运行,这 … ??
问题2:
两者的架构不同,如何使得两者的架构统一为大端模式。也就是mips。
思路:目前使用的是openwrt sdk,固件使用的是官方的,官方认为7620为小端,但其实是大端适合我们,下一步可以尝试找到源码并进行编译从而解决大小端问题。
Openwrt源码编译:
- 下载openwrt源码:
git clone https://github.com/openwrt/openwrt.git
- 获取最新的安装包:
./scripts/feeds update -a
- 报错:有依赖的安装包未安装,安装一下就好。
- 安装最新的安装包:
./scripts/feeds install -a
- 选择硬件版本:
make menuconfig
Target System:MediaTek Ralink MIPS
Subtarget:MT7620 based boards
Target Devices:MediaTek MT7620a EVB
- 下载编译的依赖:
make download V=s
- 编译源码:
make V=s
- 安装交叉编译链:
vim ~/.bashrc
export PATH=$PATH:/home/kondl/KonDL_Openwrt/openwrt/staging_dir/toolchain-mipsel_24kc_gcc-11.3.0_musl/bin
export STAGING_DIR=$STAGING_DIR:/home/kondl/KonDL_Openwrt/openwrt/staging_dir
source ~/.bashrc
- 生成交叉编译链
make menuconfig
[*] Package the OpenWrt-based Toolchain
重新编译一遍就能得到交叉编译链
【问题2回答】:
所以综上所属,纯粹是自己对于架构不清楚闹的笑话,嘻嘻。MT7620a就是小端模式,MIPS也不是大端的意思,自己理解有误 😃
之后安装上述所述尝试搭建Rust交叉编译后便完成了openwrt上的rust环境安装。