分类 硬件 下的文章

主要起因是IPv6的出现吧。。现在大部分卖得火的便宜路由器往往会因为要么存储空间或RAM太小,或者CPU等硬件尚未得到支持而无法使用诸如OpenWRT一类的第三方固件。估计是出于商业目的吧,现在的路由器都不会宣称自己支持IPv6,到时候路由器就可以卖两道了。(然而放在移动放在学校寝室里的华为的接入点可以支持IPv6,估计要上千)然后接上自己的路由器,IPv6地址就没了,怪可惜的。因而打算同时支持IPv4+IPv6的“路由器”,学校接入点每次都要登陆,显然不行,主角就打算选这个刚买的开发板了。在我原本的想象中,这件事应该是十分简单的,计算机网络理论十分完整而清晰,再加上GNU这样的开源组织,多少也会提供一个能用的解决方案吧,毕竟路由器这玩意还是十分实用的。结果后来发现,著名的OpenWRT还是因为Cisco因为偷偷使用了Linux才不得不开源的。开源路由固件大头都要靠这种方式开头,这发展指望不得啊,唉。。。

现在的探索历程就很迷,在国内搜,估计基本tmd都是为了应付计网实验的,两台主机,静态ip,加个ip forward完事,要不就是vmware;在国外,也差不多只会实现流量转发的功能,不过写得比较实在,会在标题写上“流量转发”四个大字而不是像国内一样,不但话说不清楚,反倒觉得自己很NB了。看了一下鸟叔的Linux私房菜,不过里面关于路由器的那部分,层次有点高。。那真的是讲路由器的,不过是路由器之间的配置,上升到RIP和OSPF那个层次了。。我想要和下层设备的交互部分,DHCP啊。。

可能是没有找到正确博客的原因吧,在各大搜索引擎上零零散散地只是搜集到了一些相关的组件,比如Linux内核自带的IP转发IP forwarding功能,具有类似IP防火墙功能的iptables提供了网络地址转换NAT功能,hostapd提供的Wi-Fi热点功能,以及提供PPPoE拨号的pppoepppoeconf软件包(Ubuntu)。这虽然已经构成了路由器最基本的功能:数据的定向转发,但是离日常生活中花钱买的路由器还是有点距离的。除路由器的核心功能外,最关键的,也是最常用的一个,私以为便是DHCP了。

从stackoverflow上获得推荐的,ubuntu的官方路由搭建指导: https://help.ubuntu.com/community/Router

里面提到了一个DHCP服务器,不过Debian Buster的apt里面好像没有这个包: https://help.ubuntu.com/community/dhcp3-server

到时候有时间试试手动编译吧。

目前对于整个架构的设想: 使用开发板上的千兆网口作为网络输入,开发板上装Linux系统并进行有线网拨号;(已实现,pppoe) 插入无线网卡(RTL8188EU,已有内置驱动支持),作为Wi-Fi热点的发射装置;(已实现,hostapd) 使用虚拟网桥将有线网与Wi-Fi连接,让连入了Wi-Fi的设备可以手动配置后上网;(根据进一步的调查,发现这个可能要用iptables比较好,网桥的话,pppoe不知道能不能作为设备连接起来) 添加DHCP等路由器-终端自动配置服务,自动完成无线网络参数配置; 最后,如果可能的话,再更改一下Wi-Fi的认证机制,使其支持企业级认证。(记录一下,可能考虑用LEAP或者PEAP)

LLVM连同组件一起编译

对LLVM有初步了解的话,会发现LLVM可以被描述为编译器的“中后端”。也就是说,LLVM本身不是一个完整的编译器,需要与编译器前端等组件配合使用才能完成完整的编译过程。作为可选组件形式与LLVM一同发布的配件就有配置的讲究了。 根据CMakeList文件对组件的配置,加上网上其他人对于编译过程的总结,对组件及其位置罗列如下:

