Thinking: Config Linux Network

起因:今天与一位同学一起尝试去配置Linux静态IP,这中间有不少坎坷,想简单把思考的过程写下来, 复盘一下是不是应该有可以更快的定位到问题并解决的方案。

提出问题

Cl同学想要达到启动Linux后自动设置某个静态Ip的效果, 在我的理解里这并不是一件很复杂的事。

他给我的想法是在Kernel Command Line参数中指定Ip, 我之前没有看到过这种方式配网,但是网上搜了一下确实有这样的例子。 所以他目前已经完成的是:

Linux是通过Uboot起的,要增加Linux Command Line, 可能是在Uboot的bootargs中添加。 但是他在修改完bootargs并重启的时候,发现变量没有成功赋值, 即使已经成功saveenv。所以就邀请我和他一起讨论。

动手实践

了解到问题之后,我先说出了我的想法:

  • 配置静态Ip这个事其实我第一时间想到的是以前修改/etc/network/interfaces文件的方式
  • 但是我愿意陪他先看下为什么命令行参数没有配置上去

这是两条路,因为他的系统里没有真正的文件系统,而是initrd, 所以我提出的方案需要去解包inird的压缩文件,还是尽量先去研究为什么命令行参数没有配置上去。

为什么CMDLINE没有配置上去呢?

首先它说bootargs没有保存成功,这个我也不知道为啥, 可以先不管,即便在每次启动之前在Uboot里设置了Bootargs, 他说在启动之后Kernel的打印也没有输出配置的项目。

Uboot中Bootargs设置的值是和Kernel Command Line配套吗? 这个我反正是不太确定。

好,那能不能通过别的方式来设置CmdLine呢? 我们搜索找到了两种方式:

  1. Dts中
  2. Menuconfig中修改

没有尝试Menuconfig是因为他说“目前Menuconfig配置的CmdLine为空, 但是实际Kernel启动后又是有值输出的,那么说明肯定是其他的地方有添加。” 对于这句话我也表示认同,Menuconfig里给的说明是:“默认配置”, 所以即便添加了也无法保证会不会被其他的给冲刷掉。所以,一个根本问题就是: CmdLine配置的顺序,或者说优先级是什么?

先去Dts里改改试试吧,找到了一个chosen结点有关于bootargs的配置, 不管怎么样改了一下,发现并没有生效,和最终Kernel输出的对不上。

所以,看起来修改CmdLine这条路要失败了,只能去修改initrd试试。

修改Initrd达到目的

initrd是打包好的,用的是cpio+lz4的方式。要修改首先要把他解开, 解开到还好说,网上能搜得到命令。 但是重新压缩回去问题很多,前期我就想到了我在华为实习时期遇到的类似的问题, 压缩的算法不对、打包的版本差异都会导致Kernel无法解析重新打包的initrd而panic。

实际也遇到了这个问题,但是这有个小插曲:即便是换回原来的initrd也还是panic。 最终破案是因为需要make clean之后重新make,猜测可能是用了什么中间文件。 不得不感慨Linux Kernel的构建还是相当复杂的。

问题来了:修改/etc/network/interfaces并没有改变静态Ip, 这就使我产生了疑惑,想着可以先在系统启动之后修改试试嘛, 执行ip down和ipup发现确实没有成功修改,这不禁让我想问为什么?

此时,我们突然想到一个问题,既然shell命令能成功修改Ip, 那么就在启动时增加一个脚本去执行设置Ip的行动,不就行了吗?

确实是可以的,所以暂时先不管为什么interfaces不生效。 那就修改有关于/etc/init.d和/etc/inittab相关的知识了, 这一部分我就没参与了,网上的资料的非常全,最终是成功达到目的。

感慨

虽然成功达到了目的,但是消耗了4个小时左右的时间,我觉得这件事并不应该这么复杂。 主要原因是Linux可以配置网络的方式太多了,以至于像我们这种不是非常熟悉的人一时间不知道如何下手。

另外,其实这中间还有一些问题没有去解决,可能以后有时间再搞一个完整的qemu-liunx环境去测试一下吧💭。


创建于: 2023-12-08T17:19:44, Lastmod: 2023-12-16T19:20:35