ジャンル不定の日記です。

今日もBuildroot

昨日寝てる間にlighttpdをuhttpdに置き換えてBuildrootし直したのだが、容量が減るどころか微妙に増えた気が・・・
って感じだったのだが、lighttpdは消したのだが/usr/lib以下にlighttpd関連が残ってた。
なので make distclean してからbuildrootし直した。
13MB強になったので4MBほど減ったかな?
と思ったが、8189es入れたら15MB強になった。
まあ、httpdがない状態でも13MB強だったからuhttpdはほとんど消費しないかも。
httpdは入れときたいしこれで行く。
8189es.koは1.5MB近くあるのね・・・

だいぶ記事が別れてるんで、 Buildroot の手順まとめとく。

$ git clone git://git.buildroot.net/buildroot --depth=1
$ make orangepi_r1_defconfig
$ make menuconfig
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi-
これで Orange pi R1 用のOSイメージができちゃう。
が、zImage とかは別途調整したいんで  rootfs.ext2 だけ使ってる。

BusyBoxの機能は package/busybox/busybox.config で設定できる。
標準で depmod がないが
# CONFIG_DEPMOD is not set

CONFIG_DEPMOD=y
に代えれば depmod できるようになる。
Buildrootでインストールできるkmodを入れれば代用できると思うがBusyBoxに機能追加のほうが小さいと思う。

menuconfigでは、
Toolchain  --->
    Custom kernel headers series (5.4.x)
    [*] Enable WCHAR support
System configuration  --->
    [*] Enable root login with password
        (0000) Root password
Kernel  --->
    [*] Linux Kernel
        Kernel version (Custom version)  --->
            (5.4.12) Kernel version
Target packages  --->
    Networking applications  --->
        [*] dnsmasq
            [ ]   tftp support
        [*] hostapd
        [*] nftables
        [*] openssh
        [*] pppd
        [*] uhttpd
    Shell and utilities  --->
        [*] sudo
    Text editors and viewers  --->
        [*] nano
こんな感じで、rootパスワードの設定と、KErnelを5.4.12に変更。
5.4.xにした場合はCustom kernel headers series (5.4.x)にしないと途中でエラー落ちする。
nanoをインストールするのにEnable WCHAR supportが必要。
パッケージは、
dnsmasq hostapd nftables openssh pppd uhttpd sudo nano
を入れた。
dnsmasqのtftpdは明らかに要らないんで消した。
hostapdにも要らない機能ありそうだがよくわからないのでそのままにした。

Squashfsマウントできた

Orange pi R1用OS作成でSquashfsマウントできた。initramfsなしで。
リードオンリーになっちゃうけど、これで/sbin/init実行できるから/etc/fstabにoverlay書けばいいんじゃないかな?

まずinitramfsを使ってみようと思って、実機の方で作業しようと思ったがBusyBoxのcpioが違っててやり方がわかんなかったので母艦でやった。
$ su
# mount /dev/sdg2 /mnt
# mkdir /tmp/initrd
# mkdir /tmp/initrd/dev
# mkdir /tmp/initrd/bin
# mkdir /tmp/initrd/mnt
# cp -a /mnt/bin/busybox /tmp/initrd/bin
# ln -s busybox /tmp/initrd/bin/sh
# ln -s busybox /tmp/initrd/bin/mount
# ln -s busybox /tmp/initrd/bin/switch_root
# nano /tmp/initrd/init
# chmod 744 /tmp/initrd/init
# mount /dev/sdg2 /mnt
# cd /tmp/initrd
# find . | cpio -o | gzip -9 -c > /mnt/initramfs.img
こんな感じの作業内容かな?
作業ディレクトリのしたに dev bin mnt を作成。
binにbusyboxをコピーしてシンボリックリンクで sh mount switch_root を作る。
作業ディレクトリの直下に init スクリプトを作る。
initの内容は
#!/bin/sh
/bin/mount -t devtmpfs devtmpfs /dev
/bin/mount /dev/mmcblk0p2 /mnt

exec /bin/switch_root /mnt /sbin/init
/dev にdevをマウントする。
/mnt にrootfsをマウントする。
/mnt にswitch_root で/sbin/init を実行。
て感じかな?
initを実行可能にして作業ディレクトリをinitramfs化する。

てな感じでやってブートしてみてエラーでなかったが、もともとextのrootfsでinitramfsなしでブートできてたからよくわからん。
というわけで、rootfsをSquashfsにして起動してみたがダメ。initramfsなしでブートしてもダメ。
kernelをSquashfs有効にしないで作ってるから当然w

