---
# System prepended metadata

title: 提交第一份 Patch 到 Linux Kernel
tags: [Linux Kernel]

---

---
tags: Linux Kernel
---

# 提交第一份 Patch 到 Linux Kernel
contributed by < [steven1lung](https://github.com/steven1lung) >


## 我自己的心得
在看老師的書 Demystifying the Linux CPU Scheduler 的時候，突然好奇說每一個任務的 loading 是如何運算的，畢竟排程器上的任務如此多，計算出 load 然後依據每個 CPU 的狀態去做 task migration 應該是很重要的課題。所以我就跑去 [pelt.c ](https://elixir.bootlin.com/linux/latest/source/kernel/sched/pelt.c) 看了一下實際的運算是如何做到的。

> pelt 全名是 Per Entity Load Tracking

在看程式碼的時候，發現有個地方的中括號打反了變成 `[1002..1024[`，我就想說試試看發人生第一個 patch。

結果自己在摸索如何發 patch 花了好多時間...，轉眼間就早上了。所以就記錄了一下自己發 patch 的過程來紀念逝去的時間。雖然這個 patch 最後是我誤會中括號的用法，所以並沒有被採納，但跟這些厲害的人交流讓人有點興奮><
> 結果發現反過來的中括號是法文的用法，是我自己搞錯 xD


我發的 patch 在[這裡](https://lore.kernel.org/lkml/3193fcc9-c672-19d9-a2e2-ad67809dd20b@infradead.org/T/)。


## 前言 

Linux Kernel 的開發跟維護方法是透過信件來溝通跟 review，Linux Kernel 有一個龐大的 mail server，每天收到近千個信件提交 patches，格式不正確或是表達不好的 patch 很常會被忽略，連回覆都不會有，所以要如何寫好一個好的 patch 充滿學問。

> “Only wimps use tape backup. REAL men just upload their important stuff on ftp and let the rest of the world mirror it.” --Linus Torvalds



## 準備提交 Patch 會使用到的 Email Client
* git send-email
* mutt 

git 其實就有提供一個命令：`git send-email` 來做到發出信件的功能，或是也有很多人會使用 `mutt` 來幫忙發 plain text mail。我自己是 send patches 時會使用 `git send-email`，如果只是回覆 comment 之類就會用 mutt。
> 這邊要小心如果回覆 patch 的 comment 的時候使用 gmail 或是手機內建的信箱，要記得信件不要使用到 html，會被 lkml 認為是 spam 或病毒，就會被退回。

### git send-email
使用之前還需要到 `~/.gitconfig` 裡先設定一些 smtp 的資料：

```
$ vi ~/.gitconfig
```

然後在最後面加上：
```
[sendemail]
        smtpencryption=tls
        smtpserver=smtp.gmail.com
        smtpuser=你的信箱@xxxx.com
        smtpserverport=587
        smtpPass=你的APP密碼   
```
> APP 密碼的設定方式在下面有說明。
### mutt
mutt 是一個很多開發者都會使用到 mail client，Greg Kroah-Hartman 也是使用這個！他也有在網路上分享自己的 workflow，詳情可以看[這裡](http://kroah.com/log/blog/2019/08/14/patch-workflow-with-mutt-2019/)。

mutt 並不是內建的，所以事先需要安裝：
```
$ sudo apt install mutt # Debian 
$ sudo dnf install mutt # Fedora
$ brew install mutt # Macos
```
接著一樣要去設定一些 smtp 的參數：
```
$ vi ~/.muttrc
```
把以下的資料填好並且儲存：
```
set ssl_starttls=yes
set ssl_force_tls=yes
set imap_user = "你的信箱@XXXX.com"
set imap_pass = "你的APP密碼"
set from="你的信箱@XXXX.com"
set realname="FIRST_NAME LAST_NAME"
set folder = "imaps://imap.gmail.com/"
set spoolfile = "imaps://imap.gmail.com/INBOX"
set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
set header_cache = "~/.mutt/cache/headers"
set message_cachedir = "~/.mutt/cache/bodies"
set certificate_file = "~/.mutt/certificates"
set smtp_url = "smtps://你的信箱@XXX.com:你的APP密碼@smtp.gmail.com:465/"
set record="~/mail/sent"
set move = no
set imap_keepalive = 900
```


### App 密碼設定
因為我信箱是使用 gmail，這邊就放我是如何設定 gmail 的。其中 `你的APP密碼` 需要到 gmail 裡面設定一個給應用程式的密碼，步驟如下：
> https://support.google.com/mail/answer/185833?hl=en
1. 開啟 google 的 2FA 認證
    > 到 [這裡](https://myaccount.google.com/security?rapt=AEjHL4Ma9vPuhKss9SEbsfcQQAYyuW0pwsA_mMKLb2w6XyJJucvD-5MgBKAW5_O8KOD4tnetMuUtSxfGiGvzFqhnkC-wnUkwpA) 的 「登入 Google」點選兩步驟驗證，並且完成設定。
2. 建立應用程式密碼
    > 「開啟兩步驟驗證」的下方有一個「應用程式密碼」，點進去後選擇「郵件」跟「其他」，名字就取一個自己會認得的就可以，完成後會顯示密碼，複製貼到 `.gitconfig` 或是 `.muttrc` 就可以了。

## 在本地端建立一個 Repo
如果直接去 github 上 clone 會花很長的時間，這裡我是到 [release](https://github.com/torvalds/linux/tags) 找最新的檔案下載，之後再解壓縮就好了。

這裡舉我下載的 `linux-5.19-rc1.tar.gz` 為例，載完後將檔案解壓縮到想要開發的目錄下：
```
$ tar -zxvf linux-5.19-rc1.tar.gz
```
之後就可以進去設定 git：
```
$ cd linux-5.19-rc1
$ git init
$ git add .
$ git commit -m "origin"
$ git checkout -b my-patch
```
> 如果是第一次使用 git 也要記得先`git config` 設定一下名字跟信箱喔！

之後就可以進行修改了！

## Commit Message
完成自己的修改後就可以新增 commit：
```
$ git commit -asv
```
-a：加入剛剛修改並且有 track 的檔案
-s：commit 會加上 `Signed-off-by: <你的名字> <你的信箱@XXX.com>`
-v：verbose，會列出你的修改，看著寫 commit message 會比較方便

### commit message 格式
Patch 的格式都有嚴格的限制，沒有寫過的同學可以去看你編輯的檔案之前 commit 是如何寫的比較有概念。

簡單來說就是會分成：標題、內容描述、自己的簽名，中間都會空一行：
```
subsystemName: short description
# blank line
patch content description
# blank line
Signed-off-by: "name" <email>
```

## 建立 Patch
完成 commit 就可以建立等等要寄出去的 patch 了：
```
$ git format-patch master
```
建立好的 patch 要先通過一些 scripts 裡面的檢查：
```
$ ./scripts/checkpatch.pl ./patch_name.patch
```
如果你的 patch 有問題，會有提示訊息跟你說是哪裡需要修改，修改完後可以使用：
```
$ git commit -a --amend
$ git format-patch master
```

## 寄送 Patch
接著就要找出 maintainer 是誰，並且將 patch 寄給他，這邊舉修改 docs 為例：
```
$ ./scripts/get_maintainer.pl ./patch_name.patch

Jonathan Corbet <corbet@lwn.net> (maintainer:DOCUMENTATION)
linux-doc@vger.kernel.org (open list:DOCUMENTATION)
linux-kernel@vger.kernel.org (open list)
```
從輸出就可以看到要寄給的人了，通常裡面的人都會要 CC 到。

使用 `git send-email`：
```
$ git send-email --to corbet@lwn.net \
--cc linux-doc@vger.kernel.org \
--cc linux-kernel@vger.kernel.org \
./patch_name.patch
```

使用 `mutt`：
```
$ mutt -H ./patch_name.patch
```

## 後續
之後就可以到 [lkml.org](https://lkml.org/) 看看有沒有出現你的 patch 了，靜靜等待 review 就好了。


### 後記
之後在看 UML (User Mode Linux) 的時候找到一個錯字，也順手送了一個 patch 過去，document 的維護者 Jonathon 還恭喜我發送第一個 kernel patch，人真的很好 xD
> Jonathon 的[回覆](https://lore.kernel.org/all/20220621072910.4704-1-1030steven@gmail.com/t/)