文件名 对应组件 对应位置
llvm-.src.tar.gz LLVM本体 ./
cfe-.src.tar.gz Clang ./tools/clang
compiler-rt-.src.tar.gz Compiler-RT ./projects/compiler-rt
libcxx-.src.tar.gz libcxx ./projects/libcxx
libcxxabi-.src.tar.gz libcxxabi ./projects/libcxxabi
libunwind-.src.tar.gz libunwind ./projects/libunwind
lld-.src.tar.gz LLVM连接器 ./tools/lld
lldb-.src.tar.gz LLVM调试器 ./tools/lldb
openmp-.src.tar.gz OpenMP支持 ./projects/openmp
polly-.src.tar.gz (暂时不懂) ./tools/polly
clang-tools-extra-.src.tar.gz Clang附加工具 ./tools/clang/tools/extra
test-suite-.src.tar.gz 测试程序(相当大) ./projects/test-suite

编译时遇到错误:r7 cannot be used in asm here

https://tls.mbed.org/kb/development/arm-thumb-error-r7-cannot-be-used-in-asm-here

根据上述网站叙述,该问题在于gcc对于arm处理器中寄存器的使用方式与arm自身对编译过程的优化中产生了冲突。arm优化的函数在汇编中显式地使用了编号为r7的寄存器,而在不经优化的情况下,r7被gcc用作帧指针寄存器,不允许被显示地用作其他用途,从而报错。

在解决这个问题时,发现另一个问题:理论情况来说,发布的稳定版的软件源码在编译时会默认设置为发布版本Release,在该模式下,编译器将会对目标软件进行大幅优化以加快运行速度(比如常见的开启-O2-O3选项),删除不必要的调试信息从而缩小软件大小。而LLVM却将其默认设置为了调试版本Debug,在该模式下,将保留较多的源代码信息,能够在出错时较好地帮助开发人员进行调试,也会相比发布版本有着更加接近原代码的二进制逻辑过程,而这也正是上面在直接编译LLVM时遇到错误的原因。

因而解决方法十分清晰了:将CMake中决定编译版本的参数设置为Release即可。

cd /path/to/llvm/src
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release

然后再加上其他需要的参数配置完以后,使用make进行编译即可。

若是只想解决该问题并编译调试版本的话,在编译器参数中加上-fomit-frame-pointer选项即可。

台式机,E3 1245 v2,风扇是玄冰300,之前装电脑的时候不懂事,把涂好了硅脂的新风扇按上cpu后,又拿下来看一下压匀没再装上去。(错误操作请勿模仿:这样会在cpu与风扇接触面之间产生气泡,降低导热效率)用了一年,拆下来之前试了一下,开个rpcs3游戏,(咳咳,rpcs3性能测试专用软件——冷门星mk2(大雾)),六十五六度的样子。

然后本来打算给用了两年的笔记本换个7921,结果。。拆的时候散热螺丝拆坏了,花钱修好顺便上了原装硅脂。然后就想起了如上所述的神奇操作,感觉还是换一下比较好。然后两个重点:

  1. 玄冰300的正确拆卸方式 玄冰300的固定原理是用卡扣将风扇固定在(固定在主板上的)底座上。将风扇上与卡扣相连的金属环向下压,将卡扣较为自然地移出即可。

  2. 7921的正确涂法 网传众多涂法,包括一字、十字、五点、九点,甚至涂匀。台式机上可以直接涂一字,与散热铜管方向垂直即可。(经少量硅脂测试,在涂成圆点的情况下会按照铜管方向扩散得更远)从左涂到右,两边可以留个2-3mm左右的间距,然后直接平压安装风扇即可。这个时候要保证cpu和风扇紧贴,不然进气泡就没什么意义了= =涂完之后从四周侧边观察,有极少量的硅脂溢出,猜测恰好覆盖完全。 笔记本的话可以考虑用刮板在核心上涂好再装散热。但是根据网友反映,这橡皮泥黏刮板比黏核心严重多了。。因而有网友提出,可以按照散热上的金属标记槽(往往是方形)涂好硅脂,然后再与核心贴合。

然后再开冷门星mk2,温度都上不了60度了,快乐

修改/usr/bin/init-zram-swapping文件: 将这一行

mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024))

中除以2那部分替换为自己想要的比例,即默认swap空间为内存容量的1/2。 似乎zram还采用了内存压缩技术,能减少flash写入量?