kernel作り直しだが、menuconfigの Miscellaneous filesystems の下にSquashfsあった。
これ有効にしてリビルド。
extのrootfsで起動確認したあとでSquashfsで起動してみたが、initramfsなしで起動できた。
# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root                 7424      7424         0 100% /
devtmpfs                116652         0    116652   0% /dev
tmpfs                   125356         0    125356   0% /dev/shm
tmpfs                   125356        32    125324   0% /tmp
tmpfs                   125356        24    125332   0% /run
圧縮しても7MBで、u-bootとzImage等で別途5MBくらい必要だから余裕ないね。
今回のリビルドの際に要らないもん消したからzImageは4MB割ってるがあまり削減余地はなさそう。

BusyBoxは標準でdepmodが無効だった

作成中のOrange pi R1用OSでwlan0を出すために8189es.koをビルドして入れたんだが、depmodが無かった。

というわけでbusyboxだけmakeしようとしたんだが、limits.hがないとか怒られた。
Buildroot使うとビルドできるのになんでー
って感じだが、BuildrootのMakefile見たら、
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- busybox
すればbusyboxだけBuildrootで作れそう?
というわけでやったらできた。
package/busybox/busybox.configで
CONFIG_DEPMOD is not set
のところを
CONFIG_DEPMOD=y
にしたらoutput/target//sbin/depmodがoutput/target/bin/busyboxへのリンクになってた。

sdイメージの方にbusyboxコピーしてlnでdepmod作ったらできた。
wlan0も無事出てきた。
/bin/busyboxはsビットがついてるので消えないように。

linux 5.4.12でBuildrootし直した

Orange pi R1ルーター化計画でSPIフラッシュにのるサイズまでOSサイズを削減しようとしてSquashfsを使おうとしたがつまずいたので、まだできてない。
とりあえず5.4.12でBuildrootできた。

最初 Buildroot のmenuconfigで
Kernel Version ---> Latest version (5.4)
にしてやってみたが、これだと5.4.10になった。先日gitからkernelビルドやったときは5.4.11だったので下がってる。
だが、kernelバージョンが変わったときは、
Toolchain ---> Custom kernel headers series (5.3.x)
となってるところを5.4に変えないとmakeがかなり進んでからエラーになった。

で、やり直しの際に、Kernel Versionをgit URLにすることができることに気づいたので5.4.11にしようと思った。
その場合は Custom repository version がブランチ名になるみたい。わかりにくい・・・
でやってみたが、depth指定の方法がわからなく、大量に持ってこようとしてたので強制終了した。

次にtarballのURL指定ができることがわかったのでtarballで指定したが、最新stableが5.4.12に増えてたので5.4.12にした。
ビルドする際、squashfsとinitramfsを作成しようと思って、ext2/3/4のチェックは要らないと思ったので外した。
そしたらimageを作る最終段階でエラー。
squashfsのイメージはできあがったので、それをextで作ったパーティションイメージにコピーして起動しようとしたが起動できなかった。
それでinitramfs経由で起動を試みたりして時間食ったが、断念した。

再度のBuildrootし直しで、
Kernel version (Custom version)
(5.4.12) Kernel version
とすれば5.4.12でBuildrootできることがわかった。
のでmakeしたのだが、最初と同じくToolchain ---> Custom kernel headers series (5.3.x)のままやっちゃって止まった。
のでまたやり直しとなった。

時間かかったが、とりあえず5.4.12で起動するイメージは作成できた。
前回見つからなかったので入れなかったが sudo があったので入れた。
iptablesの後継のnftablesなるものがあったのでiptablesを置き換えてみた。
容量行けそうなんでlighttpd入れた。
のだが前回13MBだったが17MBに増えた。
lighttpdよりuhttpdのが小さそうな気がするが、Archにパッケージがないレベルでマイナーみたいなのでlighttpdにした。
あまり容量に余裕はないか?

Squashfsでどの程度サイズが減るのか確認してみた

Orange pi R1用OSをSPIフラッシュにのせるために16MB未満への容量削減を考えてるが、
一般的な圧縮ファイルシステムは読み込み専用な模様。
読み込み専用のファイルシステムを/に使うなら書き込み可能なファイルシステムを重ねる必要がある。
というわけで、いくつか選択肢はあるようだがカーネルにoverlayfsという重ねるFSはあり、圧縮の方はSquashfsというのがよく使われるぽい。

まず、Squashfsで圧縮した場合、目的が達成できそうか確認のために、Buildrootで作ったext4のrootfsをSquashfsにしてみた。

$ df
ファイルシス   1K-ブロック      使用     使用可 使用% マウント位置
.
.
.
/dev/sdg2            55397     13211      37886   26% /home/user/stock/sbc/opi-r1/mnt
ext4のSDカードをマウントしたが13MB強。
kernelとかは別なんでこれでは16MBをオーバーしちゃう。

