au Qua Station - Part 4 - Kernel Build and install

Although the Qua station is based on Linux, the factory firmware uses Android for some reason.  This is the first headless Android system I have seen in the wild.  Android is also not really designed for CLI use, and the directory structure is... odd - so for most people it is much easier to set up a "normal" Linux distribution for daily use.

This Post (https://old.haruroid.com/haruroid.0t0.jp/blog/archives/1309.html) described an approach to use the existing kernel and run Debian on top of that using chroot.  (Note; The link above does not work for me in Chrome, but it works in Safari).  That technically works, but it is a bit dodgy.  

The good thing about using the stock kernel from au is that it supports all of the LEDs and buttons, the bad thing is... everything else.  For heavy use, it's probably better to install a native Linux system.

As for trying to use the stock au kernel binary/device tree with a normal distribution: It is easy enough to set up, and the kernel/device tree files can be extracted from the eMMC relatively easily in case you want to USB boot - but there is a watchdog function that keeps resetting the machine every 30 seconds.  

Au/KDDI has released the source code to the kernel, but it is a 4.1.17 kernel.  My attitude is that if it works, it works, so 4.1.17 is fine.  On the other hand, if I have to compile anyway, I would rather use a newer kernel.  Since the QuaStation has no built-in ethernet port (unusual for a NAS, no?), it is required to use a USB ethernet dongle.  I can tell you from my testing the following dongles worked:

1. Apple MacBook Air USB ethernet dongle.  (The original one that says on the package "Compatible only with Apple MacBook Air computers")

2. Nintendo WII ethernet dongle.  

3. Some other generic ethernet dongle I found laying around.

But... none of these are USB 3 Gigabit Ethernet dongles, and since I intend to use these machines for major network traffic, that wouldn't do.  

I found some dongles which were supposed to work well in Linux and tried them:


This TP-Link adaptor claims on their page to "Support Linux", but it doesn't say which versions/distributions. It didn't work for me on on the stock au 4.1.7 kernel.  It is working on the Zidoo rescue image and supported out of the box on 4.9.x by default, though.  


The Buffalo brand adaptor is not advertised as specifically supporting Linux, but the chipset it uses is.  Similar to the adaptor above, it works on 4.9.x out of the box, but again not with the stock au 4.1.17 kernel.  

Update, I also found a tp-link adaptor which contains a USB-3 hub as well.  This is great since the Qua Station has only one USB 3 port.  (The model is UE330)

The Qua Station uses the same SoC as the Banana Pi W2.  Sources are available for that machine for kernel 4.9, so that is a good place to start.  (http://forum.banana-pi.org/t/bpi-w2-new-image-ubuntu-20-04-linux/12288)

I tried to use the kernel from the latest Banana Pi W2 Debian 20 server release as-is, but it did not work, so I had to recompile it with some configuration changes.  (including some found here).

For that, I referred to the lovely guide available here: 【Qua station】 Linuxカーネルをビルドする – お部屋でモバイル

I saved copied of all of these files in case they suddenly become unavailable, so feel free to contact me if you can't find them.  

Recompiling did not work on the Qua Station itself, with strange errors appearing.  Instead, I compiled on my MacBook under Debian 20.  


I was amazed when it compiled in less than a minute, since the poster mentioned that it took around an hour on his computer.  This is probably more because I have 64GB of RAM and am using a fast SSD than it is because the i9 is that much faster than an i3.  

Once the kernel is built, it can be booted from USB relatively easily.  

You need to :

1. Create a FAT32 formatted USB drive.

2. Copy the device tree (dtb), linux kernel, and initrd files from wherever the build process dumps them into a folder on the USB drive. (I took a screen shot here so I would remember the names and path to enter in u-boot in order to load them).


Note that the bpi-w2.dtb device tree only enables 1.6GB of RAM for some reason.  inside the dtb folder there are other files including ~2GB files which may work to enable more RAM.  (It's not critical for my usage, so I am using the default bpi-w2 file for now).  

I took detailed notes on the boot parameters I used in u-boot, which you can find below.

Basically speaking, though, I followed the guide here, which covers booting from USB and also burning the image into the eMMC in order to boot without the USB.  Note that the process for burning to the eMMC is not without risk, because if you overwrite the u-boot firmware, you will be stuck with a bricked machine.  (I don't know anyway to write to the memory without a working u-boot).  

Note about layout: The rescue images typically have one partition that has a FAT32 partition which holds the kernel, device tree, and initrd, and another partition with an ext4 filesystem that has the root filesystem to boot linux.  (Sometimes the root system is a SquashFS image, etc).  

As much as I don't want to use FAT32, that is what u-boot understands.  Also, I want to keep the OS partition separate from my data, and I want to have my data in btrfs.  

There are a few major ways to boot up:
1. Kernel/dtb/initrd on USB, Root FS also on USB
2. Kernel/dtb/initrd on USB, Root FS on SATA
3. Kernel/dtb/initrd on eMMC, Root FS on SATA

These go from less to more involved so we will try in order.  
The other thing is that even if I am from USB or eMMC, I want to have a copy of the kernel/dtb/initrd on my media, so I don't get things mixed up later (or in case I lose a USB drive), so I am always setting up my SD card/SATA drive as follows:
1. FAT32 - ~1GB - Contains kernel, device tree, initrd
2. ext4 - 8~64GB - Contains root filesystem
3. btrfs - 200GB ~ 1TB - Contains the /home/ directory

If you want to experiment with different distributions, then you can add more ext4 partitions with other rot filesystems.  Having more than one root FS also means you can boot up in one, and use the other for the "dd" command to do updates of the root filesystem to/from SD card.

I had to change some things, as my system recognized the internal eMMC as /dev/blkmmc0 in kernel 4.1.17 but /dev/blkmmc1 under 4.9.x.  That can be quite annoying if you are trying to experiment with different kernel versions and want to set up the root filesystem on an SD Card for testing.

Please note that SATA devices show up like /dev/sda under v4.1.x and /dev/sataa under 4.9.x.


Booting Notes:

After copying the files to the USB drive, I used the following commands in u-boot:

usb start

fatload usb 0 0x01f00000 /bpi/bpi-w2.dtb

fatload usb 0 0x03000000 /bpi/uImage

fatload usb 0 0x02200000 /bpi/uinitrd

#You need to tell the system where to use as the root filesystem, what memory addresses to use, and tell it to put the output to the serial port.  
#root filesystem from SD Card
env set bootargs "earlycon=uart8250,mmio32,0x98007800 console=ttyS0,115200n8 initrd=0x02200000,0x7F0000 root=/dev/mmcblk0p2 rw rootwait init=/sbin/init selinux=0 nmiwatchdog=1 rootfstype=ext4 devtmpfs.mount=1 loglevel=7 initcall_debug=1"
# mmcblk0p2 because mmcblk0p1 has a backup copy of the files from USB in partition 1.
# mmcblk1p2 for 4.1.x, as it seems to reverse the SD-card and eMMC

#boot from SATA SSD/HDD
env set bootargs "earlycon=uart8250,mmio32,0x98007800 console=ttyS0,115200n8 initrd=0x02200000,0x7F0000 root=/dev/satab2 rw rootwait init=/sbin/init selinux=0 nmiwatchdog=1 rootfstype=ext4 devtmpfs.mount=1 loglevel=7 initcall_debug=1"
#satab2 because satab1 has a backup copy of the files from the USB
#satab2 should be sda2 for 4.1.x

env set bootcmd booti 0x03000000 - 0x01f00000
b2ndbc
---
There are various warnings, etc., but eventually it boots up:

If you are using the debian image for the Banana Pi, then the root password is "bananapi".  If you used a stock Debian image... well then you can't log in, because you would have to set the password via chroot and enable root login from the console or such before even making the filesystem.  

root@QuaStation:~# uname -a
Linux QuaStation.local 4.9.119-BPI-W2-Kernel #2 SMP PREEMPT Sat Jul 3 01:26:49 PDT 2021 aarch64 aarch64 aarch64 GNU/Linux
This is the kernel I compiled from the BPI sources with config changes, and the root filesystem for Ubuntu server 20 for the BPI - but there were various issues in getting here, and various things to change.    

Issue:kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Root Cause:/dev/satab2 instead of /dev/sda2 (the 4.1.x and 4.9.x kernels display SATA devices differently in the device tree).  It couldn't mount the root device because what I specified wasn't something it recognized.  

Issue: ---[ end Kernel panic - not syncing: Requested init /sbin/init failed (error -2).
Root Cause: Similar to the above.  mmcblk1d2 but should have used mmcblk0d2 because the emmc isn't detected by the kernal  (kernel shows eMMC as mmcblk1 and sd-card as mmcblk0)

Issue: Slow Boot/Ubuntu Server 20 initd issues
Root Cause: Various, but basically un-needed services can be removed or deactivated.
systemctl disable systemd-udev-settle.service
systemctl disable multipathd.service
systemctl disable systemd-networkd-wait-online.service
systemctl disable systemd-networkd-wait-online.service
systemctl disable ifupdown-pre.service
systemctl disable cloud-init.service
systemctl disable networking.service
nano /etc/fstab (fix the LABEL=BPI-BOOT stuff).  

Ethernet driver Test
root@ubuntu:~# dmesg | grep enx
[ 1351.849047] cdc_ether 7-1:2.0 enx28ee5215e0eb: renamed from eth1
[ 1465.477836] cdc_ether 7-1:2.0 enx28ee5215e0eb: unregister 'cdc_ether' usb-xhci-hcd.8.auto-1, CDC Ethernet Device
[ 1481.378386] ax88179_178a 7-1:1.0 enx50c4dd6dc7a0: renamed from eth1
[ 2650.881035] ax88179_178a 7-1:1.0 enx18ece79533e9: renamed from eth1
[ 2668.738468] ax88179_178a 7-1:1.0 enx58278cbe48c4: renamed from eth1

Copying the root partition from the SD card to the SATA SSD after booting:
#Copy from SD card to SATA SSD (dirty way since we are mounted).
dd  status=progress bs=512 if=/dev/mmcblk0 of=/dev/satab
# Fix damage caused by copying mounted FS
chkfs.ext4 /dev/satab
# Add new partition for /home
cfdisk /dev/satab
mkfs.btrfs /dev/satab3

# remove the thing that causes lots of error messages 
apt-get remove cloud-init 
# install useful tools and create /etc/network/interfaces 
apt-get install avahi-daemon mc uptimed mosh ifupdown net-tools 

Once had copied the root filesystem to the SATA drive and everything was working okay, I automated it to start from USB automatically:
#set up to boot from USB
env set bootcmd "usb start;fatload usb 0 0x01f00000 /bpi/bpi-w2.dtb;fatload usb 0 0x03000000 /bpi/uimage;fatload usb 0 0x02200000 /bpi/uinitrd; env set bootargs earlycon=uart8250,mmio32,0x98007800 console=ttyS0,115200n8 initrd=0x02200000,0x7F0000 root=/dev/satab2 rw rootwait rootfstype=ext4 init=/sbin/init selinux=0 nmi_watchdog=1 devtmpfs.mount=1;env set bootcmd 'booti 0x03000000 - 0x01f00000';b2ndbc"

          env save 

 

The next step is to burn the kernel into the eMMC so the USB is not needed at all for booting.

Basically:
1. One pass of dd to zero out the eMMC for the areas where the kernel and bpi go
2. A second pass of dd to copy the kernel and bpi to the eMMC.
3. Changing the boot params to something like the following to make the system boot automatically.
bootcmd=mmc read 0x03000000 1512A 8772;mmc read 0x01f00000 13581 6d;mmc read 0x02200000 230A0 2D7A;mmc read 0x01b00000 135FA 1A8F;env set bootargs earlycon=uart8250,mmio32,0x98007800 console=ttyS0,115200n8 initrd=0x02200000,0x7F0000 root=/dev/satab2 rw rootwait rootfstype=ext4 init=/sbin/init selinux=0 nmi_watchdog=0 devtmpfs.mount=1;env set bootcmd booti 0x03000000 - 0x01f00000;b2ndbc

Realtek> env save                                                               
Saving Environment to FACTORY...                                                
[ENV] Writing to Factory...                                                     
[FAC] factory_save: MMC                                                         
[FAC] Save to eMMC (blk#:0x1100, buf:0x07000000, len:0x22000)                   
[FAC] Save to eMMC (seq#:0x38, pp:0)                                            
done 

    Realtek> reset

 
Notes: 
1. The kernel I compiled seems not to support WLAN at all, but the ethernet adaptors I wanted it to support are working.  (I don't plan to use WLAN, so this is okay for me).  
2. There is a panic issue at shutdown time sometimes with the kernel I compiled.  (late in the process, so not a big issue).  Update: This seems to be because the board doesn't support real power off at all.  
3. You might want to leave the USB boot instead of booting from eMMC, as using USB is an easy way to try out different kernels, etc., without having to open up the system to get at the serial port.  (i.e. you can always stick in a known good USB and get back control of the system).  Booting from eMMC makes more sense once you know you have everything set up how you want it.  
4. U-haru (the blogger) said that only the Zidoo kernel actually worked to write to the eMMC for him.  I haven't noticed an issue.  
6. I tried to build the kernel on the Qua Station again once I was up and running with 4. 9 and Ubuntu 20, but it still did not go well.  It may simply be that the build setup in the file I downloaded from BPI is designed only for cross-compilation.

Here is the error log:

Please choose a mode(1-7): 1

 Now building...

make -C u-boot-rt rtd1296_sd_bananapi_defconfig CROSS_COMPILE=/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/toolchains/gcc-linaro-7.3.1-2018.0
5-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
make[1]: Entering directory '/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/u-boot-rt'
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  SHIPPED scripts/kconfig/zconf.tab.c
  SHIPPED scripts/kconfig/zconf.lex.c
  SHIPPED scripts/kconfig/zconf.hash.c
  HOSTCC  scripts/kconfig/zconf.tab.o
In file included from scripts/kconfig/zconf.tab.c:2534:
scripts/kconfig/confdata.c: In function ‘conf_write’:
scripts/kconfig/confdata.c:765:19: warning: ‘%s’ directive writing likely 7 or more bytes into a region of size between 1 and 4097 [-Wfor
mat-overflow=]
  765 |  sprintf(newname, "%s%s", dirname, basename);
      |                   ^~~~~~
scripts/kconfig/confdata.c:765:19: note: assuming directive output of 7 bytes
In file included from /usr/include/stdio.h:867,
                 from scripts/kconfig/zconf.tab.c:84:
/usr/include/aarch64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 1 or more bytes (assuming 4104) into a desti
nation of size 4097
   36 |   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   37 |       __bos (__s), __fmt, __va_arg_pack ());
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from scripts/kconfig/zconf.tab.c:2534:
scripts/kconfig/confdata.c:768:20: warning: ‘.tmpconfig.’ directive writing 11 bytes into a region of size between 1 and 4097 [-Wformat-o
verflow=]
  768 |   sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
      |                    ^~~~~~~~~~~~~~~~~
In file included from /usr/include/stdio.h:867,
                 from scripts/kconfig/zconf.tab.c:84:
/usr/include/aarch64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 13 and 4119 bytes into a destination o
f size 4097
   36 |   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   37 |       __bos (__s), __fmt, __va_arg_pack ());
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
make[1]: Leaving directory '/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/u-boot-rt'
make -C u-boot-rt all CROSS_COMPILE=/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/toolchains/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu
/bin/aarch64-linux-gnu- BUILD_BOOTCODE_ONLY=true
make[1]: Entering directory '/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/u-boot-rt'
/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/toolchains/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc: 1: canno
t open @@: No such file
/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/toolchains/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc: 1: ELF
: not found
/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/toolchains/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc: 3: Synta
x error: "(" unexpected
/bin/sh: 1: /home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/toolchains/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g
cc: Exec format error
dirname: missing operand
Try 'dirname --help' for more information.
scripts/kconfig/conf --silentoldconfig Kconfig
  CHK     include/config.h
  UPD     include/config.h
  GEN     include/autoconf.mk
/bin/sh: 1: /home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/toolchains/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g
cc: Exec format error
make[2]: *** [scripts/Makefile.autoconf:72: include/autoconf.mk] Error 1
make[1]: *** No rule to make target 'include/config/auto.conf', needed by 'include/config/uboot.release'.  Stop.
make[1]: Leaving directory '/home/console/qua/BPI-W2-bsp-w2-4.9-v1.0/u-boot-rt'
make: *** [Makefile:36: u-boot] Error 2

 Build failed!




Comments

Popular Posts