博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
kexec on openwrt - linux boots linux, kernel boots kernel on openwrt
阅读量:5052 次
发布时间:2019-06-12

本文共 4122 字,大约阅读时间需要 13 分钟。

kexec on openwrt - linux boots linux, kernel boots kernel on openwrt

背景

对于嵌入式设备比如路由器,每次版本升级,总是需要image的升级,所以需要烧写Flash。这种方式速度慢,并且还可能损坏Flash里的引导image,造成设备无法启动,只能返厂维修。

如果能够做一个小系统,出厂时烧录到Flash里,然后它用来查询和下载新版本image到内存,从内存启动这个新的image,那么就不用再烧录Flash,并且可以把image升级放到云端控制。

技术分析

可以通过添加功能到bootloader支持这种需求,但是修改原路由器bootloader开发难度比较大,并且将原bootloader替换掉也不容易恢复到原厂image。

Linux里kexec-tools特性,支持linux启动linux,或kernel引导kernel,刚好可以被用到这里。我们可以实现一个小的开启kexec特性的linux系统。然后通过它来下载和引导新的initramfs的全特性的linux系统。

kexec的原理是内核启动时会保留一段内存用来加载和解析新的linux系统,内核提供了kexec的系统调用,来加载制定段到物理内存。

支持kexec特性的openwrt image

  1. 打开内核的kexec
$ make menuconfigUtilities --> kexec-tools
  1. 加入kexec-tools用户空间工具
$ make menuconfigUtilities --> kexec-tools
  1. 将sysupgrade.bin烧录到Flash里
$ sysupgrade -n openwrt-*-sysupgrade.bin

kexec用法

$ kexec -d --command-line="$(cat /proc/cmdlin)" -l vmlinux-initramfs.elf.gz$ kexec -d -e

Note: kexec-tools在MIPS下–type只支持elf-mips, 并且elf必须经过gzip压缩

支持initramfs的openwrt image

  1. 修改openwrt配置文件以产生ramdisk
$ make menuconfigTarget Images --> ramdisk
  1. LEDE 17.01上需要修改KERNEL_SIZE,支持生成更大完整的initramfs, AA 12.09是不需要的
$ target/linux/mips/ramips/image/mt7621.mk
  1. LEDE 17.01上image位置:
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.elfkernel.bin.dtb
  1. LEDE170.01上需要补丁bin.dtb,AA12.09不需要
$ ./staging_dir/host/bin/patch-dtb vmlinux-initramfs.elf ubnt-erx-kernel.bin.dtb
  1. 为了能够访问到Flash里的calibration data,需要修改preinit过程,加载caldata和挂载rootfs_data
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 Communicationsinitramfs_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}
  1. 压缩elf文件
$ gzip -c vmlinux-initramfs.elf > initramfs.elf.gz

参考文献

遇到的问题

  1. No valid device tree found, kernel panic on Failed to find mtk,mt7621-sync node
    原因: 系统device Tree没有加载正确
    openwrt在mips上dtb的处理如下:
    在vmlinux的elf里,预留了0x400, 16K的区域用来保存dtb信息,然后使用全局变量__image_dtb来索引这个区域,从而读取dtb新信息。并且在这个区域预存了特定字符"OWRTDTB:",生成image时使用。
    在生成vmlinux文件后,查找"OWRTDTB:"关键字,将dtb的bin,写入到这个区域。
    解决方案:在生成vmlinux.elf后,将dtb.bin补丁到elf文件里。
...[    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...
  1. okos is unstable and gets panic sometimes after hot boot

    原因:一些外围芯片比如usb controller, wmac正在处理中断过程中被hot boot, 造成下次启动中断大量上报,内核stuck。
    解决方案:尽量保证sysloader的简洁,裁剪掉不需要的外设驱动,只保留Flash的访问。
    修改sysloader的.config文件,剔除不需要的模块选择。

  2. Overlayfs not enabled in initramfs

    原因:overlayfs是通过一个底层只读文件系统squashfs加上一个上层可写文件系统JFFS2/UBI构建出来的。
    在initramfs下不能使用squashfs下的不再更新的rootfs.
    解决方案:修改preinit过程,挂载rootfs_data分区

  3. caldata加载失败

    原因: preinit过程中如果发现是initramfs就会跳过加载caldata和flash分区
    解决方案:为了能够访问到Flash里的calibration data,和挂载rootfs_data,需要修改preinit过程,加载caldata和挂载rootfs_data

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 Communicationsinitramfs_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}

– 2017-12-3

转载于:https://www.cnblogs.com/nicephil/p/7965767.html

你可能感兴趣的文章
使用matlab遇到的问题
查看>>
Java中的HashMap遍历和C#的字典遍历
查看>>
21_listview展示数据内容回顾
查看>>
在手机网络情况下,Android的微信页面不能播放背景音乐
查看>>
SpringBoot:第二篇 集成日志lombok
查看>>
【Python】新建自定义个数的自定义长度名字
查看>>
区块链与比特币小结
查看>>
也说python的类--基于python3.5
查看>>
Oracle 存储过程
查看>>
HashMap原理阅读
查看>>
冲刺7
查看>>
html5 drag 文件拖拽浅淡
查看>>
window安装Scrapy———解决报错问题
查看>>
关于VS2010编译警告LNK4221
查看>>
简单的一个程序,猜字游戏
查看>>
软件架构阅读笔记07
查看>>
关于使用pageoffice插件实现导出数据到excel文档中
查看>>
OnPreInit,OnInit ,OnInitComplete ,OnPreLoad ,Page_Load等执行顺序
查看>>
Python集合set()操作详解
查看>>
程序员技能图谱
查看>>