嵌入式Linux开发者Unix环境搭建避坑指南
|
去年十一月,凌晨三点二十,我正用牙签掏着树莓派4B散热片底下那层发黑的硅脂,听见机柜那边“啪”一声脆响——不是断电,是继电器在喘气。值班室泡面桶堆在UPS底下,汤沿儿已经干成一圈盐霜。 我原以为只是串口线虚焊,结果敲了三遍`dmesg | tail`,全是`usb 1-1.2: device descriptor read/64, error -71`。第七次重插USB转串口模块时,老张从隔壁工位探头:“你那板子又在装失联孤儿?”他手里攥着刚撕下的监控屏贴纸,上面写着“告警已关(临时)”,胶布翘边,沾着点茶叶渣。 时间倒回四天前。我们给新来的嵌入式组搭交叉编译环境,说白了就是把`gcc-arm-linux-gnueabihf`和`buildroot-2023.02`往Ubuntu 22.04上砸。没人提`/tmp`分区大小——谁想到Buildroot的`output/images/`会往`/tmp`里扔三个G的中间镜像?更没人拦住小王,他非要把所有SDK解压到`/home/dev/.local/share/yocto/`,而那个目录底下挂的是NAS,NFS挂载参数还写了`soft,intr,retry=3`。软挂载啊兄弟,三次重试就直接跪,连errno都懒得报。
文章配图,仅供参考 昨天下午两点半,CI流水线突然卡在`make menuconfig`。我扒日志发现`/dev/shm`满了。不是`/tmp`,是`/dev/shm`。它默认只有64MB,而Buildroot里有个鬼脚本会往这儿塞`config.cache`再fork五十个进程读——这事儿我在2018年调TI AM5728时见过,但早忘了。我就去`echo 2G > /proc/sys/kernel/shmmax`,按回车键手抖,多敲了个空格。`sh: 2G: command not found`。屏幕没反应。我盯着光标闪了四十来分钟,才想起要补个`sysctl -w`。 老板凌晨一点十七分在运维群里发了个链接,是某云厂商的《嵌入式开发环境最佳实践白皮书》PDF。标题加粗,第7页画了个三层架构图:Host → Container → Target。底下小字写着“建议使用Docker Desktop for Linux”。我没敢回。去年这时候,我们就信了这句话,用Docker跑QEMU模拟arm64,结果内核`CONFIG_KVM_ARM_VGIC_V3=y`没开,虚拟中断永远不触发,`ping`命令能发包,但从不回。整整两天,大家对着`ping: sendmsg: Operation not permitted`发呆。后来发现,是Docker默认`--cap-drop=ALL`,连`CAP_NET_RAW`都掐了。这不是权限问题,是阉割。 窗外开始下雨,雨刷器声音断续,像磁盘坏道读取。我忽然想起上一次搬家——搬完当天硬盘箱忘拆防震泡沫,插上电,风扇转了半小时才听见第一声异响。这次也一样,所有备份都配了rsync --delete,可没人设`--exclude='.swp'`。于是`vim`临时文件被同步过去,覆盖掉`defconfig`;`git add .`误提交了`.build/`里的二进制,commit哈希值每天变;最绝的是,我们用GitLab CI自动生成固件镜像,但runner配置了`cache: {untracked: true}`——每次清理缓存时,把`output/images/rootfs.cgz`当垃圾清了。三天没发现。直到设备上线后`/etc/passwd`权限变成600,ssh登不进去,才查出rootfs打包阶段的`fakeroot`环境变量根本没生效。 小刘凌晨四点打来电话,嗓子哑着:“主控板启动后WIFI模块初始化失败,但烧录旧固件就正常。”我没接话。我知道他想问是不是驱动问题。可就在两小时前,我看到`dmesg`里有句`qcom_wcnss_ftp: module verification failed: signature and/or required key not available`。不是签名错了,是我们编译内核时,把`CONFIG_MODULE_SIG_FORCE=y`关了,但`scripts/sign-file`路径写死在Makefile里,指向的却是另一台服务器上的OpenSSL 1.1.1。证书没过期,是签名工具链根本不在PATH里。我把它硬symlink过去,重启build机器。可`make modules_install`还是失败,报错`cp: cannot create regular file '/lib/modules/.../modules.order': Permission denied`——因为`/lib/modules`挂载的是只读NFS。这事儿我上周就该发现,可那天孩子发烧,视频问诊窗口弹出来,我顺手点了全屏,再切回来时终端已经滚走了两千行日志。 老张刚才又来了,拎着半瓶冰啤酒,瓶身全是水珠。“你试试拔掉JTAG调试器再上电?”他拧开盖子灌一口,泡沫溢到虎口。“上次我们测IMX6UL,就是调试器供电干扰了DDR初始化时序。”他说话时,我瞥见他工牌背面贴了张便签:女儿小学运动会,周五上午。而我的手机锁屏壁纸,还是上个月拍的机房顶棚漏水照片,水渍边缘泛黄。 DNS?对,我们真踩过。内网用dnsmasq做本地解析,但`/etc/resolv.conf`被Buildroot的`genimage.sh`覆盖了三次。第四次我们改用`chattr +i`锁死,结果CI构建失败,报`resolvconf: command not found`——因为`resolvconf`包没进rootfs。没人记得Buildroot菜单里`System configuration → Install resolvconf`那项是灰色的,要先开`BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y`。这个细节我到现在也没想明白,为什么BusyBox的配置开关能卡住一个网络工具包的依赖链。 我原以为只是环境变量乱套,结果翻`.bashrc`发现`export PATH="$HOME/.local/bin:$PATH"`被注释掉了,旁边一行小字:“为防止conda污染交叉编译路径”。可我们根本没装conda。是谁加的?没人认。监控屏右下角贴着张便签,字迹潦草:“zabbix agent 内存监控失效(2023-11-03起)”,下面用红笔圈了“失效”俩字,又划掉,改成“失明”。我伸手抠了抠,胶布底下露出半截铅笔写的“@小王”。 明天先把告警阈值调了。`/dev/shm`不能只看size,得加inode监控;`/tmp`得独立挂载,最小2G;NFS挂载必须加`hard,nointr`,哪怕它卡住整个shell。至于那份白皮书……我已经把它打印出来,钉在机柜侧面了。等下个月新来实习生看见,我就指着第7页说:你看这三层,第一层是你手抖按错的Ctrl+C,第二层是你没看见的Makefile缩进,第三层是烧录器芯片上那颗松动的钽电容——它去年就裂了,但灯还亮着,谁都没管。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


ASP脚本避坑指南:90%开发者忽略的语法雷区
站长必备:SQL Server运维12大故障避坑指南