分类 操作系统 下的文章

一般情况下这是Ubuntu系统下的包管理工具apt报出的错误。出错的原因通常为包的描述文件损坏。 描述文件的位于/var/lib/dpkg/info,文件后缀为.list,可以用vi查看对应的文件内容。正常情况下为每行一个路径,损坏后会出现大量非法字符。 修复的方法之一为,使用同一个系统的描述文件进行覆盖。

根据stackoverflow上的帖子,提供了这样一种方法:

  1. 删除对应的.list.postrm文件
  2. 执行以下命令:
    sudo dpkg --configure -a
    sudo apt update
    sudo apt upgrade

当然,提一句,根据我的个人理解,后两句是升级软件用的,盲目yes可能会更新某些关键软件版本,导致翻车。 提一个想法,不知道能不能使用apt的--reinstall参数对指定的包进行更新。

起因是高二的时候,看到有100+ RMB的SBC,还能运行Android。
当时父亲还是比较支持我去体验一下新东西的,于是便央求着父亲给我买了一块。
彼时的Pine A64有三个版本,分别是内存512MB,1GB,2GB的。存储空间全部靠外插卡,系统也从此处启动。
当时省钱观念还是比较强的,在考虑用途的同时选择了折中的1GB版。
然后拿它打了半年的废狗,当时用的三棒手机连cpu都没写是哪家的
然而在后来才发现java是个内存怪兽,早知道就直接上2GB的了。
然而,现在2GB的变成了Long Term Supply版,结构也重新被设计过,内存从DDR3L换成了LPDDR3,即低功耗版。
也就是说,现在的2GB的Pine A64已经不能使用以前的镜像了。
不过问题不大,现在看来玩玩GPIO,Python,以及搭建个小服务器什么的,性能还是绰绰有余的。
然后当时为了省钱,做了另一件事情——没有买配套的Wifi+Bluetooth模块。
其结果就是,每当要上网的时候,就要找个有网线的地方(捂脸)。
其实当时手头还是有usb的wifi模块的——万能的RTL88188EU
当时也试过在台式机上给这块网卡编译驱动,不过当时什么都不懂,看着教程一路makemake install就完事了。
后来才发现在半闭源的Android上编译驱动是件难事,而当时也几乎不懂Linux。

1.jpg

到了大学之后,有了更多的时间来研究这个东西,也学习了更多Linux和硬件相关的知识。
在全球巡回演唱会级别的咕咕之后,终于把这个问题解决。步骤如下:

其之一 获取内核源码

首先uname -a一下,从里面找出内核版本kernel version。我的是3.10.104

2.jpg

再到对应的内核仓库repository去看一下,找到对应的发行版本release
仓库地址:https://github.com/longsleep/linux-pine64
点releases去查看所有的发行版本。找到对应的源码source code包如下:

3.jpg

其中第四组数字为内核的修补号,对内核功能没有什么影响。这里选择最新的3.10.104-2-pine64版本。
下载后,使用对应的命令解压,应有如下的目录结构:

4.jpg

其之二 编译内核

在此采用~/Desktop/linux-pine64-3.10.104-2-pine64作为临时目录。

为稳妥起见其实是看不懂参数,获取当前内核的配置文件,作为接下来的配置文件。

cd ~/Desktop/linux-pine64-3.10.104-2-pine64
make mrproper  # clean all previously generated file
cp /proc/config.gz .
gunzip config
mv config .config

就在源码的根目录下直接完成了配置。

然后就直接是make编译生成内核。由于本人在编译gcc时深受-j,即多线程multithreading参数的折磨,再加上没贴散热片怕CPU烧掉,这里采用单线程编译。(当然有兴趣的可以试试-j(自动设置为最大可用线程数)或者-jX(指定为X线程编译))

放了一晚上(也不知道多久),编译完成。

其之三 安装内核头文件kernel_headers

这个编译镜像的人是真的让人服气,tmd一块开发板,你还把头文件排除在外,搞个红红的软链接soft link放在镜像里。
结果,凡是想要编译和内核相关模块的全都搞不了,况且这东西还不知道apt上的general版能不能适配。
好在内核的开发者为我们提供了继续开发的希望,将其中一些工序写成了脚本提供出来,其中恰好有我们需要的。
https://github.com/longsleep/build-pine64-image/blob/master/kernel/install_kernel_headers.sh
没错就是上面这个。
我是直接把脚本的部分内容复制出来执行(为了学习理解),有用的部分从27行开始到最后都是。
理论上把28行删掉,就能够直接将脚本在Pine A64上运行,但是我没有测试。(本机编译不需要跨平台)
其实感觉差不多就是直接运行脚本了。。
我的配置如下:

