歡迎光臨
每天分享高質量文章

《DIM-SUM作業系統詳解–邁向工業級伺服器系統》樣章(1)—-準備工作

 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的存在,但是實在找不到一臺可以正常安裝使用LinuxPC。因此只能閱讀相關的原始碼分析書籍而不能動手實踐。

在浮躁的年代,談論夢想可能一件不合時宜的行為。然而有什麼辦法呢?這畢竟真的是20年前的夢想,難道您想讓我撒謊?

3、開源軟體運動,已經為我們實現作業系統提供了現實可能性。首先,象Linux這樣的開源作業系統為我們提供了很好的基礎,這樣我們可以從開源軟體中學習到不少的技能、方法、設計思路。其次,開源軟體允許分散在各地的開發者協同工作,集思廣益的開發作業系統。作者在Linux社群中,作為ARM/ZTE ARCHITECTUREMaintainer,對此深有體會。

4、作業系統是IT行業的核武器。到目前為止,我們還處於缺芯少魂的狀態,其中的就是作業系統。真正核心的軟體,需要一代人,甚至幾代人耐心的雕琢,而不能寄希望於短時間內產生立竿見影的效果。換句話說,要有板凳一坐十年冷的心態來做這件事。有了這樣的心態,就不會覺得難。

5、從另一個角度來說:萬古長空,一朝風月。任何難事,一旦想要去做,就需要把握當下。空談誤國,實幹方能興邦。即使這件事情很難,但是不動手永遠不會有任何結果。況且,作者喜歡有挑戰性的事情,例如:寫一個工業級伺服器作業系統🙂

目前,DIM-SUM已經實現瞭如下功能

1arm 64 qemu小系統,含記憶體、時鐘初始化。

2、全域性優先順序排程模組,排程演演算法類似於Linux實時排程。

3、記憶體管理模組,包含頁面管理、beehive分配器。

4相容linux ext3LEXT3檔案系統

5塊裝置層實現。

6、集成了LWIP網路協議棧。

7、移植了常用的核心態CAPI

8、實現了一個粗糙的命令控制檯。

總之,作者認為HOT-POTDIM-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

關於DIM-SUM作業系統的新訊息,我也會透過部落格釋出,地址是:

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.64PC,透過如下連結下載

http://old-releases.ubuntu.com/releases/16.04.3/ubuntu-16.04-desktop-amd64.iso

2.32PC,透過如下連結下載

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”。該網絡卡用於虛擬機器與物理機的檔案共享連線。

網絡卡2”標簽介面中,選擇啟用網路連線,併在連線方式中選擇網路地址轉換(NAT)”該網絡卡用於虛擬機器與網際網路的連線。後面我們將會看到,無論是安裝軟體包,還是透過git下載程式碼,都需要連線到網際網路。

第二步,啟動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

其中enp0s3是作者建立的虛擬機器中的內網網絡卡,用於虛擬機器與主機之間的通訊,在您的機器上可能是其他名稱,請註意調整。192.168.0.98是該網絡卡的地址,請根據您的實際配置進行調整。

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-SUMHOT-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開發環境了。在此,作者假設您已經安裝好Linuxgit。這裡推薦兩份比較好的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-urlDIM-SUM分支的URL路徑。

隨時可以使用如下命令更新分支程式碼:

git fetch tag-name

隨著DIM-SUM的發展,不同的模組會有不同的Maintainer來維護。這些Maintainer會有自己的程式碼分支。可以在DIM-SUM原始碼目錄\MAINTAINERS檔案中,找到相應檔案的維護者,及其git地址。

MAINTAINERS檔案的格式與Linux類似。例如,Linux核心中,watchdog模組的資訊如下:

WATCHDOG DEVICE DRIVERS

M:      Wim Van Sebroeck 

R:      Guenter Roeck 

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

其中,git://www.linux-watchdog.org/linux-watchdog.git是其git地址。

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的第192193行,其程式碼看起來如下:

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 

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.c193行,程式碼行超過了80個字元,並且與上一行沒有正確的對齊,因此應該刪除其多餘的前導TAB鍵。本補丁刪除這些多餘的TAB鍵以滿足程式碼格式規範。

 

Signed-off-by: Baoyou Xie 

 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.c193行,程式碼行超過了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 

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 

Date:   Mon May 21 14:53:49 2018 +0800

 

    排程:整理程式碼格式

    

    在core.c193行,程式碼行超過了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”  (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檔案瞭解最新的幫助方式

2.關註作業系統駭客公眾號並留言

3.關註作者的部落格:http://blog.chinaunix.net/uid/25845340.html

4.您也可以向baoyou.xie@aliyun.com發郵件來獲得幫助

1.6. 提醒

作者儘量將本書寫得通俗易懂,以方便初學者入門。但是,要真正深入的理解任何一門學問,都需要花費大量的時間,做大量身體力行的練習,並且深入思考。因此,本書會提出一些讓讀者深入思考的小問題。這些小問題值得您在多次閱讀本書後,認真回答。如果您真的想急切知道答案,請閱讀附錄中的答案。但是作者仍然提醒您,不要試圖直接翻閱答案。我閱讀了不少技術書籍,真正優秀的書都註重激發讀者思考的習慣。

【終南山.核心問道】Linux故障分析方法(上)

【終南山.核心問道】Linux故障分析方法(中)

【終南山.核心問道】Linux故障分析方法(下)

贊(0)

分享創造快樂