修改lk2nd

观察lk2nd现有的设备树,和一部分实现,发现lk2nd的设备树其实也并不是只用于原装bootloader识别,大佬们也实现了设备树中的按键定义在系统中的注册。
查看littlekernel中进入fastboot的逻辑,不难发现除了音量下键可以作为进入fastboot的事件,home和返回键也可以作为进入fastboot的条件之一。

在app/aboot/aboot.c中

 if (!boot_into_fastboot){if (keys_get_state(KEY_VOLUMEUP))boot_into_recovery = 1;if (!boot_into_recovery &&(keys_get_state(KEY_HOME) || keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))boot_into_fastboot = true;}

整个按键的初始化在lk2nd中加入了通过设备树初始化的部分,通过读取lk2nd,keys属性来完成。
在lk2nd/lk2nd-device.c中

static struct lk2nd_keymap* lk2nd_parse_keys(const void *fdt, int offset)
{int len;const uint32_t *val;struct lk2nd_keymap *map = NULL;#define KEY_SIZE (3 * sizeof(uint32_t))int i = 0;val = fdt_getprop(fdt, offset, "lk2nd,keys", &len);if (len > 0 && len % KEY_SIZE == 0) {len /= KEY_SIZE;/* last element indicates end of the array with key=0 */map = calloc(len + 1, sizeof(struct lk2nd_keymap));for (int i = 0; i < len; i++) {map[i].key    = fdt32_to_cpu(val[i*3]);map[i].gpio   = fdt32_to_cpu(val[i*3 + 1]) & 0xFFFF;map[i].type   = fdt32_to_cpu(val[i*3 + 1]) >> 16;map[i].pull   = fdt32_to_cpu(val[i*3 + 2]) & 0xFF;map[i].active = fdt32_to_cpu(val[i*3 + 2]) >> 8;}}dprintf(INFO, "Device keymap:\n");while (map && map[i].key) {dprintf(INFO, "key=0x%X, gpio=%x, type=%d, pull=%d, active=%d\n",map[i].key, map[i].gpio, map[i].type, map[i].pull, map[i].active);i++;}return map;
}

其实实现edl按键进入fastboot的思路就已经很清晰了,就是在设备树中加一条定义就行,把gpio37注册成为home按键。
最终的设备树代码如下所示

// SPDX-License-Identifier: GPL-2.0-only
// Copyright (C) 2021 HandsomeYingyan <handsomeyingyan@gmail.com>/dts-v1/;#include <skeleton.dtsi>
#include <lk2nd.h>/ {model = "Handsome Stick";compatible = "handsome,stick", "qcom,msm8916", "lk2nd,device";qcom,msm-id = <0xce 0x00 0xf8 0x00 0xf9 0x00 0xfa 0x00>;qcom,board-id = <0x08 0x100>;lk2nd,keys = <KEY_HOME 37 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
};

刷入boot分区测试,完美触发!在测试的时候发现fastboot烧写boot.img采用的不是先擦除再烧写,而是覆盖的方式。如果lk2nd有问题,安卓内核就会一直重启,进不到原来的bootloader的fastboot模式。
解决的方法也很简单,使用edl工具在edl模式下擦除boot分区就行。

$ edl e boot

第一次执行可能会卡住,直接中断马上再执行相同指令,就完成了boot分区的擦除。
但是,一个好用的bootloader还需要能够知道设备的启动状态,由于安卓的默认灯也是红色。我定义bootloader一开始亮起的灯为蓝灯,最终对代码的修改如下。
加入对wifi三个led灯和edl按键 gpio号的宏定义
target/msm8916/init.c

#define TLMM_EDL_BTN_GPIO    37
#define TLMM_USR_BLUE_LED_GPIO  20
#define TLMM_USR_GREEN_LED_GPIO  21
#define TLMM_USR_RED_LED_GPIO  22 /* UNUSED */