参考:https://askubuntu.com/questions/730749/how-to-change-zram-size http://www.sbfeng.cn/blog/detail?blogId=1488117926

原因:官网提供的预编译包使用的glibc版本为2.28,而16年编译的Pine A64系统上使用的还是glibc2.23。由于缺乏高版本的符号支持,使用新版本的编译器编译的程序可能会出现找不到符号一类的问题。(在重新编译系统和编译器之间,我选择了后者,因为实在不知道该如何配置多环境glibc了。。)

参考:https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/ 基本上就是翻译了

>>> 本文中的所有操作都假设在用户的家目录下的gnu-aarch64文件夹~/gnu-aarch64/下执行 <<<
>>> 用于编译的文件夹以build-作为前缀,如build-gcc <<<
>>> 编译完成后的工具链安装在dist目录下 <<<
系统为Ubuntu 16.04 Server
这里使用/home/esper/作为用户的家目录。

一套完整的编译工具链由三个部分组成,binutilsgccglibc
三者的功能分别如下:
binutils:顾名思义,与二进制binary相关,负责对二进制文件相关的操作,比如常见的ld(可能全称是link dynamics),即链接动态库,此时的文件已经是编译为二进制的对象文件object file了;在之前的曾经提到过的strip,删除二进制文件中不必要的符号信息,等等。
gcc:全称GNU Compiler Collection,是GNU开源计划的编译器套件。完成的功能是将高级语言转化为对应的机器代码/二进制文件。stdc++库是和gcc一同发布的 -> 想要降级libstdc++,就要降级gcc。
glibcglibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的应用程序编程接口Application Programming Interface, API,几乎其它任何运行库都会依赖于glibc。(摘自百度百科)

事先说明:

  1. 如果编译过程中出现了错误,不要慌!在排查完自己步骤上的错误之后,别忘记怀疑软件和系统!!(惨痛的教训)
  2. 如果遇到了error: cannot compute suffix of object files问题的话,说明你可能是提前开始了gcc的编译,或者没有配置好必要的环境变量。

第一步 准备必要环境

这一步包括所有相关的软件及其相关配置等。

必要软件包

通过包管理器安装-辅助软件包:texinfo, gettext, bison, 用于编译的gcc, make
源码-主要软件包:目标版本的gcc, binutils, glibc, 目标系统对应版本的linux内核源码
源码-辅助软件包:gmp, isl, mpc, mpfr, libiconv
其中软件的版本可通过包内的INSTALL文件中对软件包的要求进行确定。
其中不同发行网站(比如gnu官方和arm官方)提供的gcc源码包内,有的直接提供了可用版本的辅助软件包,有的可以通过contrib目录下的download_prerequisites脚本进行下载。

必要环境变量

需要确保编译完的输出文件夹的bin目录在搜索路径search path中。

export PATH=/home/esper/gnu-aarch64/dist/bin:$PATH

因为交叉工具链的编译是一个可以称为自举的过程,即先编译一部分,然后这一部分参与编译另一部分,直至编译完成。从文首的引用中借图可以清晰展示如下:

1

gccglibc都是交叉工具链的一部分,作为一个整体的工具链,像一个人走路一样左脚、右脚地迈进,而不是各自独立完成编译然后组合在一起。因而,在过程步骤上有点复杂。

第二步 编译安装binutils

为了编译安装软件,对于二进制文件的操作是必不可少的。因而,要先编译用于目标平台的binutils以使得接下来可以修改能在目标平台上运行的程序。

tar xf binutils-2.26.1.tar.gz
mkdir build-binutils
cd build-binutils
../binutils-2.26.1/configure --prefix=/home/esper/gnu-aarch64/dist --target=aarch64-linux-gnu --disable-multilib
make -j4
make install
cd ..

由于configure命令不允许使用相对路径,故需要使用绝对路径。将其替换为自己的用户名。
完成后,直接在命令行输入aarch64,然后多按几次tab键,应该会出现诸如aarch64-linux-gnu-ld的命令补全提示。
如果现象与上述一致,则该步骤成功完成。

第三步 准备linux内核头文件

参考我的这篇博客以获得pine64对应的内核源码。
但是由于在这里,我们的内核头文件不是为系统配置使用的,因而无需使用文中提到的来自longsleep大神的安装脚本。