$ sudo mksquashfs mnt squashfs.img
$ sudo umount mnt
$ sudo mount squashfs.img mnt
$ df
ファイルシス   1K-ブロック      使用     使用可 使用% マウント位置
.
.
.
/dev/loop0            4864      4864          0  100% /home/user/stock/sbc/opi-r1/mnt
4.8MBまで減った!
mksquashfs は ソースディレクトリと出力イメージファイルを引数にすればgz圧縮してくれるみたい。
他の圧縮タイプも選べる感じ。

Buildrootをやってみた

Orange pi R1のOSをSPIフラッシュに入る16MB未満で作りたいと考えてるが、
コマンド群をまとめる BusyBox は必要と思われる。BusyBoxならinitとかコンソールもまとめて置き換えられる。
BusyBoxのサイト見てたら、uClibcなるものを知った。glibcを置き換えるものでこれも必須ぽい。
さらに、BusyBoxとuClibcでrootfsを作るというBuildrootというものを知ったのでやってみた。

すごく簡単にu-boot linux rootfsを全部作れちゃう。
アプリが何も入ってないディストリビュージョンみたいな感じ。

$ git clone git://git.buildroot.net/buildroot --depth=1
$ make orangepi_r1_defconfig
$ make menuconfig
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi-
これでSD用のimageが出来上がるんでddで書き込むだけ。

menuconfigではとりあえず、
Toolchain --->
 Enable WCHAR support
System configuration --->
 (0000) Root password
 [*] Install timezone info
Target packages --->
 Networking applications --->
  [*] dnsmasq
  [*] dhcp support
  [*] hostapd
    [*] iptables
  [*] openssh
  [*] pppd
 Text editors and viewers --->
  [*] nano
ここだけいじった。
BusyBoxだけでviもどきが使えると思うが、viは使いこなせないのでnanoを選択したが、nanoにWCHAR supportが必要。
ルーター用なんで dnsmasq hostapd iptables pppd openssh を選択した。
RTL8152Bは標準で入るんでeth1は有効になるがwlan0は出てこないんで8189esは別途ビルドが必要そう。
kernelバージョンは標準で5.3.12だったが変更もできそうな感じ。

SDカード用のイメージは標準で60MBになるが、
/boot 10MB
/ 55MB
くらい?
/の使用済みは13MB強だった。

wlan0 出てきた!

かなり苦戦したが、Orange pi R1 の自ビルドカーネルでwlan0出てきた。
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 02:42:87:c2:e6:34 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.106/24 brd 192.168.2.255 scope global dynamic eth0
       valid_lft 22828sec preferred_lft 22828sec
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether c0:74:2b:ff:da:7b brd ff:ff:ff:ff:ff:ff
4: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 7c:a7:b0:81:a5:6f brd ff:ff:ff:ff:ff:ff

Orange pi R1 のwifiチップは RTL8189FTV なんで最初 https://linux-sunxi.org/Wifi#RTL8189FTV 参考に、
$ git clone https://github.com/jwrdegoede/rtl8189ES_linux.git
$ cd rtl8189ES_linux.git git checkout -B rtl8189fs origin/rtl8189fs
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- KSRC=../linux
とやって8189fs.koを作ったが、8189fsはロードできるのだがwlan0が出てこなかった。
これのビルドの際にはkernelのmenuconfigで作れるがcfg80211が必要。

RTL8189FTVはSDIOデバイスのようなので、SDIO関連のモジュール入れたり、他のRealtekドライバ入れたり試してみたが解決しなかった。
その際にR1の有線LANの片方はRTL8152Bなんでそれも有効にしたんでeth1は出るようになった。

wlan0が出てくるArmbian確認したらKernel 5.4.8でモジュールは8189fsではなく8189esだった。
kernelバージョン近いし手段はありそうだが・・・
5.4.8のカーネルを自ビルドしてArmbianのモジュールを流用しようか・・・

とか考えてたが、
モジュール作成の際にRTL8189FTVモジュールのビルド手順でブランチをmasterからrtl8189fsに切り替えて8189.fsができあがったが、
$ git checkout master
$ make clean
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- KSRC=../linux
としてmasterブランチに切り替えてやり直してみた。
そうすると8189es.koが出来上がる。
これいれたらwlan0でてきた。

8189fs.ko のビルドはできたのだが・・・

8189fs.ko のビルドはできた。
linuxのmenuconfigで無線を有効にしなきゃいけなかった。

↑こんな感じにしてカーネルのビルドをやり直した。
だが、まだ調整必要だから、ここは*にしてカーネルに組み込むんじゃなくてMにしてモジュールにするんだった。