在target_init()中加入gpio初始化语句

 gpio_tlmm_config(TLMM_USR_BLUE_LED_GPIO, 0, GPIO_OUTPUT,GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);

这样lk2nd基本上就起来了,能够启动原来的安卓内核和按edl按键进入fastboot模式,让免拆刷机成为可能,唯一不好的地方就是按edl键的时间必须要准,太早就直接进edl模式了,太慢就直接进内核了。

lk1st yes!

lk2nd 的存在使得在整个引导过程中多了一层来传递主线内核需要的参数,拖慢了启动的速度。所以在最终的版本中lk2nd只用于提取原来的modem和wifi的校准数据,而设备引导由这套代码生成的lk1st完成。
lk作为aboot,许多设备树相关的东西就用不了了。也就是说前面那个设备树定义的按键在lk1st下是没有用的,必须通过自己注册按键的方式来实现。
由于这个板子上是有fb(fastboot)触点的,不想破坏原来的fastboot键功能,这里仍然将按键注册为home键。为了方便调试我还加了一个行为,进入fastboot后绿灯亮起。

target/msm8916/init.c

/* HACK : treat edl btn as home btn */
int target_home()
{static uint8_t first_time = 0;uint8_t status = 0;if (!first_time) {gpio_tlmm_config(TLMM_EDL_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA, GPIO_ENABLE);/* Wait for the gpio config to take effect - debounce time */udelay(10000);first_time = 1;}/* Get status of GPIO */status = gpio_status(TLMM_VOL_UP_BTN_GPIO);/* light up green led when edl btn is pressed*/if(status == 1) {gpio_tlmm_config(TLMM_USR_GREEN_LED_GPIO, 0, GPIO_OUTPUT,GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);}/* Active high signal. */return status;
}

向系统注册按键

 #if WITH_LK2NDuint32_t target_volume_down_old()#else
@@ -217,6 +255,10 @@ static void target_keystatus()if(target_volume_up())keys_post_event(KEY_VOLUMEUP, 1);
+
+  if(target_home())
+      keys_post_event(KEY_HOME, 1);
+}#endif

代码就修改完成了,接下来就是编译之后烧写到设备里,但是不能直接将产物进行烧写,还需对其进行签名。这里我使用的是qtestsign工具,它的简介以及十分详细,这里就不再赘述了。

烧写之后,lk完美运行,接下来就是主线linux的移植了!

fastboot模式

移植主线Linux

为了验证主线linux内核是否能够在这个设备上启动先使用我之前在红米2上弄的一个用于kexec的dragonroot 来试试。
果不其然,运行不了。在预料之外的是内核压根跳转不了,littlekernel报了一个关于scm的错然后直接重启。换成原厂的bootloader错误依旧。

稍微查了一下发现是trustzone固件的问题,貌似这个板子自带的trustzone固件用不了64位的内核,这也就是为什么lk2nd用的了而linux内核却不行的原因。lk2nd默认是以arm32的形式编译的。
尝试使用dragonboard的trustzone固件,但是分区太小刷不进去。
反正也到这里了,只能重新分区了。备份modem和wifi数据后刷入dragonboard的分区表,再把dragonboard的那一套固件刷进去,再次尝试刷入dragonroot,主线内核轻松跑起来了!

接下来的工作相对来说就比较简单了,东拼西凑弄了个可以使用的设备树,大体上内核部分也就完美了。重新组装下postmarketos的boot.img,直接使用红米2的rootfs,大体上就完美了。

PostmarketOS 使用体验

运行了一天,稳定性还是不错的,发热量也不是很大(空载状态下运行手摸接近室温)
内存很充裕,但是emmc太小了(好像只有2个多G可用)

得益于postmarketos基于的alpine linux轻量级的特点,资源占用也不是很高。

当然,wifi、蓝牙、modem也是工作的。但是modem没有卡试,也没激活商家提供的卡,只知道可以认出运营商,即使有问题,问题也不是很大。gps、gpu和硬件解码器能识别出,应该问题也不大。