LINUX_ARCH=arm64
CROSS_COMPILE=
DEST=
TARGET=$DEST/usr/src/linux-pine64-3.10.104-2-pine64

完成一系列命令后,kernel_headers安装完成。
文件目录应当如下:

5.jpg

再在/lib/modules/<kernel-version>下配置好相关的文件链接:

sudo rm -f build
sudo ln -s /usr/src/linux-pine64-3.10.104-2-pine64 $(pwd)/build

这样系统就能正常调用了。

由于系统自身的架构声明为aarch64,实际使用的却是arm64的配置文件,推荐进行以下操作:

sudo ln -s /usr/src/linux-pine64-3.10.104-2-pine64/arch/arm64 \
/usr/src/linux-pine64-3.10.104-2-pine64/arch/aarch64

就可以让某些应用程序编译时获得正确的配置文件。(下文即是其中之一)

其之四 编译网卡驱动

这一部分是写起来最快乐的,因为步骤和一般x86 PC上的没有任何区别。
make allsudo make install,完事!

然后sudo modprobe 8188eu即可加载驱动。

附注:

  1. 请务必确保在安装好的头文件目录下有一个Module.symvers文件,该文件用于链接符号和对应的操作码。 若是缺少的话,加载驱动会失败,且在dmesg中会看到如下信息: 6.jpg 其中8188eu模块报出的是没有Module.symvers文件时的错误,下面的R8188EU是操作正确下发出的信息。 Module.symvers由内核编译时动态生成,这也是前面为什么要编译内核的原因。

  2. 如果有已经配置好的内核源码的话,可以通过使用make modules_prepare进行编译驱动模块的辅助程序配置。 该命令可以解决的问题诸如scripts/basic/fixdep not found一类的问题。

啊,写到下午一点,差不多写完了,肚子早饿了,吃饭去。

  1. ssh-keygen创建多组公钥-密钥对
  2. ~/.ssh下建立config文件,格式如下:
Host host-alias
    HostName your.host.name
    IdentityFile /path/to/privkey
    PreferredAuthentications publickey
    User username

其中Host为该配置文件的“主机名”,即配置git远程仓库时用到的主机名,用于区分不同配置,不应重复
HostName为该配置文件的实际主机名,可重复
IdentityFile放私钥路径,可用相对地址
PreferredAuthentications为连接时的验证方式
User即为用户名(暂时不清楚这个有啥用,就先填用户名吧)

记得把私钥和这个config的权限改成600,为安全起见

参考: https://www.cnblogs.com/popfisher/p/5731232.html

现今绝大多数计算机都是用的是64位系统了,于是默认生成的代码的target也是64位的。 可是。。模拟器只支持32位的指令集,于是只能想办法生成32位的代码。

MIPS:

mips-img-elf-gcc -march=mips32 -mno-local-sdata ...

https://reviews.llvm.org/D4903?id=12672#inline-47153 这里提到了%gp_rel的功能,但是并看不懂 通过-mno-local-sdata使得编译时不生成该标识符。(还是模拟器不支持)

RISC-V: 需要通过编译的时候指定目标架构。 方法之一是只生成32位的编译器:

./configure --prefix=/path/to/installation --with-arch=rv32gc --with-abi=ilp32

似乎还可以通过--enable-multilib的方法在编译程序时指定。(未研究)

补充一个操作:

gcc -E -march=help -xc /dev/null

https://stackoverflow.com/questions/47299458/how-can-i-determine-what-architectures-gcc-supports 使用该命令,版本较新的gcc会把支持的架构作为报错信息输出来。 原作者说的最低版本是gcc7,但是我的gcc6.4也能用

Windows 10默认把硬件时间当成当前时间,时区就成了摆设。 而*nix显示时间的方式是硬件存储的UTC时间+当前设置的时区。 因而如果在两个系统中都开启自动同步时间的话,就会经常出现错乱。 解决方法是在Windows 10中使用硬件的UTC时间存储方式。

修改注册表:

HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation

在该项下新建一个DWORD值RealTimeIsUniversal,取值设置为1。 重启即可。