tar xf linux-pine64-3.10.104-2-pine64.tar.gz
cd linux-pine64-3.10.104-2-pine64
make ARCH=arm64 INSTALL_HDR_PATH=/home/esper/gnu-aarch64/dist/aarch64-linux-gnu headers_install
cd ..

将头文件安装到以架构命名的子文件夹中。这样做的好处是允许系统中同时配置有多个不同环境的编译套件,而且似乎gcc也贯彻落实了这一点——如果不这么做的话,往往会出现意料之外的错误。

第四步 编译安装gcc套件

gcc套件只是工具链的一部分,获得的gcc源码包中还含有libstdc++一类同捆发行的依赖库,在此时并不能完成编译。
可以将gmp, isl, mpc, mpfr, libiconv的源码文件夹链接或是直接解压到gcc源码目录下,configure命令若是识别到了不带版本后缀的文件夹名的话,会试图将该源码包编译,并用于后续的编译过程。否则需要在系统路径提供安装好的、满足版本要求的对应软件包。

tar xf gcc-arm-src-snapshot-8.3-2019.03.tar.xz
mkdir build-gcc
cd build-gcc
../gcc-arm-src-snapshot-8.3-2019.03/configure --target=aarch64-linux-gnu --prefix=/home/esper/gnu-aarch64/dist --with-bugurl=https://bugs.linaro.org/ --enable-gnu-indirect-function --enable-shared --disable-libssp --disable-libmudflap --enable-checking=release --enable-languages=c,c++,fortran --enable-fix-cortex-a53-843419 --disable-multilib
make -j4 all-gcc
make install-gcc
cd ..

如果需要提供ada支持的话,需要安装flex包。由于我的后续工作中用不到,且为了节约时间,就没有编译部分语言的支持。 如果对于configure的参数有疑问的话,可以通过gcc -v获得对应gcc编译器的编译配置参数以参考。

第五步 构建glibc初始环境

根据参考文章的作者描述,除开configure之外,该步骤属于临时性但又不得不做的措施。

tar xf glibc-2.23.tar.xz
mkdir build-glibc
cd build-glibc
../glibc-2.23/configure --prefix=/home/esper/gnu-aarch64/dist/aarch64-linux-gnu --build=x86_64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-headers=/home/esper/gnu-aarch64/dist/aarch64-linux-gnu/include --disable-multilib --disable-werror
make install-bootstrap-headers=yes install-headers
make -j4 csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o /home/esper/gnu-aarch64/dist/aarch64-linux-gnu/lib
aarch64-linux-gnu-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /home/esper/gnu-aarch64/dist/aarch64-linux-gnu/lib/libc.so
touch /home/esper/gnu-aarch64/dist/aarch64-linux-gnu/include/gnu/stubs.h
cd ..

其中根据参考文章的作者描述,glibc的configure必须显式指明build, host, target三个平台参数值。
这里的configure添加了--disable-werror参数,目的在于取消编译器将警告作为错误处理,进而终止编译过程的行为。该参数在软件的编写过程中十分有效,但是在编译一个已经公开发行且没有出现大问题的软件的时候,emm...还是关掉它吧

第六步 编译gcc支持库

cd build-gcc
make -j4 all-target-libgcc
make install-target-libgcc
cd ..

第七步 编译glibc

此时才能使用目标平台的gcc编译glibc。

cd build-glibc
make -j4
make install
cd ..

第八步 完成gcc编译

cd build-gcc
make -j4
make install
cd ..

然后dist目录下就是一套完整的交叉编译工具链了。经过测试,该工具链已经可以生成能在目标平台运行的程序了,但在移动位置之后使用我还没试过。理论上是没问题的,因为arm官方发布的预编译包似乎就是这样。祝好运!

===========================================================
当场补充

相信看到这里,并且在机器上一步一步跟着做的读者(如果有的话)应该是长舒了一口气。然而,在下要在这里提一句,ubuntu上有预编译好的交叉编译工具链,如果你不知道的话。

sudo apt install gcc-5-aarch64-linux-gnu g++-5-aarch64-linux-gnu

(逃