最近给linux社区提交了一个新驱动,反复修改了快两个月,发了9个版本。。。终于被社区接受了。做个笔记总结一下。
下载最新的linux内核代码:
下载最新的内核代码用于新驱动的编译验证,因为最新的内核中可能有一些新的特性,比如新的接口什么的,这些你可能并不知道,而维护者会要求你的新驱动中务必要使用新的接口或实现新的功能,所以你必须基于最新的内核代码进行编译验证和代码提交:
最新版本linux下载:git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
个别情况下,维护者可能会要求你使用即将在下一版中才会使用的功能,也就是比最新的kernel还要新,这种情况下你需要下载linux-next版本进行编译验证和提交。
linux-next版本下载:git clone https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
添加你的驱动到上述内核代码中,在本地commit代码:
git commit -s
加上-s参数可以在commit的下端生成Signed-off-by: My Name <my_email@gmail.com> 这些都是必要的。
关于commit信息,务必要参考同类驱动的历史提交中的commit信息的格式,否则会被要求重新提交;
新加的驱动会有dt-binding和vendor信息的相关修改,这两个会被要求各自是独立的commit,不能和驱动代码放在同一次提交中。
所有工作之前,如果你的代码是windows下创建的,你需要用dos2unix drivers/iio/proximity/hx9023s.c转换成linux文件格式。
如果你的代码并没有遵循linux的格式要求的话,可以先用astyle格式化代码
astyle --style=linux --indent=tab --convert-tabs --pad-oper --pad-header --align-pointer=name --align-reference=name --add-brackets --suffix=none drivers/iio/proximity/hx9023s.c
编译:
我们提到这个内核代码只是用于编译验证的,因此,在把你的驱动添加进去后大可不必做交叉编译(因为大部分人工作时都是用交叉编译,这里可能会因为惯性,又开始做交叉编译,可以这么验证,但是没必要),直接编译x86做验证即可。
首先安装编译相关的工具:
sudo apt-get update
sudo apt-get install build-essential libncurses-dev bison flex libssl-dev libelf-dev
然后测试编译原始版本,完整编译:
make defconfig 在x86环境下对应的是arch/x86/configs/x86_64_defconfig
make -j16
先完整编译一次内核是有必要的!因为后续的某些代码检查工具会依赖这次完整编译。
修改你的代码中的全部编译错误。
静态编译检查:
没有编译错误后执行代码的静态编译检查:
make C=1 CHECK="sparse" M=drivers/iio/proximity 最后这个参数指向你的新代码所在的目录
修改以上静态检查结果中的错误;
单独编译你的驱动:
后续修改代码后可以快速编译,只编译你的驱动即可,不必全部编译:
make M=drivers/iio/proximity hx9023s.ko
代码格式规范检查:
./scripts/checkpatch.pl --strict drivers/iio/proximity/hx9023s.c
直接对源码进行规范检查尝试是可以的,但是正规的方式是把你的修改做个patch,然后对patch进行规范检查,如下:
./scripts/checkpatch.pl --strict 0001-iio-proximity-Add-driver-support-for-TYHX-s-HX9023S-.patch 0002-iio-proximity-Add-driver-support-for-TYHX-s-HX9023S-.patch 0003-iio-proximity-Add-driver-support-for-TYHX-s-HX9023S-.patch
没有什么问题就可以给社区提交了,最好不要用最基本的git send-email这种方式提交代码!因为代码会反复修改和提交多次,这个原始方法不适合管理。
b4是一个专用的linux社区代码提交工具,用这个会更方便一些:
先安装git-email用来发送邮件
sudo apt install git-email
安装b4:
sudo apt install python3 python3-pip
pipx install b4
pipx ensurepath
pipx completions
需要重启终端后b4才可用
对b4的一些理解:
b4必须工作自己的特定分支,,它会在这个特定分支顶端创建一个空commit,这个commit用于分割你要提交的修改和以前的commit,同时这个commit会被b4反复修改用来跟踪你的每次patch提交。它也是cover-letter。每次通过b4 send patch之后,这个commit就会以注释的形式追加一个下次的提交版本号和对应的comment模板。所以第一步就是创建一个b4的工作分支:
b4 prep -n Add-TYHX-HX9023S-sensor-driver
然后如果你先前在没有b4的跟踪下工作,可以把你的先前提交cherry-pick过来,要知道,这就是一个普通的branch而已,没什么特别。像以前一样在这个分支工作就好。把你的工作commit之后,提交前可以让b4做个patch检查:
b4 prep --check
编辑cover-letter正文:也就是哪个空commit的注释部分
b4 prep --edit-cover
b4会自动添加版本号,这个版本号取决于那个空commit中的revision关键字,它记录的上次的版本号,所以这次的版本号会在这个revision的基础上加1.所以如果你半路把工作切换到b4的,那你要用git rebase -i hash123456,把这个空提交的revision改成你的上次给社区提交时用的版本号。
尝试用b4将patch给自己发出,用以测试效果:
b4 send --to yasin.lee.x@gmail.com
如过没有执行过auto-to-cc的话,b4会给你提示,然后你要执行一下:
b4 prep --auto-to-cc 以上给自己发出patch后,检查无误后再执行这个命令!!!执行完这个命令后,发送时就会给所有相关维护者发出邮件了!
然后继续b4 send --to yasin.lee.x@gmail.com,就能给相关维护者抄过去了(同时可以给自己发一份)。
提交后可以在以下公开的邮件列表中搜索到你的提交。
后续等待维护者给你回复邮件,社区要求每个回复邮件中的每条建议都要被响应。所以你需要回复每个邮件,并对每一条建议或者疑问给出回复。那怕只是回复一句话表示接受这个建议。注意回复邮件应该是纯文本模式!回复时采用inline方式,就是把你的回复嵌入在原邮件中。
b4命令总结:
b4 prep --check 用脚本检查patches
b4 prep --edit-cover 编译封面邮件内容,注意别忘记邮件标题就是那个空commit的第一行信息
b4 prep --auto-to-cc 生成接收列表并记录在那个空commit中
b4 send --to yasin.lee.x@gmail.com 这个真的发送,不过中间会和用户交互一次,此时可以Ctrl+C终止。除了上面记录的接收列表,你也可以自己在这里再加一些接收者
最后,千万不要用outlook的邮箱!!!outlook服务器会篡改邮件头,这样邮件达到其他人那里后会无法和历史邮件关联成邮件线程!!!
其他一些可能的优化:
使用pahole工具检查代码中结构体的内存空洞,然后通过调整结构体中成员的位置,对空洞进行消除,一般情况下,把相同的数据类型排列在一起,并将数据类型从大到小排列,可以减少空洞的产生。
安装:
sudo apt-get install dwarves
使用:先要编译出带调试信息的内核模块,需要加上CFLAGS_MODULE="-g"参数。如果你在调试应用程序的话只有在gcc后加上-g参数即可,如:
gcc -g -o my_program my_program.c
然后:pahole my_program
如果是内核模块的话,就要像下面这样啦:
make M=drivers/iio/proximity CFLAGS_MODULE="-g" hx9023s.ko
然后:pahole drivers/iio/proximity/hx9023s.ko
检查dt-binding相关的yaml文件:
先安装相关工具,否则yaml有错误也检查不出来
sudo apt install yamllint
pip3 install dtschema --upgrade
rm Documentation/devicetree/bindings/processed-schema.json
DT编译检查
make dt_binding_check -j16 这会编译检查全部的yaml文件,特别慢!不要用!
用下面这个,编译检查指定的yaml文件
make DT_SCHEMA_FILES=Documentation/devicetree/bindings/iio/proximity/tyhx,hx9023s.yaml dt_binding_check