在刷入hyp虚拟化firmware之后,kvm也可以使用了。


硬件上的所有功能应该是压榨干净了,但是还没完全干净。

WHY?

作为一个高级路由器,一个host模式usb不应该是基本要求吗?
根据常识不难设计出转换的板子,两个usb母口电源线并联,用一个mircousb供电,数据线分别相连就行。


但是这个usb默认工作在slave模式下,厂家也没设计io口作为usb
的id引脚,只能通过手动的方式切换usb模式。
查找一番后发现可以通过sysfs切换,这就很nice了。

   $ sudo -s$ echo host > /sys/kernel/debug/usb/ci_hdrc.0/role

芜湖!成功认出了我插入的USB鼠标。

u盘也是没有问题的。

这下离线下载、打印服务器之类的玩法实现也比较轻松了。至此,一个非常廉价、性能还可以的arm64单板电脑就诞生了。

这个板子唯一的遗憾就是emmc太小了,要是有sd卡槽,基本上就无敌了。
缺一个好用的系统,就完美了。

Openwrt ?

这个比较复杂。其一是没有任何openwrt设备的soc是自带modem的,usb modem很久以前就支持了,但是不确定modem能不能驱动。其二是msm8916没有被官方支持,而且内核是安卓格式的,必须对生成镜像的过程进行修改,加一些构建工具。还要backport msm8916-mainline主线内核里的一些修改到稳定版内核。

另外openwrt还没有管理usb slave(gadget)模式的工具。我的目标不仅仅是让usb实现网卡的功能,还要实现串口、adb、磁盘挂载等一些其他的功能。这可能要自己造轮子了。

其实研究红米2的时候就在我的openwrt fork – HandsomeMod 里我已经做了一些尝试了,能够进入shell,但是硬件还没有完全跑起来。

但是这是迟早的事情,谁叫你配置这么高又卖的这么便宜呢,哈哈~~

源代码及帮助

目前lk linux 和一部分二进制的包已经开源到github上。
WIKI里也记录了许许多多的玩法。
感兴趣的老哥自取
OpenStick主页
OpenStick WIKI

