跳转至

hardware

向咸鱼派写入 ArchlinuxARM

之前由于我的 macOS 上不知道为啥不能把我的 TF 卡设备放到我的虚拟机里,所以之前就没能刷 ArchLinuxARM 上去。今天我想到了一个方法,完成了这件时期:

$ wget https://mirrors.tuna.tsinghua.edu.cn/archlinuxarm/os/ArchLinuxARM-armv7-latest.tar.gz
$ dd if=/dev/zero of=archlinuxarm.img bs=1M count=1024
$ mkfs.ext4 archlinuxarm.img
$ sudo mkdir -p /mnt/archlinuxarm
$ sudo mount -o loop archlinuxarm.img /mnt/archlinuxarm
$ sudo bsdtar -xpf ArchLinuxARM-armv7-latest.tar.gz -C /mnt/archlinuxarm
$ sudo umount /mnt/archlinuxarm

这样就获得了一个 ext4 的 ArchlinuxARM 镜像。刚好解压出来不到 1G,所以开了 1G 的镜像刚好放得下。然后把 archlinuxarm.img 拷回 macOS,然后用 dd 写进去:

$ sudo dd if=archlinuxarm.img of=/dev/rdisk4s2 bs=1048576

这时候可以确认,我们确实是得到了一个正确的 ext4fs:

$ sudo /usr/local/opt/e2fsprogs/sbin/tune2fs -l /dev/disk4s2

不过,我们实际的分区大小可能不止 1G,所以可以修改一下大小:

$ sudo /usr/local/opt/e2fsprogs/sbin/resize2fs -p /dev/disk4s2

这样就成功地把 ArchlinuxARM 写进去了。默认的用户名和密码都是 root,可以成功通过串口登录。

咸鱼派的启动配置

最近刚拿到了一个咸鱼派的测试板子,准备自己把 U-Boot 和 Linux 内核这一套东西跑通,都用主线的东西,尽量减少魔改的部分。首先是编译 u-boot,我用的是现在的 master 分支的最新版 99431c1c:

$ # Archlinux
$ sudo pacman -Sy arm-none-eabi-gcc
$ make LicheePi_Zero_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j24

这时候会得到一个 u-boot-sunxi-with-spl.bin 的文件。我们只要把它写到 SD 卡的 8192 偏移处,就可以把 U-Boot 跑起来了:

$ diskutil unmountDisk /dev/disk4
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/disk4 bs=1024 seek=8

接着我们做一下分区。我采用的是 MBR 分区,这样保证不会和 U-Boot 冲突。使用 fdisk 进行分区,我从 1M 处开始分了一个 10M 的 FAT-32 分区作为启动分区,然后之后都是 EXT4 的系统盘分区。接着就是编译内核。

我用的是八月份时候的 4.18.2 内核,虽然不是很新但也足够新了。一番调整内核参数后,得到了一个可用的内核,然后把 zImage 和 sun8i-v3s-licheepi-zero.dtb 都复制到刚才创建的 FAT-32 启动分区,然后进入 U-Boot 进行启动:

$ setenv bootcmd 'fatload mmc 0 0x41000000 zImage; fatload mmc 0 0x41800000 sun8i-v3s-licheepi-zero.dtb; setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait; bootz 0x41000000 - 0x41800000'
$ saveenv # optional
$ boot

这里一开始遇到了很多坑,比如一直看不到 console,这个是找了 @gaoyichuan 拿到的一份 Kernel Config 进行修改修好的。另一个是进去以后找不到 root,我先是搞了一个有 busybox 的 initrd,进去看发现是能找到 mmc 的,但是有延迟,那么添加上 rootwait 就好了。进去以后就差 rootfs。由于我缺少一个写 ext4 的工具,又发现手上有一个 Raspbian 的镜像,它里面也正好是两个分区,而且架构也同样是 armv7l,我就直接把它烧到 SD 卡中,把 U-Boot 写进去,然后往 boot 分区里写内核和 dtb,然后就成功进去,并且跑起来了。最喜感的就是,进去以后是个 pi@raspberrypi,实际上确是另一个东西。不过,只有当我 apt update 发现用了半小时的时候,我才想起来这其实是是一个嵌入式系统。。

