对于嵌入式设备好比路由器,每次版本升级,老是须要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