quilt는 여러 개의 패치를 스택(stack) 형태로 관리하는 도구다.
각 패치는 순서대로 쌓이며, 위에 있는 패치가 아래 패치의 변경 내용을 기반으로 동작한다.
커널 개발에서 quilt를 쓰는 이유는 명확하다.
- 패치 단위로 작업을 나눌 수 있음
- upstream rebase 시 충돌 정리가 쉬움
- Yocto, BSP 환경에서 사실상 표준처럼 사용됨
- git을 쓰지 않는 빌드 환경에서도 패치 관리 가능
이 글에서는 커널 소스 트리에서 특정 소스 코드를 수정하고, 그 변경을 패치로 관리하는 과정을 예제로 다룬다.
먼저 기본 quilt 사용법에 대해서는 다음글을 참조한다.
1. 커널 소스 준비
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
- 최신 커널 소스를 clone한다.
quilt은 Git과 별개로 패치를 관리하므로, Git 브랜치와 병행해 사용할 수 있다.
2. quilt 초기화
quilt init
.pc/디렉터리가 생성되어 패치 관리 환경이 준비된다.
일반적인 커널 소스 트리에서 quilt를 쓸 때 구조는 다음과 같다.
linux/
├── arch/
├── drivers/
├── include/
├── kernel/
├── patches/
│ ├── series
│ ├── 0001-mm-fix-xyz.patch
│ └── 0002-sched-add-debug.patch
└── .pc/
patches/series: 패치 적용 순서를 정의.pc/: quilt 내부 메타데이터 (자동 생성)
보통 환경변수로 위치를 지정한다.
export QUILT_PATCHES=patches
3. 패치 디렉터리 생성 및 series 파일 준비
패치 디렉터리 생성 및 series 파일 준비한다.
mkdir -p patches
touch patches/series
export QUILT_PATCHES=patches
현재 상태 확인
quilt series
quilt applied
quilt unapplied
4. 새 패치 생성
예를 들어 페이지 캐시 디버그 로그를 추가하는 패치를 만든다고 가정한다.
quilt new 0001-mm-add-pagecache-debug.patch
- 이 시점부터 수정되는 파일은 이 패치에 포함됨
- 아직 어떤 파일도 추적되지 않음
5. 패치에 파일 추가
수정할 파일을 quilt에 등록한다.
quilt add mm/filemap.c
이제 이 파일을 수정하면 변경 내용이 패치에 기록된다.
4. 실제 커널 코드 수정
/* mm/filemap.c */
pr_debug("pagecache: index=%lu\n", index);
수정 후 상태 확인
quilt diff
출력 예시:
$ quilt diff
Index: linux/mm/filemap.c
===================================================================
--- linux.orig/mm/filemap.c
+++ linux/mm/filemap.c
@@ -962,6 +962,8 @@ int filemap_add_folio(struct address_spa
if (ret)
return ret;
+ pr_debug("pagecache: index=%lu\n", index);
+
__folio_set_locked(folio);
ret = __filemap_add_folio(mapping, folio, index, gfp, &shadow);
if (unlikely(ret)) {
5. 패치 갱신(refresh)
작업이 끝났으면 패치를 실제 파일로 반영한다.
quilt refresh
이제 patches/0001-mm-add-pagecache-debug.patch 파일이 생성된다.
6. 다음 패치 쌓기
이제 스케줄러 관련 로그 패치를 추가해 보자.
quilt new 0002-sched-add-runqueue-log.patch
quilt add kernel/sched/core.c
코드 수정:
quilt diff
Index: linux/kernel/sched/core.c
===================================================================
--- linux.orig/kernel/sched/core.c
+++ linux/kernel/sched/core.c
@@ -2080,6 +2080,8 @@ unsigned long get_wchan(struct task_stru
void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
{
+ pr_info("rq=%d task=%s\n", cpu, p->comm);
+
if (!(flags & ENQUEUE_NOCLOCK))
update_rq_clock(rq);
반영:
quilt refresh
7. 패치 이동 (push / pop)
패치 스택을 위아래로 이동할 수 있다.
quilt pop # 현재 패치 제거
quilt push # 다음 패치 적용
quilt push -a # 모든 패치 적용
quilt pop -a # 모든 패치 제거
이 기능 덕분에 특정 패치만 빼고 테스트하는 것이 매우 쉽다.
8. 패치 수정 (이미 refresh한 경우)
이미 만들어진 패치를 다시 수정하고 싶을 때
quilt push 0001-mm-add-pagecache-debug.patch
quilt add mm/filemap.c
코드 재수정 후
quilt refresh
quilt는 기존 패치를 덮어쓴다.
9. 패치 순서 변경
patches/series 파일을 직접 수정한다.
0001-mm-add-pagecache-debug.patch
0002-sched-add-runqueue-log.patch
순서를 바꾼 뒤
quilt pop -a
quilt push -a
10. quilt + Yocto / BSP 실전 팁
1) 커밋 단위 == 패치 단위
- 기능 / 버그 / 실험 로그를 절대 섞지 말 것
2) upstream rebase 대비
- 하나의 패치에 너무 많은 파일을 넣지 말 것
- 충돌은
quilt push시점에 바로 드러남
3) git과 병행 사용
- 개발은 git
- 배포·빌드는 quilt
git format-patch→ quilt로 관리하는 방식이 가장 안정적
quilt vs git 간단 비교
| 항목 | quilt | git |
|---|---|---|
| 패치 스택 | 매우 직관적 | 상대적으로 복잡 |
| BSP/Yocto | 사실상 표준 | 보조 |
| 히스토리 관리 | 약함 | 강력 |
| rebase 감각 | 쉬움 | 숙련 필요 |
정리
quilt는 커널 패치 작업에 특화된 도구다.
- 패치 기반 개발
- BSP·Yocto 환경
- upstream 추적
- 실험적 커널 튜닝
이 네 가지 키워드가 보이면 quilt를 쓰는 것이 맞다.