进去以后发现,没有识别到网卡驱动。网上找了 LicheePi Zero 的一个解决方案,但是并不能用,还出现了神奇的 Kernel Oops,怀疑是内核版本太新的问题。我又找到 @icenowy 的一个 Patch ,它终于是解决了这个问题,成功地找到了网卡,并且愉快地 ssh pi@raspberrypi.local 。之后会在咸鱼派那边公布一下我们做的修改。

现在的想法是,把 HomeBridge 搭建到它上面,不过目前来看硬件资源有点紧张,放着会有点慢。可能还是用树莓派做这个事情比较合适。

在荔枝糖(Lichee Tang)上初次体验 FPGA

今天从张宇翔学长那拿到了 荔枝糖(Lichee Tang) 的 FPGA 板子,于是立即开始把前段时间学到的 Verilog 应用上来。不过想到现在我手上没有多少外设,然后又必须远程到 Windows 电脑上去操作,于是先实现了一下 UART 通信。

在网上找到了 ben-marshall/uart 一个简易的实现,很快做到了一直在串口上打印 A 字符。接着我开始尝试实现一个简单的串口回显。一开始,我直接把 UART 读到的数据直接输出,果然可以了,但是一旦传输速率跟不上了,就会丢失数据。于是我添加了 FIFO IP 核,然后把读入的数据存入 FIFO,又从 FIFO 中读取数据写入到 UART 中去。不过发现了一个小 BUG:每次打印的是倒数第二次输入的字符,即丢失了第一个字符。在张宇翔学长的帮助下找到了问题:当 FIFO 的读使能信号为高时,其数据在下一个时钟周期才来,于是解决方案就是等到数据来的时候再向 UART 中写数据:

always @ (posedge clk_in) begin
    uart_tx_en <= uart_fifo_re;
end

这样就解决了这个问题。完整代码在 jiegec/learn_licheetang 中。

在 macOS 上读取移动硬盘的 S.M.A.R.T. 信息

之前想看看自己各个盘的情况,但是发现只能看电脑内置的 SSD 的 S.M.A.R.T 信息,而移动硬盘的都显示:

$ smartctl -a /dev/disk2
smartctl 6.6 2017-11-05 r4594 [Darwin 17.7.0 x86_64] (local build)
Copyright (C) 2002-17, Bruce Allen, Christian Franke, www.smartmontools.org

/dev/disk2: Unable to detect device type
Please specify device type with the -d option.

Use smartctl -h to get a usage summary

一开始我怀疑是个别盘不支持,但换了几个盘都不能工作,问题应该出现在了 USB 上。查了下资料,果然如此。根据 USB devices and smartmontools ,获取 S.M.A.R.T 信息需要直接发送 ATA 命令,但是由于经过了 USB,于是需要进行一个转换,导致无法直接发送 ATA 命令。这个问题自然是有解决方案,大概就是直接把 ATA 命令发送过去(pass-through)。上面这个地址里写到,如果需要在 macOS 上使用,需要安装一个内核驱动。可以找到,源码在 kasbert/OS-X-SAT-SMART-Driver 并且有一个带签名的安装包在 External USB / FireWire drive diagnostics support 中可以下载。丢到 VirusTotal 上没查出问题,用 v0.8 版本安装好后就成功地读取到了移动硬盘的 S.M.A.R.T 信息了。

然后我又简单研究了一下各个 S.M.A.R.T 各个值的含义是什么。 VALUE 代表当前的值, WORST 代表目前检测到的最差的值, THRESH 代表损坏阈值。这些值都是从 RAW_VALUE 进行计算后归一化而来。然后 TYPE 分为两种,一是 Pre-fail ,代表如果这一项的值小于阈值,代表这个机器很危险了,赶紧拷数据丢掉吧。二是 Old_age ,代表如果这一项小于阈值,代表这个机器比较老了,但还没坏。真正要看是否坏了,可以看 When_Failed 一栏。