そして、モジュールは1個もないが、
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- modules
する必要があった。
これするとモジュール以外に modules.order と modules.builtin ができる。
これを /lib/modules/5.4.11 に置かないと depmod ができない。

カーネルの再ビルドしたあとは 8189fs のビルドはすんなりいった。
8189fs.ko も/lib/modules/5.4.11 に置いた。

# depmod -a
# modprobe 8189fs
でモジュールのロードはできたぽい。

が、wlan0とかインターフェイス何も出てこない・・・
あと、eth0はあるけどeth1がないね。
これもなんかモジュールいるね。

RTL8189FTV用ドライバの作成に失敗・・・

Orange pi R1のwifiチップはRTL8189FTVなわけだが、
https://linux-sunxi.org/Wifi によると
$ git clone https://github.com/jwrdegoede/rtl8189ES_linux.git
$ cd rtl8189ES_linux.git git
$ checkout -B rtl8189fs origin/rtl8189fs
$ make -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnu- KSRC=../linux
で作れるぽいことが書いてある。

クロスコンパイラは手元のに合わせてやってみたが、
  LD [M]  /run/media/user/1c2f8fa0-9a7c-4de1-b384-9d5e79bbf856/src/opi-r1/rtl8189ES_linux/8189fs.o
  Building modules, stage 2.
  MODPOST 1 modules
ERROR: "wiphy_free" [/run/media/user/1c2f8fa0-9a7c-4de1-b384-9d5e79bbf856/src/opi-r1/rtl8189ES_linux/8189fs.ko] undefined!
ERROR: "cfg80211_unlink_bss" [/run/media/user/1c2f8fa0-9a7c-4de1-b384-9d5e79bbf856/src/opi-r1/rtl8189ES_linux/8189fs.ko] undefined!
.
.
.
ERROR: "cfg80211_inform_bss_frame_data" [/run/media/user/1c2f8fa0-9a7c-4de1-b384-9d5e79bbf856/src/opi-r1/rtl8189ES_linux/8189fs.ko] undefined!
make[2]: *** [scripts/Makefile.modpost:94: __modpost] エラー 1
make[1]: *** [Makefile:1609: modules] エラー 2
make[1]: ディレクトリ '/run/media/user/1c2f8fa0-9a7c-4de1-b384-9d5e79bbf856/src/opi-r1/linux' から出ます
make: *** [Makefile:1719: modules] エラー 2
途中省略したが、stage 2に移行したあとに作業ディレクトリに 8189fs.ko が見つからないと大量に言われて失敗した。
8189fs.koはないが、8189fs.oはできあがってる。
本来ならstage1の最後に.oを元に.koが作成されるぽい?

解決方法がわからずとりあえず断念したが、
linuxの方を、
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --depth=1
で持ってきてたが、これ開発版みたい。
それが問題な可能性も考えて、
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b linux-5.4.y --depth=1
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- sunxi_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- zImage
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi- dtbs
で作り直した。
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git の方が安定版で、ブランチlinux-5.4.yが最新版。

だが、結局同じエラーに。
作り直したkernelはまだ試してない。

Orange pi R1でArch Linux起動した

前の記事に書いたが、朝原因わかったので昨日断念したOrange pi R1でArch Linuxを再トライ。

同じSD使ったんで、u-boot本体はパーティションの外に入ってるんで、フォーマットしてrootfs展開してboot.scrだけ更新。
rootfsはext4にした。
自ビルドカーネルのmenuconfigみたらext4しかチェックされてなかったので、とりあえずext4が無難と判断。
最終的にはフラッシュメモリ向きのFSにしたいかな。

boot.cmd
setenv bootargs root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200
load mmc 0:1 ${kernel_addr_r} /boot/zImage
load mmc 0:1 ${fdt_addr_r} /boot/${fdtfile}
if load mmc 0:1 ${ramdisk_addr_r} /boot/initramfs.img;then
    bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r};
else
    bootz ${kernel_addr_r} - ${fdt_addr_r};
fi;
こんな感じにした。
/boot/initramfs.img がない場合はinitramfsを使わない。ある場合は使う。あってもなくても起動した。
注意点はカーネルパラメータに rw つけないとエラー多発でログイン不能になる。
あと、ArmbianはramdiskがuImageだったからと思うが、Archの場合は bootz にramdiskを渡すときにサイズも入れる必要があった。入れないとboot失敗する。

初期パスワードは、
root(root) と一般ユーザのalarm(alarm)

zImageを昨日作った自ビルドのものに差し替えても起動した。
自ビルドカーネルは5.5.0-rc5になってたけど、stableが5.4.11なのね。stableにしとくべきだった。