我的4g网卡运行着GNU/Linux -- 某4g无线网卡的逆向工程与主线Linux移植 (二)相关推荐

  1. 我的4g网卡运行着GNU/Linux -- 某4g无线网卡的逆向工程与主线Linux移植 (一)

    最近,某鱼和某宝上开始出现一些基于高通处理器的4g无线网卡,有一些网卡采用的方案也就是我之前折腾过的红米2的主控msm8916.如果能够在这些无线网卡上跑起主线linux,这应该是世界上最便宜的arm ...

  2. 记一个老年机的逆向工程与主线linux移植 (二)—— 主线内核和postmarketOS

    现在,这台手机已经有了一个可以调试的Bootloader.接下来可以去搜索以下其他大佬有没有什么现有的成果,免得做许多无用功. Linux Mailing List就是一个不错的地方,这里聚集着很多提 ...

  3. linux内核裁剪视频,Kernel内核的裁剪及移植(二)

    远程视频监控程序设计摄像头采集驱动移植 gspcav1-20071224 gspcav1-20071224下载地址: 由于linux-2.6.24.4/drivers/usb目录下没有media目录, ...

  4. 华为云IoT智慧物流案例04 | 4G网卡拨号(广和通L610-CAT.1模组)与北斗定位模组(中科微电子)数据解析

    华为云IoT智慧物流案例04 | 4G网卡拨号(广和通L610-CAT.1模组)与北斗定位模组(中科微电子)数据解析 回顾 第一章 广和通L610-CAT.1模组调测和拨号脚本编写并验证网络 第二章 ...

  5. 【逗老师的无线电】MMDVM添加4G网卡之后变身4G路由器

    此前,逗老师介绍了如何给MMDVM热点添加一个4G网卡: [逗老师的无线电]MMDVM盒子pi-star系统添加4G网卡及修改路由优先级 本文,咱们接着玩个东西.让这个盒子不光可以连接4G网络进行HA ...

  6. linux无线usb网卡,Linux下USB无线网卡WL-167G驱动安装过程

    最近经过前期调研选定网卡,又折腾一两天,终于搞定了Linux下的无线网卡,对遇到的问题进行了分析,并整理了下详细过程,现与大家分享,还有更具体的开发文档,有需要的可以联系下一步工作要将其移植到ARM平 ...

  7. OpenWrt 4G网卡拨号配置

    基础知识 MiniPCI-e, 接口其实就是USB接口, 采用的USB协议. USB协议中有product id, vendor id. 4G网卡的拨号方式有三种: PPP (PPP over EV- ...

  8. NanoPi NEO3上手日记第三天——安装3G/4G网卡(OpenWrt系统均适用)

    NanoPi NEO3上手日记第三天 一.识别上网设备 二.接口配置 三.性能测试(不感兴趣可以不看) 1.LTE性能 2.WiFi性能 四.一些必要说的事 --上接第一篇 配置WiFi 注: 如果读 ...

  9. 4G网卡驱动调试-ec20

    4G网卡驱动调试分三步走: 一.基本概念 USB 部分的功能接口 APN 二.驱动移植 USB Driver GobiNet Driver 或者 QMI WWAN PPP 拨号配置 三.RIL 移植 ...

最新文章

  1. 【深度学习理论】(2) 卷积神经网络
  2. Windows 技术篇 - 远程桌面连接不保存密码、每次都要输入密码问题解决
  3. 1.11 Lambda表达式遍历Iterator迭代器
  4. 七夕福利 | 拒绝狗粮,给你全部的AI(爱)
  5. Windows卸载软件出现蓝屏SYSTEM SERVICE EXCEPTION(VrvProtect_x64_2.sys)
  6. PYTHON得到pdf页数、遍历当前文件夹
  7. 如何给网页标题添加icon小图标
  8. 开放计算架构:蚂蚁金服是如何用一套架构容纳所有计算的?
  9. matlab 图像显著性检测ft_全局对比度的图像显著性检测算法
  10. 怎么恢复linux定时器任务,定时操作 crontab at 以及恢复定时操作
  11. 初中三年级计算机课程教案,三年级信息技术教案下
  12. 统计用产品分类目录8位代码类别_沪市主板605代码“1号选手”来了
  13. win10安装vc2015失败,尝试解决方案,目前有效
  14. CNN(卷积神经网络)的深度
  15. OneNET麒麟座应用开发之六:与气体质量流量控制器通讯
  16. python中复制上一行快捷键_Pycharm最常用的快捷键及使用技巧
  17. 【SQL注入-文件读写】文件的读取+写入:函数、使用方法
  18. oa 服务器 微信,微信OA:一种新的办公方式
  19. java游戏boss是冰龙_炉石传说冒险模式冰龙区Boss技能及过关卡牌奖励
  20. python高级--数据分析(Pandas库)

热门文章

  1. 系统自己弹出诸如 kernel:NMI watchdog: BUG: soft lockup - CPU#2 stuck for 26s [mysqld:2875]
  2. K8s安装遇见问题笔记
  3. 流水线生产,精益生产,TPS和TOC的缓冲管理
  4. XMind与MindManager哪个好(网易云课堂老师:Array老师讲解稿)
  5. 邮件群发平台哪个好,什么是群发单显怎么操作?
  6. 乐驼金融:AI助力金融智能化转型 未来五年中国或迎行业爆发期
  7. [VIM]VIM/GVIM中代码的折叠和打开
  8. 一些用于聚类和分类问题的数据集
  9. 树莓派linux界面命令行,Linux/Raspberry Pi下使用基于命令行的网页浏览器
  10. 计算机课代表自荐信,课代表自荐信