對於嵌入式設備好比路由器,每次版本升級,老是須要image的升級,因此須要燒寫Flash。這種方式速度慢,而且還可能損壞Flash裏的引導image,形成設備沒法啓動,只能返廠維修。
若是可以作一個小系統,出廠時燒錄到Flash裏,而後它用來查詢和下載新版本image到內存,從內存啓動這個新的image,那麼就不用再燒錄Flash,而且能夠把image升級放到雲端控制。html
能夠經過添加功能到bootloader支持這種需求,可是修改原路由器bootloader開發難度比較大,而且將原bootloader替換掉也不容易恢復到原廠image。node
Linux裏kexec-tools特性,支持linux啓動linux,或kernel引導kernel,恰好能夠被用到這裏。咱們能夠實現一個小的開啓kexec特性的linux系統。而後經過它來下載和引導新的initramfs的全特性的linux系統。linux
kexec的原理是內核啓動時會保留一段內存用來加載和解析新的linux系統,內核提供了kexec的系統調用,來加載制定段到物理內存。web
$ make menuconfig Utilities --> kexec-tools
$ make menuconfig Utilities --> kexec-tools
$ sysupgrade -n openwrt-*-sysupgrade.bin
$ kexec -d --command-line="$(cat /proc/cmdlin)" -l vmlinux-initramfs.elf.gz
$ kexec -d -e
Note: kexec-tools在MIPS下–type只支持elf-mips, 而且elf必須通過gzip壓縮bash
$ make menuconfig Target Images --> ramdisk
$ target/linux/mips/ramips/image/mt7621.mk
llwang@compiler~/repos/master_for_lede-17.01/osdk_repos $ ls build_dir/target-mipsel_24kc_musl-1.1.16/linux-ramips_mt7621/ vmlinux-initramfs.elf kernel.bin.dtb
$ ./staging_dir/host/bin/patch-dtb vmlinux-initramfs.elf ubnt-erx-kernel.bin.dtb
llwang@compiler~/repos/master_for_AA-12.09/osdk_repos/package_repos/ok_base-files/lib/preinit $ cat 70_initramfs_test #!/bin/sh # Copyright (C) 2006 OpenWrt.org # Copyright (C) 2010 Vertical Communications initramfs_test() { echo "---> initramfs_test $INITRAMFS" if [ -n "$INITRAMFS" ]; then boot_run_hook initramfs preinit_ip_deconfig # OK_PATCH do_load_ath10k_board_bin mount "$(find_mtd_part rootfs_data)" /overlay -t jffs2 mtd -qq unlock rootfs_data # end of OK_PATCH break fi }
$ gzip -c vmlinux-initramfs.elf > initramfs.elf.gz
... [ 0.000000] No valid device tree found, continuing without //initialize device tree is incorrect [ 0.000000] PERCPU: Embedded 10 pages/cpu @81203000 s8608 r8192 d24160 u40960 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024 [ 0.000000] Kernel command line: kexec console=ttyS0,57600 rootfstype=squashfs,jffs2 rootfstype=squashfs,jffs2 //command line should be changed during build ... [ 0.000000] Kernel panic - not syncing: Failed to find mtk,mt7621-sysc node [ 0.000000] Rebooting in 1 seconds.. [ 0.000000] Reboot failed -- System halted ...
okos is unstable and gets panic sometimes after hot boot
緣由:一些外圍芯片好比usb controller, wmac正在處理中斷過程當中被hot boot, 形成下次啓動中斷大量上報,內核stuck。
解決方案:儘可能保證sysloader的簡潔,裁剪掉不須要的外設驅動,只保留Flash的訪問。
修改sysloader的.config文件,剔除不須要的模塊選擇。工具
Overlayfs not enabled in initramfs
緣由:overlayfs是經過一個底層只讀文件系統squashfs加上一個上層可寫文件系統JFFS2/UBI構建出來的。
在initramfs下不能使用squashfs下的再也不更新的rootfs.
解決方案:修改preinit過程,掛載rootfs_data分區ui
caldata加載失敗
緣由: preinit過程當中若是發現是initramfs就會跳過加載caldata和flash分區
解決方案:爲了可以訪問到Flash裏的calibration data,和掛載rootfs_data,須要修改preinit過程,加載caldata和掛載rootfs_dataspa
llwang@compiler~/repos/master_for_AA-12.09/osdk_repos/package_repos/ok_base-files/lib/preinit $ cat 70_initramfs_test #!/bin/sh # Copyright (C) 2006 OpenWrt.org # Copyright (C) 2010 Vertical Communications initramfs_test() { echo "---> initramfs_test $INITRAMFS" if [ -n "$INITRAMFS" ]; then boot_run_hook initramfs preinit_ip_deconfig # OK_PATCH do_load_ath10k_board_bin mount "$(find_mtd_part rootfs_data)" /overlay -t jffs2 mtd -qq unlock rootfs_data # end of OK_PATCH break fi }
nicephil@gmail.com – 2017-12-3.net