修改Linux内核添加Air72X 4G模块支持
这话从何说起呢,还是疫情之前吧,那会合宙刚刚推出Air724模块,脑子一热,团购了一个,以为没团上,然后小号又团了一次,然后就有了两个了。然后和囤积的大多数东西一样没有然后了 。类似这款,但是显然比他早。
最近有个需求用上了,所以寻思用一下,结果发现竟然不行,原因么应该是因为Linux内核太老了,我这里有个树莓派4代,直接插上USB也是不行的,但是更新了系统以后就可以了。那么开始吧。参考资料主要是两个,第一个来自合宙问答,是一篇基于树莓派更改内核的帖子,另一个来自“【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.pdf”文件中“第七十一章 第二节”;具体步骤如下:
1、 更改内核文件
这里主要涉及到一个文件“drivers/usb/serial/option.c”,添加usb设备的PID和VID,我用的是Air724UG模块,其PID和VID是{0x1782, 0x4e00},另外还添加了一个,可能是另外一种类型模块的。
//1. 更改option_ids数组,大约在630行左右,可以搜一下static const struct usb_device_id option_ids[] = { //在数组中添加以下USB设备的PID和VID //Air72X 4G模块 {USB_DEVICE(0x1286, 0x4e3d)}, {USB_DEVICE(0x1782, 0x4e00)}, //在下边是原来就有的设备的PID和VID,不需要修改 {USB_DEVICE(0x19d2, 0x0117)}, /* ME3630*/ {USB_DEVICE(0x19d2, 0x0199)}, {USB_DEVICE(0x19d2, 0x1476)}, 。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。 //2. 更改option_probe函数,大约在1865行左右 static int option_probe(struct usb_serial *serial, const struct usb_device_id *id){ struct usb_interface_descriptor *iface_desc = &serial->interface->cur_altsetting->desc; //这一行本来是要添加的,但是正点原子已经给添加了,所以,就不用了 struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; const struct option_blacklist_info *blacklist; /* Never bind to the CD-Rom emulation interface*/ if (iface_desc->bInterfaceClass == 0x08) return -ENODEV; //。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 //这部分是中间一堆代码,我没有复制过来 //。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 if (dev_desc->idVendor == cpu_to_le16(0x05c6) && dev_desc->idProduct == cpu_to_le16(0x9215) && iface_desc->bInterfaceNumber >= 4) return -ENODEV; if (dev_desc->idVendor == cpu_to_le16(0x2c7c) && iface_desc->bInterfaceNumber >= 4) return -ENODEV; //在接紧最下边,添加下述两个if条件 //Air72X if (dev_desc->idVendor == cpu_to_le16(0x1286) && dev_desc->idProduct == cpu_to_le16(0x4e3d) && iface_desc->bInterfaceNumber <= 4) return -ENODEV; if (dev_desc->idVendor == cpu_to_le16(0x1782) && dev_desc->idProduct == cpu_to_le16(0x4e00) && iface_desc->bInterfaceNumber <= 4) return -ENODEV; /* Store the blacklist info so we can use it during attach. */ usb_set_serial_data(serial, (void *)blacklist); return 0;}
2、配置和编译内核
内核配置是比较麻烦的,但是好在正点原子已经将需要配置的都配置好了,所以如果懒的话,接下来就可以直接编译了。如果是想学习的话可以参考正点原子的教程手动进行配置,这里需要注意的是,他的教程中配置过程是他配置成功后的截图,顺序是不对的,需要先启用usb support才能有Network device support这个选项出现,所以配置时需要注意,我在这里找Network device support找了好久都没找到。编译是比较简单的
# 进入内核源码,执行下述命令即可./mx6ull_alientek_emmc.sh# 该脚本中包含了清空、配置、编译等指令#如果出现 fatal error curses.h no such file or directory错误,需要执行下述命令安装相关包sudo apt-get install libncurses5-dev
3、 加载内核到内存并运行
这里参考“【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.pdf”文件中“第三十七章 第三节 第三目(37.3.3)”。稍微不同的是我使用的MobaXterm是有tftp功能的,所以不用自己搭建tftp服务了,这个另开一篇再写。
# 内核加载并运行后,进入系统后,可以执行ip addr# 我的输出为root@ATK-IMX6U:~# ip addr1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default 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 inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: can0: mtu 16 qdisc noop state DOWN group default qlen 10 link/can3: eth0: mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether be:1a:9e:2c:ce:72 brd ff:ff:ff:ff:ff:ff4: eth1: mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether 9e:ae:8c:63:59:99 brd ff:ff:ff:ff:ff:ff5: sit0@NONE: mtu 1480 qdisc noop state DOWN group default link/sit 0.0.0.0 brd 0.0.0.0# 这行注释是我加的# eth2即4G模块所使用的网卡信息,可以看到有IPv-4和IPv-6两个地址# 使用ping命令测试是可以联网的,就搞定了6: eth2: mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000 link/ether ac:4b:b3:b9:eb:e5 brd ff:ff:ff:ff:ff:ff inet 192.168.5.8/24 brd 192.168.5.255 scope global eth2 valid_lft forever preferred_lft forever inet6 ::ae4b:b3ff:feb9:ebe5/64 scope global mngtmpaddr dynamic valid_lft forever preferred_lft forever inet6 fe80::ae4b:b3ff:feb9:ebe5/64 scope link valid_lft forever preferred_lft forever
下篇写烧录。