当Linux驱动程序开发到一定阶段,向kernel.org提交代码是一个很好的选择。对于很多没有向上游提交过代码的开发者来说,还是有很多疑问需要解决的。比如,究竟我们向哪里提交驱动程序?提交时我们的代码应该处于什么状态?提交的过程又如何呢?
向哪里提交
Linux staging tree是Greg KH建立的用于提交驱动程序的git仓库。我们可以把staging tree看作是代码进入mainline内核之前的一个预科班,新增的驱动程序首先需要放到这里供社区review和测试。Staging tree是 Greg KH于2008年建立的一棵kernel tree,其建立之目的是用来放置一些未充分测试或者因为一些其他原因未能进入内核的新增驱动程序和新增文件系统。
Linux staging tree的URL是" git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git "或者" http://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git "。这里需要注意的是,git协议的端口号是9418,因为很多公司的防火墙只会开放80端口,clone代码仓库时如果git协议超时,不妨试试http协议。
关于Linux staging tree更详细的描述可以参考我前一篇博文《小议Linux staging tree》(http://www.cnblogs.com/wwang/archive/2011/03/08/1970432.html)。
我们的代码
在我们向上游提交驱动程序之前,需要保证代码能够遵循Linux内核的coding style。当然,这个规定并不是强制的,如果您经常阅读Linux内核代码,就会发现很多驱动对内核coding style的遵循情况也并不是太好。但一致的代码风格对代码的维护大有裨益,所以对作为Linux内核驱动程序员的我们来说,遵循coding style是一个很好的习惯。关于Linux内核的coding style的详细信息,可以参考Linux内核里的Documentation/CodingStyle文档,或者我之前的博文《谈谈为 Linux 内核开发驱动代码的编码风格》(https://linux.cn/article-5919-1.html)。
我们在提交驱动之前还需要用静态代码检查工具sparse来检查一下代码。
sparse的源代码可以从“git://git.kernel.org/pub/scm/devel/sparse/sparse.git”获得,得到代码之后,执行"make; make install"来编译生成可执行程序。默认情况下,sparse程序会被放到目录“~/bin”下面,如果您不喜欢这个位置,可以修改Makefile来设定路径。需要注意的是,使用sparse之前,PATH环境变量要设置正确。
sparse的使用方法很简单,只要在make驱动程序时加上“C=N”的选项即可,其中N的取值是1或者2。当N=1时表示对需要重新编译的C文件进行代码检查,N=2时表示对所有的C文件进行代码检查。
对于staging目录下的驱动来说,我们还需要附上一个TODO文件,用来描述未来的维护计划。一般情况下,TODO文件可以这样写:
TODO:
- support more features
- use kernel coding style
- checkpatch.pl fixes
如何提交
我们可以通过patch的形式把驱动程序提交给staging tree。提交之前,需要首先把staging tree clone到本地,然后基于当前的工作目录制作patch。
Git提供了制作格式化的patch的功能,命令如下:
git format-patch -N
其中,N是整数,用来指定我们把最近N次提交做成N个patch。比如当N=1时,就表示把最近一次提交制作成patch。Git会根据提交的log信息来自动命名patch文件。
这里需要注意的是,每次提交的log的描述要遵循一定的格式。
Log的第一行是一个简短的描述。本文主要介绍如何向staging tree提交代码,我们需要在Log首行以“staging:”开头。Log的最后一行需要提供提交者的email信息,我们可以这样写:“Signed-off-by: wwang <wwang@some.site>”。
举个例子,假定我们的staging driver命名为hello_world,log的格式可以参考如下:
staging: hello_world: My first commit
This is my first commit.
Signed-off-by: wwang <wwang@some.site>
Patch生成之后,我们需要把它寄给staging tree的维护者,通常是Greg KH本人以及linux内核驱动的开发者列表。这个步骤也可以使用git来帮助我们完成,但首先需要确定系统里已经安装msmtp和git-email这两个包。这里还需提醒一下,如果您的邮件服务器是Exchange,很可能需要NTLM认证,这就要求msmtp支持NTLM。Ubuntu仓库里的msmtp默认支持NTLM,可以直接使用,但还有些其他的发行版的软件仓库里自带的msmtp并不支持NTLM(如Arch Linux),这种情况就需要自己编译了。
msmtp安装好之后,需要配置"~/.msmtprc"文件。以Gmail为例,".msmtprc"可以这样配置:
# Set default values for all following accounts.
defaults
logfile ~/.msmtp.log
# gmail
account gmail
protocol smtp
host smtp.gmail.com
from my@gmail.com
user my@gmail.com
password mypasswd
port 587
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
syslog LOG_MAIL
# Set a default account
account default : gmail
用git发送patch的命令如下:
git send-email \
--smtp-server /usr/bin/msmtp \
--from my@gmail.com \
--to gregkh@suse.de \
--to devel@linuxdriverproject.org \
--to linux-kernel@vger.kernel.org \
./my.patch
将patch发送出去只是提交驱动程序的第一步,之后还需要不断的维护与完善,把代码丢给内核然后就放手不管的做法是不可取的。提交代码还有一个原则,就是每次提交只做一件事情,这样才会比较方便内核维护者来review我们的代码。
谈谈为Linux内核写驱动的编码规范:http://www.linuxdiyf.com/linux/13079.html
Linux设备驱动的分层设计思想:http://www.linuxdiyf.com/linux/11731.html