交叉编译Ubuntu Debian内核 for raspiberry 4B && 另一种开机自动连接wifi的方法

本文包括:

  1. 交叉编译树莓派ubuntu系统可使用的内核(debian package格式的可安装文件)

  2. 使用WPA_Supplicant连接wifi


1.1 情景重现:

树莓派开机,运行

复制代码
$ uname -r

结果显示是 5.15 版的内核。 因此去Github下载了 5.4 版的内核源文件,想试验一下更新(切换?)内核。跟着官方教程 <The Linux kernel > 一步步往下做,还算顺利。直到这一步:

复制代码
$ sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img
$ sudo cp arch/arm64/boot/Image mnt/fat32/$KERNEL.img

mnt/fat32 路径下运行下:

复制代码
$ ls -l -h | grep img

找出的像内核的玩意,也只有initrd.img 了。把它备份,然后将编译好的Image复制到 mnt/fat32/ 下,改名为kernel8.img(树莓派4B 64位内核的默认名字)。接下来照猫画虎,一步步完成。接着插卡,开机,就启动不了了。屏幕卡在 "Initramfs unpacking faild: invalid magic at start of compressed archive"。然后我在百度、谷歌、搜狗搜索了两天,了解了内核发展史上,使用过的各种压缩解压算法,比如lz4,gzip等等等。也尝试着在各种配置文件里,修改内核启动时的解压算法选项。啥用都没有。之后又郁闷了一个周日,为啥initrd.img 28M,我编译的内核才十几M?直到我灵光一闪,去搜索了initrd.img。原来这位根本就不是内核啊。可是 mnt/fat32/ 下,除了这位,找不到第二个像内核的啦。:-(

后来我才知道,原来ubuntu跟树莓派官方系统的内核文件结构是不同的。刷回树莓派系统,迫不及待的打开 mnt/fat32/ 查看,果然有kernel8.img。

但是如果就是想将ubunut 5.15版的内核改成5.4版,该怎么办?方法总结如下。

1.2. 编译树莓派ubuntu系统可使用的内核(debian package格式的可安装文件)

参考网页:編譯 Raspberry Pi 4 的 Kernel Image (十分感谢这篇博客,因为基本上没找到其它有用的资料。其它为数不多涉及到该主题的内容,也大多是些论坛内零零散散的回答。)

复制代码
#1 准备编译环境

$ sudo apt update

# 创建编译linux所需要的环境

$ sudo apt build-dep linux 

# 上边那步做的还不够,还需要安装这些软件

$ sudo apt install build-essential libncurses-dev linux-tools-common fakeroot


# man apt-get 对build-dep的解释
# build-dep
#           build-dep causes apt-get to install/remove packages in an attempt
#           to satisfy the build dependencies for a source package. By default
#           the dependencies are satisfied to build the package natively. If
#           desired a host-architecture can be specified with the
#           --host-architecture option instead.


#2. 安装交叉编译器

$ sudo apt install crossbuild-essential-arm64

#3. 下载内核源文件
#一般下载ubuntu官方组织提供的版本。虽然原博客提供了直接编译mainline内核的方法,但麻烦很多。
#所谓mainline版本就是在 kernel.org 发布的版本。

$ mkdir ~/kbuild
$ cd ~/kbuild
$ git clone --depth=1 git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux-raspi/+git/focal

#4. 交叉编译

# 所需环境变量
$ export CC=aarch64-linux-gnu-gcc
$ export $(dpkg-architecture -aarm64)
$ export CROSS_COMPILE=aarch64-linux-gnu-

$ fakeroot debian/rules clean
$ fakeroot debian/rules binary-headers binary binary-perarch

# fakeroot 和 debian/rules 的简单解释
# fakeroot:
#    Gives a fake root environment, to remove the need to become root for a package build.

#debian/rules:
#    The debian/rules script is the executable script to build the Debian package.

#5. 安装内核
#生成的几个.deb在顶层目录,即~/kbuild下
#将它们复制到树莓派 /home/username 下,安装即可
复制代码
$ sudo dpkg -i *.deb
$ ync; sudo reboot

亲测可用。但是对于这种debian/rules的编译方法,如何编译外部模块(比如驱动),我试验了好久都没有解决。因为用make编译外部模块时,会提示缺少配置文件(比如.config)。这些配置文件是直接通过make编译内核时,一定会有先配置好的。而用 debian/rules编译内核时,跳过了配置这一步(用了debian/rules的配置方法,当然其配置文件也存放在某个目录下,但不在源码根目录下)。因此,直接用make编译外部模块时,会找不到配置文件。而如何用debian/rules的方式编译外部模块,又找不到太多的相关资料,只知道个m-a(module-assistant,https://wiki.debian.org/ModuleAssistant)命令。虽然用ubuntu源代码build目录下的某个目录,替换源代码目录,可解决找不到配置文件的问题。但又会有其它问题。总之,现在还不会。

而换回树莓派官方系统后,很容易就配置成功了。因为树莓派一开始就是直接用make直接编译的。比如:

复制代码
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs

而编译前,它显示的配置了内核:

复制代码
cd linux
KERNEL=kernel8
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig

2.1 情景重现:

树莓派官方系统,用systemctl设置开机自动连接wifi后,会出现启动死循环。即启动失败,掉电,又加电,又启动失败。如此循环,一直不知道为啥。后来在树莓派的ubuntu系统上,测试systemctl start testwifi.service时(blog1里有介绍),一start就关机。一enable就进入启动死循环。当我把服务所执行的脚本 test.sh 的命令减少到只有一条 nmcli dev wifi connect "myssid" password "mypassword" 时,情况还是如此。我就知道nmcli靠不住了。

2.2 WPA_Supplicant连接wpa2网络

参考网页:Using WPA_Supplicant to Connect to WPA2 Wi-fi from Terminal on Ubuntu 16.04 Server

复制代码
#1 确保无线网卡可用(一般可以跳过)
# 因为各国家/地方的法律问题等,无线网卡的初始状态可能是被锁定
$ sudo apt install rfkill
# 检查无线网卡状态
$ rfkill list
# 如果无线网卡被锁住,解锁
$ rfkill unblock wifi

#2 如果系统有NetworkManager服务,关闭它
# 可先查看下,当前系统有无此服务
$ sudo systemctl status NetworkManager
# 有则关闭
$ sudo systemctl stop NetworkManager
$ sudo systemctl disable NetworkManager

#3 查看无线网卡
# 一般叫wlan0,此时ACCESS POINT状态为 not associated
$ iwconfig
# 打开网卡
$ sudo ifconfig wlan0 up
# 搜一下,要连接的wifi能不能搜到
sudo iwlist wlan0 scan | grep your-ESSID

#4 使用wpa_supplicant连接网络
# 生成配置文件,同时文件里的密码会被加密
$ wpa_passphrase your-ESSID your-passphrase | sudo tee /etc/wpa_supplicant.conf
# 连接wifi,这个-B是指在后台运行,所以一次iwconfig查不到连接状态,可以在稍等一会。
sudo wpa_supplicant -B -c /etc/wpa_supplicant.conf -i wlan0
#查看无线网卡,此时ACCESS POINT状态为所连接的wifi
iwconfig
#此时还没有分配ip
$ sudo dhclient wlan0
#查看无线网卡,此时应该有ip了,且可以上网了。ping baidu.com能通
iwconfig
#发布ip
#-r
#Tell dhclient to release the current lease it has from the server. This 
#is not required by the DHCP protocol, but some ISPs require their 
#clients to notify the server if they wish to release an assigned IP address.
$ sudo dhclient wlan0 -r
相关推荐
A小辣椒2 天前
TShark:Wireshark CLI 功能
linux
A小辣椒2 天前
TShark:基础知识
linux
AlfredZhao2 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao3 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334663 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪3 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush44 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5204 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩4 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言