《DIM-SUM操作系统详解--迈向工业级服务器系统》样章----准备工作
Posted 操作系统黑客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《DIM-SUM操作系统详解--迈向工业级服务器系统》样章----准备工作相关的知识,希望对你有一定的参考价值。
第 1章
准备工作
本书详细解剖了DIM-SUM操作系统的源代码。DIM-SUM操作系统是本书作者谢宝友在过去几年中,陆续实现的一个操作系统。它的版权遵循GPL V2开源软件协议。
由于DIM-SUM是一个不断发展中的操作系统,因此本书以其第一个发布版本为基础进行剖析。这个版本的名称是:HOT-POT。以后的版本可能会被称为“dumpling”、“noodle”,总之是我们能够想到的中国小吃名称:-)
1.1. DIM-SUM简介
1.1.1. 为什么是HOT-POT?
HOT-POT意为火锅,是非常有川渝特色的地方美食。之所以取这个名称,主要有如下原因:
1、四川是作者的故乡,并且作者来到成都已经有20多年了。对这个城市的火锅印象深刻!
2、红通通的火锅,有鲜明的民族烙印,代表了喜庆、热闹、欢快的含义。
3、如果您真的吃过火锅,那么可能忘不了它的辣,一定不能小瞧它,并且久久不能忘怀以至于想要多尝几次。希望这款操作系统也能带给您这样的感觉。
1.1.2. DIM-SUM是什么
如果说目前的DIM-SUM是一个完美的操作系统,那无疑是一个谎言。但是,如果说这个操作系统就仅仅是一个茶余饭后的谈资,那无疑也是另一个谎言。
最基本的,希望它可供操作系统爱好者用于学习目的,并且作者相信这完全没有问题。但是,作者的目的不仅仅是如此。其远大的目标,是实现一款工业级服务器操作系统。简而言之,就是一款可以在生产环境下面使用的,可以在服务器和个人电脑上面正常运行的操作系统。当然了,这样的一款操作系统必然也能够运行在嵌入式设备中。例如,运行在电视、电表、摄像头、手表,以及其他一些我们能够想象得到的嵌入式设备中。
任何心智正常的人,都知道实现这样的操作系统是一件很难的事情。读者可能忍不住想问:为什么作者您想去做这么一件很难,并且可能没有什么收益,也许还会让您招致耻笑的笨事呢?难道您真的是一个笨蛋?
作者也忍不住这样回答质疑:
1、是的,作者确实是一个笨蛋。但是古语说的好:聪明人下笨功夫!
2、正如作者在其译作《深入理解并行编程》一书的译者序中所说:
20年前,当我正式成为一名软件工程师的时候,就有一个梦想:开发一款操作系统。那时候,虽然知道Linux的存在,但是实在找不到一台可以正常安装使用Linux的PC。因此只能阅读相关的源码分析书籍而不能动手实践。
在浮躁的年代,谈论梦想可能一件不合时宜的行为。然而有什么办法呢?这毕竟真的是20年前的梦想,难道您想让我撒谎?
3、开源软件运动,已经为我们实现操作系统提供了现实可能性。首先,象Linux这样的开源操作系统为我们提供了很好的基础,这样我们可以从开源软件中学习到不少的技能、方法、设计思路。其次,开源软件允许分散在各地的开发者协同工作,集思广益的开发操作系统。作者在Linux社区中,作为ARM/ZTE ARCHITECTURE的Maintainer,对此深有体会。
4、操作系统是IT行业的核武器。到目前为止,我们还处于“缺芯少魂”的状态,其中的“魂”就是操作系统。真正核心的软件,需要一代人,甚至几代人耐心的雕琢,而不能寄希望于短时间内产生立竿见影的效果。换句话说,要有“板凳一坐十年冷”的心态来做这件事。有了这样的心态,就不会觉得难。
5、从另一个角度来说:万古长空,一朝风月。任何难事,一旦想要去做,就需要把握当下。空谈误国,实干方能兴邦。即使这件事情很难,但是不动手永远不会有任何结果。况且,作者喜欢有挑战性的事情,例如:写一个工业级服务器操作系统:-)
目前,DIM-SUM已经实现了如下功能:
1、arm 64 qemu小系统,含内存、时钟初始化。
2、全局优先级调度模块,调度算法类似于Linux实时调度。
3、内存管理模块,包含页面管理、beehive分配器。
4、兼容linux ext3的LEXT3文件系统。
5、块设备层实现。
6、集成了LWIP网络协议栈。
7、移植了常用的内核态C库API。
8、实现了一个粗糙的命令控制台。
总之,作者认为HOT-POT是DIM-SUM操作系统的Good Start。在后续的开发过程中,作者怀着热切的心情,期待您参与到它的开发中来。
1.1.3. DIM-SUM欢迎什么?
任何建设性对抗性质的建议、稳定优雅的代码、BUG报告、测试、社区建设等等,都是DIM-SUM所欢迎的!
1.1.4. DIM-SUM不欢迎什么?
我们不欢迎空谈和只会报怨的人。虽然我们知道,DIM-SUM并不完善,您有很多喷它的理由。
1.2. 获得源码
Paul E.Mckenney曾经说过:
If you want to do cool things, it is necessary to invest large amounts of time learning and (especially!) practicing.
诚哉斯言!
请读者相信我这个20年传奇工匠程序员的经验:要深刻的理解象Linux操作系统这样的复杂代码,必须要动手实践,对着源代码看书!
本书也不会大量的粘贴DIM-SUM源码,这是故意为之的。目的是逼迫读者下载源代码并对照着源码阅读本书。
要获得本书配套源码,您有两种方式:
1.直接通过网页下载
2.通过git获取源代码
1.2.1. 通过网页下载源码
通过网页下载源码是最简单快捷的方式。您可以通过如下两个网址下载DIM-SUM的源代码:
1.https://download.csdn.net/user/xiebaoyou/
2.http://blog.chinaunix.net/uid-25845340-id-5785292.html
将下载的源码包命名为dim-sum.20180519.tar.bz2。为了防止下载过程中,由于网络原因导致的文件损坏,您可以验证源码包的MD5值。在ubuntu 16.04系统中,可以在命令行控制台输入如下命令来得到源码包的MD5值:
md5sum dim-sum.20180519.tar.bz2
正确的MD5值应当是:
e888c22b47adcb266382e1791bb729f8
http://blog.chinaunix.net/uid/25845340.html
通过网页下载源码,可以满足阅读本书的要求。但是,它满足不了您如下的要求:
1.获得DIM-SUM操作系统最新的源代码
2.查阅DIM-SUM操作系统的补丁记录
下一步将讨论如何通过git获得源代码。这也是作者推荐的方式。
1.2.2. 通过git获取源代码
无论怎样强调git在开源项目中的重要性都不过分。作者甚至推荐您找一本git简明手册仔细读一读。
假设您的系统中已经安装好git工具。您可以通过如下命令获取DIM-SUM操作系统的源代码。
git clone https://code.csdn.net/xiebaoyou/dim-sum.git
这个命令会在您的当前目录中创建一个名为dim-sum的子目录,并将DIM-SUM操作系统的代码下载到本地。
小问题1.1:嘿!看起来您是想让读者在Linux环境下阅读并调试代码,但是Linux环境阅读代码是否真的方便。为什么不在书中直接贴出所有代码,您用意何在?
当然,对于大多数读者来说,不仅仅想对照着源码阅读本书。他们还希望:
1、跟踪DIM-SUM的最新版本。
2、查阅DIM-SUM的补丁记录,明白每一个补丁的作用,与补丁的作者联系。
3、给DIM-SUM提交补丁。
4、在DIM-SUM中添加自己的代码。
5、在PC中调试DIM-SUM的代码。
这样的读者需要仔细阅读下一节的内容。
1.3. 搭建调试开发环境
虽然通过上一节的方法获得源码以后,您将能够顺利的阅读本书。但是有一句话说得很正确:纸上得来终觉浅,绝知此事要躬行。因此强烈建议您按照本节的方法搭建调试开发环境。
1.3.1. 安装ubuntu 16.04
作者的笔记本中,安装的操作系统是ubuntu 16.04,因此可以确保本节中的调试开发环境能顺利的运行在ubuntu 16.04系统中。其他的Linux版本应该也是可以的,但是作者并不完全保证其他版本完全正常工作。
首先,您需要在如下链接中下载ubuntu 16.04的安装镜像:
http://old-releases.ubuntu.com/releases/16.04.3/
视您的开发环境PC 机CPU配置,您可以下载不同的安装镜像:
1.64位PC,通过如下链接下载
http://old-releases.ubuntu.com/releases/16.04.3/ubuntu-16.04-desktop-amd64.iso
2.32位PC,通过如下链接下载
http://old-releases.ubuntu.com/releases/16.04.3/ubuntu-16.04-desktop-i386.iso
在http://old-releases.ubuntu.com/releases/16.04.3/MD5SUMS中,有这两个镜像文件的MD5值,分别为:
c94d54942a2954cf852884d656224186
610c4a399df39a78866f9236b8c658da
请检查下载文件的MD5值,确保与上面两个值一致。
小问题1.2:呃,您已经两次提到MD5值了,它有那么重要吗?
有两种方法安装您的ubuntu 16.04。
第一种方法,是直接在物理机上安装ubuntu 16.04。建议您找一台Linux机器,并使用dd命令将镜像烧写到USB中,并通过USB来安装系统。
第二种方法,是在虚拟机中安装ubuntu 16.04。这种方法可以不用将安装镜像烧写到USB中。在虚拟机中实际搭建开发环境,其效果和物理机中是一致的。
ubuntu 16.04的安装过程比较简单,这里不再详述。
小问题1.3:可是我没有Linux环境,也不知道怎么用dd命令来烧写镜像到USB?
为了方便Linux新手,后续假设您是在虚拟机中安装ubuntu 16.04。并以此为基础搭建调试开发环境。
1.3.2. ubuntu 16.04环境配置
首先,请配置您的虚拟机,为它创建两个网卡。
作者在Oracle VM VirtualBox管理器中,是通过“设置”->“网络”进入配置界面。
在“网卡1”标签界面中,选择“启用网络连接”,并在“连接方式”中选择“仅主机(Host-Only)适配器”,在“界面名称”中选择“vboxnet0”。该网卡用于虚拟机与物理机的文件共享连接。
第二步,启动ubuntu 16.04虚拟机,进行如下基本环境配置:
1、打开命令行控制台,在作者的环境中,是通过按“ctrl+alt+t”实现的。
2、在控制台中,输入如下命令切换到root用户。当然,为了防止误操作损坏系统,您也可以不用切换到root用户,但是请记得为后续的某些操作添加sudo前缀。
sudo -s
3、在控制台中,输入如下命令更新apt仓库:
apt-get update
视您的网络状态而定,这一步可能需要花费数分钟的时间。
由于您还没有正确的配置双网卡,因此您的虚拟机还不能正确的连接到互联网。这时可以简单的禁止第一个网卡。
4、在控制台中,输入如下命令安装vim:
apt-get install vim
5、编辑/etc/network/interfaces,输入如下内容:
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
auto enp0s3
iface enp0s3 inet static
address 192.168.0.98
netmask 255.255.255.0
auto enp0s8
iface enp0s8 inet dhcp
enp0s8则是作者创建的虚拟机中的外网网卡,用于虚拟机与互联网之间的通信,在您的机器上可能是其他名称,请注意调整。
编辑并保存/etc/network/interfaces文件后,请运行如下命令重启网络服务,使配置生效:
/etc/init.d/networking restart
第三步,运行如下命令创建工具目录:
mkdir /hot-pot
小问题1.4:一定要在根目录下创建hot-pot目录吗?其他目录名称可以吗?
1.3.3. 搭建编译环境
首先,您需要在ubuntu 16.04中安装git工具。在控制台中输入如下命令开始安装:
apt-get install git
执行完毕后,在控制台中输入如下命令验证git工具是否正确安装:
git --version
如果看到如下控制台输出,则表示git工具安装成功:
git version 2.7.4
第二步,通过git工具下载辅助工具。可以通过如下命令获取这些工具:
cd /hot-pot/
git clone https://code.csdn.net/xiebaoyou/assistant.git
由于assistant这个git仓库中包含了数百M的工具链,可能会花费数分钟甚至一个小时的时间,请耐心等待。完成后,通过如下命令查看是否下载成功:
ls assistant -al
在控制台上,应当看到如下输出:
总用量 44
drwxrwxr-x 5 xiebaoyou xiebaoyou 4096 5月 20 15:12 .
drwxrwxr-x 31 xiebaoyou xiebaoyou 4096 5月 20 20:04 ..
drwxrwxr-x 2 xiebaoyou xiebaoyou 4096 5月 20 15:12 gcc-linaro-5.3
drwxrwxr-x 8 xiebaoyou xiebaoyou 4096 5月 20 15:15 .git
drwxrwxr-x 2 xiebaoyou xiebaoyou 20480 5月 19 17:16 hot-pot.toolchains.4.9.3
-rw-rw-r-- 1 xiebaoyou xiebaoyou 15 5月 19 16:45 README.md
第三步,您需要安装编译工具链。要编译HOT-POT,需要gcc 4.x版本的交叉编译工具链。作者已经将相应的工具链放到assistant/hot-pot.toolchains.4.9.3中。
在控制台中运行如下命令,获得hot-pot.toolchains.4.9.3.tar.bz2工具链压缩包:
cd /hot-pot/assistant/hot-pot.toolchains.4.9.3
cat x* > hot-pot.toolchains.4.9.3.tar.bz2
其中第二条命令将hot-pot.toolchains.4.9.3目录中所有文件合并,生成压缩包文件。
然后使用如下命令检查生成的压缩包是否正确:
md5sum hot-pot.toolchains.4.9.3.tar.bz2
您将会看到如下输出:
3cdfaf72c2fe82535c596414fd4b026c hot-pot.toolchains.4.9.3.tar.bz2
如果输出的MD5值不是“3cdfaf72c2fe82535c596414fd4b026c”,则说明下载过程有误,生成的工具链压缩包不正确。
在控制台中输入如下命令,将压缩包解压,获得可以运行的工具链:
tar xvjf hot-pot.toolchains.4.9.3.tar.bz2 -C ../
在控制台中输入如下命令,检查工具链是否能够正常运行:
/hot-pot/assisant/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc --version
如果在控制台中看到如下输出,那么恭喜您:
aarch64-linux-gnu-gcc (GCC) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
第四步,您需要安装gdb工具。这样我们就能够象调试应用程序那样,对DIM-SUM操作系统进行单步跟踪调试了。这对于深入理解DIM-SUM操作系统有极大的帮助。因此,强烈建议您安装这个工具。
在Linaro gcc 5.3工具链中,已经包含了gdb工具。
同样的,作者在已经将Linaro gcc 5.3工具链放到assistant/gcc-linaro-5.3中。
您可以在控制台中输入如下命令,来生成Linaro gcc 5.3工具链压缩包:
cd /hot-pot/assistant/gcc-linaro-5.3
cat x* > gcc-linaro-5.3-2016.02-x86_64_aarch64-elf.tar.bz2
同样的,请使用md5sum命令检查压缩包是否正确:
md5sum gcc-linaro-5.3-2016.02-x86_64_aarch64-elf.tar.bz2
您应当在控制台中看到如下输出。
e1b129d60b2b8e6f398014057f514b34 gcc-linaro-5.3-2016.02-x86_64_aarch64-elf.tar.bz2
同样的,请注意MD5值应当为“e1b129d60b2b8e6f398014057f514b34”。
在控制台中输入如下命令,将工具链解压:
tar xvjf gcc-linaro-5.3-2016.02-x86_64_aarch64-elf.tar.bz2 --C ../
在控制台中输入如下命令,确认gdb工具是否正常:
/hot-pot/assistant/gcc-linaro-5.3-2016.02-x86_64_aarch64-elf/bin/aarch64-elf-gdb -v
如果一切正常,您将在控制台中看到如下输出:
GNU gdb (Linaro GDB 2016.02) 7.10.1.20160210-cvs
第五步,通过git下载源码。在控制台中输入如下命令:
cd /hot-pot/
git clone https://code.csdn.net/xiebaoyou/dim-sum.git
这一步很快就能够完成,因为DIM-SUM目前的代码规模还不算大:-)
第六步,检出HOT-POT代码,在控制台中输入如下命令:
git checkout -b hot-pot v0.1
该命令会在您的git仓库中创建一个hot-pot分支,并将v0.1版本的代码检出。其中v0.1版本是DIM-SUM的HOT-POT版本。
是不是迫不及待的想为HOT-POT编译出一个可以运行的版本?请接着看下一节。
1.3.4. 编译HOT-POT
编译HOT-POT的方法很简单。如果您编译过Linux源码,应该对下面的命令非常熟悉:
cd /hot-pot/dim-sum/
make ARCH=arm64 qemu_defconfig
make ARCH=arm64 EXTRA_CFLAGS="-g -D__LINUX_ARM_ARCH__=8 -DCONFIG_QEMU=1" CROSS_COMPILE=/hot-pot/assistant/aarch64-linux-gnu/bin/aarch64-linux-gnu- Image dtbs
如果在控制台中看到如下输出信息,则表示编译成功:
CC usr/shell/sh_symbol.o
CC usr/shell/sh_task.o
CC usr/shell/sh_memory.o
CC usr/shell/sh_register.o
LD usr/shell/built-in.o
LD usr/built-in.o
LD vmlinux.o
MODPOST vmlinux.o
WARNING: modpost: Found 20 section mismatch(es).
To see full details build your kernel with:
'make CONFIG_DEBUG_SECTION_MISMATCH=y'
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
KSYM .tmp_kallsyms1.S
AS .tmp_kallsyms1.o
LD .tmp_vmlinux2
KSYM .tmp_kallsyms2.S
AS .tmp_kallsyms2.o
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/arm64/boot/Image
Kernel: arch/arm64/boot/Image is ready
目前,HOT-POT借用了Linux的编译框架,因此输出的符号表文件仍然是“vmlinux”,正如上图中“LD vmlinux”一行所示。当然,如果您能够提交一个补丁来修正这些问题,我们会非常感激的。
小问题1.5:您为什么不详细解释一下编译命令,就象大多数书籍中那样?
在控制台中输入如下命令,看看HOT-POT镜像是否生成成功:
ls arch/arm64/boot/Image -al
预期的结果大概是这样的:
-rwxrwxr-x 1 xiebaoyou xiebaoyou 1066496 5月 21 10:07 arch/arm64/boot/Image
小问题1.6:我的天,生成的镜像竟然超过1M?
1.3.5. 运行HOT-POT
要运行HOT-POT,您需要安装qemu。这为您免除了购买单板的需要。在控制台中,输入如下命令:
apt-get install qemu
安装完成后,请使用如下命令确认成功安装qemu模拟器:
qemu-system-aarch64 --version
您应当在控制台中看到如下输出:
QEMU emulator version 2.5.0 (Debian 1:2.5+dfsg-5ubuntu10.28), Copyright (c) 2003-2008 Fabrice Bellard
运行如下命令,在qemu中启动HOT-POT:
cd /hot-pot/dim-sum/
sudo qemu-system-aarch64 -machine virt -cpu cortex-a53 -m 512 -kernel arch/arm64/boot/Image -drive file=./disk.img,if=none,id=blk -device virtio-blk-device,drive=blk -device virtio-net-device,netdev=network0,mac=52:54:00:4a:1e:d4 -netdev tap,id=network0,ifname=tap0 --append "earlyprintk console=ttyAMA0 root=/dev/vda rootfstype=ext3 init=/bin/ash rw ip=10.0.0.10::10.0.0.1:255.255.255.0:::off"
现在,您看到的应该是如下空白窗口:
别急,按“ctrl+alt+2”看看。激动人心的界面应当出现了,如下:
在这个界面中回车,并输入ls命令,您将会看到如下界面:
小问题1.7:但是请等一等,我想看看前面的输出,该怎么办?
看起来大功告成,但是似乎还缺少一点什么东西?
1.3.6. 开始调试
在前面的步骤中,我们已经将gdb调试工具解压到:
/hot-pot/assistant/gcc-linaro-5.3-2016.02-x86_64_aarch64-elf/bin/aarch64-elf-gdb
现在是时候用用它了。
首先应当换一种方式启动HOT-POT,使用如下命令:
sudo qemu-system-aarch64 -machine virt -cpu cortex-a53 -m 512 -s -S -kernel arch/arm64/boot/Image -drive file=./disk.img,if=none,id=blk -device virtio-blk-device,drive=blk -device virtio-net-device,netdev=network0,mac=52:54:00:4a:1e:d4 -netdev tap,id=network0,ifname=tap0 --append "earlyprintk console=ttyAMA0 root=/dev/vda rootfstype=ext3 init=/bin/ash rw ip=10.0.0.10::10.0.0.1:255.255.255.0:::off"
请注意该命令中的“-s -S”参数,它会暂停HOT-POT的运行,并等待gdb调试。
在控制台中,按“ctrl+shift+t”启动一个新的控制台,我们称之为“调试控制台”。在调试控制台中,输入如下命令启动gdb,准备开始调试HOT-POT:
cd /hot-pot/dim-sum/
/hot-pot/assistant/gcc-linaro-5.3-2016.02-x86_64_aarch64-elf/bin/aarch64-elf-gdb vmlinux
在(gdb)提示符下,输入如下命令,连接到qemu:
target remote localhost:1234
您的调试控制台看起来是这样的:
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x0000000040000000 in ?? ()
在(gdb)提示符下,输入“c”命令,启动HOT-POT。然后切换到qemu窗口,看看HOT-POT是不是已经正常启动了?
接下来,在调试控制台中,按“ctrl+c”,暂停HOT-POT的运行,并在(gdb)提示符下,输入“bt”命令,查看HOT-POT当前停留在什么地方?看起来应当是这样:
(gdb) bt
#0 cpu_do_idle () at arch/arm64/kernel/processor.S:12
#1 0xffffffc0000a8538 in default_powersave () at kernel/sched/idle.c:15
#2 0xffffffc0000a85e8 in default_idle () at kernel/sched/idle.c:27
#3 0xffffffc0000a863c in cpu_idle () at kernel/sched/idle.c:48
#4 0xffffffc0001780c4 in start_master () at init/main.c:96
#5 0x0000000040090240 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
当然了,在调试控制台中,您可以使用所有gdb调试命令。进行诸如单步跟踪、查看变量、查看寄存器、查看堆栈、切换CPU、汇编单步等等操作。
小问题1.8:在调试Linux内核时,我无论是用kgdb,还是qemu,发现单步跟踪时会杂乱无章的跳,有些变量值也看不到。但是HOT-POT中不会这样,宝友您有什么窍门?
1.4. 向DIM-SUM操作系统提交补丁
想修改DIM-SUM的代码,并把它合入到DIM-SUM的git仓库吗?试着给DIM-SUM操作系统提交补丁吧。维护DIM-SUM操作系统的人,使用的都是汉语,沟通起来完全没有问题。并且他们都不是外星人,您不用觉得他们凶巴巴的:-)
1.4.1. 心态
Paul在《深入理解并行编程》一书第11.1.2节中说,验证和测试工作都需要良好的心态。应当以一种破坏性的、甚至带一点仇恨的心理来验证代码,有时也应当考虑到:不少人的生命依赖于我们代码正确性的几率。总之,心态对事情的成败有重要的影响。
您在向DIM-SUM提交补丁之前,请保持如下正确的心态:
1、撇开DIM-SUM不谈。我们的代码,可能会影响不少人的生命,所以为任何项目编写代码,都一定要细心。
2、悲观的说,如果补丁做得不好,会影响自己的声誉,并且得不到足够的关注,最终会导致补丁没有被采纳。
3、乐观的说,DIM-SUM的维护者、开发者一般都比较Nice,如果你的水平真的比较牛的话。
4、更进一步乐观的说,您提交的高质量的补丁,可能会为您带来良好的声誉、满意的工作。
如果您和我一样,有着近乎自大的自信,想要在操作系统方面做出一些成绩,请仔细阅读后面的章节。
1.4.2. 准备工作
跃跃欲试想要提交补丁的读者,一定已经熟悉Linux开发环境了。在此,作者假设您已经安装好Linux和git。这里推荐两份比较好的git参考资料:
http://git.oschina.net/progit/
https://item.jd.com/11615420.html
1、配置git用户名和邮箱
在配置用户名的时候,建议是“名在前,姓在后”,并且第一个拼音字母大写。例如我的用户名是:Baoyou Xie。
在配置邮箱时,请使用有意义的邮箱名,而不要用纯数字邮箱名。
以下是我的配置:
xiebaoyou@ThinkPad-T440$ git config -l | grep "user"
user.email=baoyou.xie@aliyun.com
user.name=Baoyou Xie
2、配置sendemail
您可以手工修改~/.gitconfig,或者git仓库下的.git/config文件,添加[sendemail]节。该配置用于指定发送补丁时用到的邮件服务器参数。
以下是我的配置,供参考:
[sendemail]
smtpencryption = tls
smtpserver = smtp.aliyun.com
smtpuser = baoyou.xie@aliyun.com
smtpserverport = 25
配置完成后,请用如下命令,向自己发送一个测试补丁:
git send-email your.patch --to your.mail --cc your.mail
3、下载源码
如果仅仅是为了阅读本书,而不想向DIM-SUM提交补丁,那么使用git直接从DIM-SUM主分支拉取代码就行了。
使用如下命令可以从主分支拉取DIM-SUM的代码:
git clone https://code.csdn.net/xiebaoyou/dim-sum.git
随时可以使用如下命令更新主分支代码:
git fetch origin master
但是,如果想参与到DIM-SUM的开发,那么就需要从多个git分支拉取代码。这是因为:主分支代码并不一定是最新的,如果基于这个代码制作补丁,很有可能不会顺利的合入到Maintainer那里。换句话说,如果您的代码分支没有与Maintainer保持一致,那么Maintainer有时会将补丁发回给您,要求您重新制作。所以,一般情况下,您需要再用以下命令,添加其他分支:
git remote add tag-name git-url
其中tag-name是您为分支添加的别名。git-url是DIM-SUM分支的URL路径。
随时可以使用如下命令更新分支代码:
git fetch tag-name
MAINTAINERS文件的格式与Linux类似。例如,Linux内核中,watchdog模块的信息如下:
WATCHDOG DEVICE DRIVERS
M: Wim Van Sebroeck <wim@iguana.be>
R: Guenter Roeck <linux@roeck-us.net>
L: linux-watchdog@vger.kernel.org
W: http://www.linux-watchdog.org/
T: git git://www.linux-watchdog.org/linux-watchdog.git
S: Maintained
F: Documentation/devicetree/bindings/watchdog/
F: Documentation/watchdog/
F: drivers/watchdog/
F: include/linux/watchdog.h
F: include/uapi/linux/watchdog.h
4、阅读Documentation/SubmittingPatches
认真阅读这个文件,对正确制作补丁来说很重要。
5、使用如下命令检出源码
git branch mybranch remote-branch
这个命令表示将remote-branch远程分支作为本地mybranch分支,作为我们工作的基础。在这个分支上制作补丁,更容易被Maintainer合入。
使用如下命令切换为本地mybranch分支:
git checkout mybranch
接下来,就可以修改本地代码,开始制作补丁了。
1.4.3. 制作补丁
参与DIM-SUM的开发,可以从简单的事情入手。例如:
1、消除编译警告。
2、整理编码格式,例如注释里面的单词拼写错误、对齐不规范、代码格式不符合社区要求。
Linux社区里面的很多大牛,就是从消除Linux内核警告开始的。下面我们举一个简单的格式整理例子。
在kernel/sched/core.c的第192~193行,其代码看起来如下:
192 next = list_first_container(&sched_runqueue_list[idx],
193 struct task_desc, run_list);
其中第193行有两个问题:
1、该行包含了84个字符,其中每个TAB键占用8个字符空间,超过了80个字符的限制。
2、与上一行对齐有问题,排版太难看了。
我们删除该行前面几个TAB键,使其看起来如下:
192 next = list_first_container(&sched_runqueue_list[idx],
193 struct task_desc, run_list);
修改完成后,在控制台输入如下命令将补丁提交到本地git仓库:
git commit -a
然后使用如下命令生成补丁文件:
git format-patch -s -v 1 -1
生成的补丁内容如下:
cat v1-0001-.patch
From d75a0cea3945d79176645ce17748aebd5701a07e Mon Sep 17 00:00:00 2001
From: Baoyou Xie <baoyou.xie@aliyun.com>
Date: Mon, 21 May 2018 14:29:45 +0800
Subject: [PATCH v1] =?utf-8?q?=E8=B0=83=E5=BA=A6=EF=BC=9A=E6=95=B4?=
=?utf-8?q?=E7=90=86=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
在core.c第193行,代码行超过了80个字符,并且与上一行没有正确的对齐,因此应该删除其多余的前导TAB键。本补丁删除这些多余的TAB键以满足代码格式规范。
Signed-off-by: Baoyou Xie <baoyou.xie@aliyun.com>
---
kernel/sched/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3faa53c..c93df0d 100755
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -190,7 +190,7 @@ need_resched:
next = idle_task_desc[smp_processor_id()];
else
next = list_first_container(&sched_runqueue_list[idx],
-struct task_desc, run_list);
+struct task_desc, run_list);
/**
* 什么情况下,二者会相等??
--
2.7.4
难道制作一个补丁就这么简单?我们可以将它发送给Maintainer了吗?
答案当然是否定的。这个补丁有如下问题:
1、没有彻底解决模块中同类问题。
2、补丁格式不正确。
首先我们应当将补丁回退。使用如下命令进行回退:
git reset HEAD~1
1.4.4. 制作正确的补丁
实际上,在向Maintainer发送补丁之前,应当用如下对补丁进行检查:
./scripts/checkpatch.pl your.patch
对于刚才生成的补丁,我们会得到如下错误:
WARNING: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#10:
在core.c第193行,代码行超过了80个字符,并且与上一行没有正确的对齐,因此应该删除其多余的前导TAB键。本补丁删除这些多余的TAB键以满足代码格式规范。
total: 0 errors, 1 warnings, 8 lines checked
错误在于:补丁描述行太长了,应当折行,使每一行低于75个字符。我们再次使用如下命令提交补丁:
git commit -a
在提交的时候,注意修改补丁描述,使其满足格式规范。反复制作补丁并使用checkpatch.pl检查其正确性,直到消除了所有警告为止。当然,极个别的警告是允许存在的。
使用checkpatch.pl仅仅能检查格式规范方面的错误。但是一个正确的补丁远不止格式正确这么简单。它还应该满足如下要求:
1、一般情况下,同一个补丁只修改同一个模块的代码。
如果必须要同时修改多个模块中的代码,那么应该由所有模块的Maintainer同意,并确定由其中某一个Maintainer合入补丁。这种情况仅仅是特例。
但是怎么确定某个文件属于哪一个模块?您应当查看MAINTAINERS文件,里面有一个例子:
内核同步与互斥
M: Baoyou Xie <baoyou.xie@aliyun.com>
L: kernel@dim-sum.cn
T: git https://code.csdn.net/xiebaoyou/hot-pot.git core/locking
S: Maintained
F: kernel/locking/
可以看出:kernel/locking目录下的所有代码均属于“内核同步与互斥”模块。
2、同一个补丁仅仅解决一个独立的问题。
不要试图在同一个补丁中解决多个问题。例如,既消除一个编译警告,又整理一行代码。
小问题1.9:但是,消除编译警告,以及整理代码,都仅仅修改了一行代码,并且位于同一个文件之中,也不能将它制作到同一个补丁中?如果不能,请告诉我正确的做法。
3、同一个补丁必须完整的解决一个问题。
换句话说,不能将一个问题分拆到多个补丁中去。正如前一个例子所述,需要在一个补丁中将整个模块的格式全部整理完毕。如果补丁太大,可以考虑每个补丁整理其中一个文件。
4、补丁不要太大,但这不是一个强制要求遵循的规则。
一般来说,一个补丁修改的代码行数,不要超过200行。不过此规则比较灵活。如果一个单独的问题确实需要修改超过200行代码,那么就突破这个规则吧。
要制作一个正确的补丁,还有一个问题比较重要:补丁的标题和描述。
补丁第一行是标题,它首先应当是模块名称。
但是我们怎么找到kernel/sched/core.c文件属于哪个模块?
可以试试下面这个命令,看看kernel/sched/core.c文件的历史补丁:
root@ThinkPad-T440:# git log kernel/sched/core.c
commit 0521afdc65cec3265827f68d637ed7d8b07061db
Author: Baoyou Xie <baoyou.xie@aliyun.com>
Date: Mon May 21 14:53:49 2018 +0800
调度:整理代码格式
在core.c第193行,代码行超过了80个字符,并且与上一行
没有正确的对齐,因此应该删除其多余的前导TAB键。
本补丁删除这些多余的TAB键以满足代码格式规范。
可以看到,kernel/sched/core.c文件所在的模块名称是“调度”。
其中第一行是标题,在模块名称后面是补丁标题,应当简洁,清楚的说明补丁的内容。当然,标题可以超过80个字符。
随后的内容是补丁描述符,要清楚的描述:
1、为什么要制作这个补丁
2、这个补丁是如何实现的
当然了,模块的Maintainer可能对补丁描述要额外的要求,您可能也有需要特殊说明的地方,都可以补充在描述中。这有点象写作文,既要求条理清楚,又没有成规。
1.4.5. 发送补丁
在发送补丁前,我们需要用脚本再次检查一下补丁,确保其正确:
./scripts/checkpatch.pl your.patch
如果想要一次性生成并发送多个补丁,可以使用如下命令生成补丁:
git format-patch -s -v1 HEAD~2
在作者的环境中,上述命令生成了两个补丁:
v1-0001-DIM-SUM-Good-Start.patch v1-0002-.patch
然后用checkpatch.pl检查这两个补丁:
./scripts/checkpatch.pl v1-*.patch
一切无误,可以使用准备将补丁发送给Maintainer了:-)
但是应该将补丁发给谁?这可以用get_maintainer.pl来查看:
root@ThinkPad-T440:# ./scripts/get_maintainer.pl v1-*.patch
"GitAuthor: Baoyou Xie" <baoyou.xie@aliyun.com> (authored:2/1=100%,added_lines:522/522=100%,removed_lines:1/1=100%)
接下来,可以用git send-email命令发送补丁了:
git send-email v1-*.patch --to baoyou.xie@aliyun.com --cc baoyou.xie@aliyun.com
需要注意分辨,哪些人应当作为邮件接收者,哪些人应当作为抄送者。在本例中,补丁是属于实验性质的,可以不抄送给邮件列表帐户。
提醒:您应当将补丁先发给自己,检查无误后再发出去。如果你有朋友在Linux社区有较高的威望,有补丁走查的经验,或者深度参与DIM-SUM的开发,那么也可以抄送给他,必要的时候,也许他能给您一些帮助。这有助于将补丁顺利的合入DIM-SUM。
重要提醒:本章讲述的,主要是实验性质的补丁,用于熟悉提交补丁的流程。真正重要的补丁,可能需要经过反复修改,才能合入DIM-SUM。并且,这需要您反复阅读本书后面章节中,对DIM-SUM内核的代码分析。最重要的一点,是需要您对DIM-SUM代码的熟练掌握。
1.5. 获得帮助
如果您在下载源码、搭建环境、调试、提交补丁的过程中,遇到问题,可以通过如下途径获得帮助:
1.通过git更新源码,并关注根目录下hot-pot.readme文件了解最新的帮助方式
3.关注作者的博客:http://blog.chinaunix.net/uid/25845340.html
4.您也可以向baoyou.xie@aliyun.com发邮件来获得帮助
1.6. 提醒
作者尽量将本书写得通俗易懂,以方便初学者入门。但是,要真正深入的理解任何一门学问,都需要花费大量的时间,做大量身体力行的练习,并且深入思考。因此,本书会提出一些让读者深入思考的小问题。这些小问题值得您在多次阅读本书后,认真回答。如果您真的想急切知道答案,请阅读附录中的答案。但是作者仍然提醒您,不要试图直接翻阅答案。我阅读了不少技术书籍,真正优秀的书都注重激发读者思考的习惯。
以上是关于《DIM-SUM操作系统详解--迈向工业级服务器系统》样章----准备工作的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 远程 RAC 打造双活数据中心 | 从容灾迈向双活案例分享