说到Linux内核,很多人可能会认为只有Linus这样的神才懂。但事实是任何人都能参与,比如我这样能力差的也参与到Linux内核社区了。可能很多人早就想贡献Linux内核了,但就是不知道怎么开始。
Linux内核有一个官方网站The Linux Kernel Archives,在这个网站上可以获取Linux内核源码以及其他相关源码。
Linux内核社区主要以邮件交流为主,以下是一些常用的网站:
openEuler托管在gitee上,贡献openEuler要通过提交Pull Requests。
CLA
协议是开源贡献协议,用于规范贡献者的权利及义务。贡献者在贡献openEuler社区前,需要签署CLA,签署流程。如果你是以公司邮箱贡献,且公司已经签了CLA,你应该选择“法人贡献者登记”;如果你是以个人邮箱贡献,选择“签署个人CLA”。注意仓库下.git/config或~/.gitconfig中的邮箱配置要求必须是签署了CLA的邮箱,用git log --pretty=fuller可以查看commit的邮箱。
openEuler内核补丁提交规范
(比较老的文档Kernel SIG |
openEuler Kernel 补丁合入规范), 可以在上游主线仓库或
stable仓库路径下用
脚本create-openeuler-git-msg.sh
生成openEuler补丁需要的格式。
注意openEuler门禁会检查修改前后的kabi变化,如果想自己本地检查,可以对比修改前后的vmlinux.symvers和Module.symvers。
openEuler的LTS有kabi白名单,使用脚本check-kabi(注意不能使用openeuler/kernel仓库的脚本)对比Module.kabi_x86_64或Module.kabi_aarch64:
../src-openeuler-kernel/check-kabi -k ../src-openeuler-kernel/Module.kabi_x86_64 -s kabi-build/Module.symvers我们以社区最近的一个LTS(longterm support,长期维护版本)v6.6的代码来讲接下来的课程。
内核源码树根目录每个文件夹的描述如下(按字母顺序):
arch:
architecture的缩写,体系结构相关。我们着重介绍arch/x86/和arch/arm64/,在每个体系结构目录下,boot/是启动相关,configs/是配置相关,include/头文件相关,mm/内存管理相关,等等。block: 块设备IO层相关。certs: 认证相关。crypto: 加密API,加密、散列、压缩、校验等算法。Documentation: 文档,要多看,很有用。也可以看在线文档:
https://www.kernel.org/doc/html/latest/drivers: 设备驱动程序相关。fs:
文件系统相关。我们主要介绍fs/目录下VFS(虚拟文件系统)相关的,还会介绍几个具体的文件系统,如fs/ext2/、fs/xfs/、fs/proc/、fs/sysfs/等,当然具体的文件系统不会介绍得很详细,只说一个大概,主要还是以VFS的讲解为主。include: 内核头文件相关。init: 内核引导和初始化相关。io_uring:
5.1版本引入的高性能异步IO框架,主要是为了加快IO密集型应用的性能。ipc: 进程间通信相关。kernel: 进程相关,包括进程管理和进程调度。lib:
可以看成是一个标准C库的子集,如strlen、mmcpy、sprintf等函数。LICENSES: 许可证。mm:
与体系结构无关的内存管理代码,注意与体系结构相关的代码在arch/mm/目录下。net: 网络子系统,如TCP/IP等网络协议的实现。rust:
内核除了C语言外采用的一门新开发语言,和C性能差不多,目前暂时主要用于驱动开发。samples: 示例代码,很好的学习资源,不要放过。scripts:
脚本文件,如make menuconfig、make scripts_gdb等都是调用这个目录下的脚本。security:
安全模块,比如复杂的selinux。sound: 语音子系统相关。tools: 开发工具相关。usr:
早期的用户空间代码(initramfs),比如有打包和压缩用的cpio等。注意,usr的全称是Unix System Resources,不是user,不是user,不是user。为什么要强调不是user呢,因为有太多太多的人读成了user,咱们专业点,读成u, s, r,一个单词一个单词的读。virt: 虚拟化相关,如kvm。上面是文件夹,接下来介绍根目录下的文件:
COPYING: 许可证。CREDITS: 贡献者。Kbuild: 内核顶层目录的Kbuild,
在进入子目录之前准备全局头文件并检查完整性。Kconfig: 内核配置。MAINTAINERS: 维护者名单。Makefile: 设置编译参数。README: 描述文档在哪里。你可以通过bugzilla或syzbot发现内核bug,也可以通过阅读内核代码发现bug或进行重构。
或者可以用calc-func-lines.sh脚本
找到长函数(不容易阅读)进行重构。
如果是多个人一起开发的补丁,需要加上Co-developed-by:,顺序是先Co-developed-by:第二作者,然后Signed-off-by:第二作者,最后Signed-off-by:第一作者。
可以参考内核仓库中的补丁 ,比如我提交的补丁 。修改代码时要参考Linux内核代码风格。
脚本checkpatch.pl中建议,
代码每行最多100个字符($max_line_length = 100),commit
message每行长度最多 75
个字符(length($line) > 75)。
git commit命令之后,使用以下命令会生成补丁文件:
# -1 表示最后一次commit
# 如果文件名较长,可以加 --stat=300,200 显示完整路径
git format-patch -1 --stat=300,200
# 指定commit号
git format-patch --subject-prefix="PATCH next" -1 <commit号>
# 如果是第2个版本或第3个版本,需要指定v2或v3
git format-patch --subject-prefix="PATCH v2" -1
# 如果内容不变,重新发送(比如加一个抄送的人)
git format-patch --subject-prefix="PATCH resend,v2" -1
# 从指定的commit号数向前3个,共生成3个补丁
git format-patch --subject-prefix="PATCH resend,v2" -3 <commit号>
# 生成从 A 到 B 之间(不含A,含B)的所有提交的补丁
git format-patch <commit-A>..<commit-B>
# 生成补丁集
git format-patch --subject-prefix="PATCH resend,v2" -3 commit号 --cover-letter
# 编辑0000-cover-letter.patch, 可参考patchwork上其他补丁的写法
vim 0000-cover-letter.patch
@linux.dev邮箱申请发送邮件到helpdesk@kernel.org:
Subject: chenxiaosong.chenxiaosong@linux.dev account request
Full name: [ChenXiaoSong ChenXiaoSong]
Canonical address: [chenxiaosong@kylinos.cn]
Reasons for needing this account:
Emails sent from the address I’m currently using are often not received by others, which greatly affects my communication with the community.
My Linux kernel contributions:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?qt=grep&q=chenxiaosong
My communication records with Kernel Mailing Lists:
https://lore.kernel.org/all/?q=chenxiaosong.gitconfig和thunderbird中登录的密码。最新版本的thunderbird默认使用html格式发送和显示,需要更改配置,参考Plain text e-mail - Thunderbird。
依次点击
Account Settings(账户设置) -> 地址簿 -> Composition & Addressing -> Composition(编写) -> 取消勾选 Compose messages in HTML format(以html格式编写消息)。
thunderbird有个快捷键k,会忽略话题,不小心按下后邮件就会不再显示,可以在查看 -> 话题里勾选已忽略话题,就能看到不小心按下k而不显示的邮件。
还有,不建议订阅内核任何模块的邮件列表,因为太多了,一旦订阅邮箱基本就爆了,可以在邮件列表网站上选择对应的模块在线浏览, 如果需要回复,可以把邮件下载下来保存成文件,然后用thunderbird打开文件,然后就可以回复了。如果实在要订阅,可以访问 vger.kernel.org和linux-kernel mailing list FAQ。
纯文本格式和签名设置:
安装软件:
sudo apt install git-email -y@linux.dev邮箱~/.gitconfig:
[sendemail]
from = chenxiaosong.chenxiaosong@linux.dev
smtpserver = smtp.migadu.com
smtpuser = chenxiaosong.chenxiaosong@linux.dev
smtpencryption = ssl
smtppass = 此处填写密码
smtpserverport = 465163邮箱~/.gitconfig:
[sendemail]
from = your_name@163.com
smtpserver = smtp.163.com
smtpuser = your_name@163.com
smtpencryption = ssl
smtppass = 此处填写163邮箱的授权密码
smtpserverport = 994 foxmail(qq)邮箱~/.gitconfig:
[sendemail]
from = your_name@foxmail.com
smtpserver = smtp.qq.com
smtpuser = your_name@foxmail.com
smtpencryption = ssl
smtppass = 此处填写qq邮箱的授权密码腾讯企业邮箱~/.gitconfig:
[sendemail]
from = your_name@your_name.com
smtpserver = smtp.exmail.qq.com
smtpuser = your_name@your_name.com
smtpencryption = ssl
smtppass = 此处填写腾讯企业邮箱的授权密码
smtpserverport = 465获取maintainer邮箱:
./scripts/get_maintainer.pl file1.patch
发送邮件:
# --to是主送,--cc是抄送
git send-email --to=to1@example.com,to2@example.com --cc=cc1@example.com,cc2@example.com file1.patch file2.patch
# 如果补丁集只发送一部分,剩下未发送的补丁用以下选项
# 其中 identifier 是尖括号中的内容: In-Reply-To: <20251027071316.3468472-1-chenxiaosong.chenxiaosong@linux.dev>
git send-email ... --in-reply-to=identifier --no-thread # --suppress-cc=all
可以使用脚本get-maintainer-email.sh来获取邮箱:
git format-patch -1 1aee9158bc97
bash get-maintainer-email.sh fs/nfs/ fs/nfsd fs/nfs_common 0001-nfsd-lock_rename-needs-both-directories-to-live-on-t.patch