본문 바로가기

IT

우분투 16.10(알파) 시스템에서 amd64 커널(stock kernel source) 컴파일하기

4월에 우분투 리눅스 16.10이 알파 버전 꼬리도 달기 전에 일찍감치 업데이트한 직후 가장 난감한 문제가 변화한 컴파일 환경에서 gcc-5나 gcc-6으로 리눅스 커널, 버츄얼박스 등 커널 모듈을 포함하는 써드 파티 패키지를 컴파일할 수가 없더군요. 문제가 있다는 글은 올라왔지만 뚜렷한 해법은 없던 상태였습니다. 그 뒤 커널이나 버츄얼박스 '-no-pie', '-fno-pie' 플랙을 포함하거나 데비안 rules 파일에서 하더닝(Hardening) 정책을 수정하여 그 문제를 풀었다는 것은 알 수 있었습니다.
그런데, 우분투 커널 소스가 아니라 커널 사이트에서 최신 커널이나 개발자 커널을 내려받아 컴파일할 때는 수동으로 패치를 적용해야 하는데 우분투 커널 소스에서는 이걸 찾기 어렵더군요. 우분투 커널 소스는 내려받으면 보통 패키지처럼 모든 소스가 풀리는 게 아니라 그 속에 debian, debian.master 디렉토리와 커널 소스 압축 파일만 들어 있어서 파악하기 어렵습니다.
해서 한참 찾아보다가 여기 링크한 페이지 맨 아래에 나오는 패치를 복사해서 편집기(vim) 안에 붙여넣은 뒤 패치 파일로 만들어 적용하니 컴파일이 제대로 되었습니다.(현재 사용하는 커널은 4.7-rc4인데 지금 4.7-rc5도 같은 방법으로 컴파일하고 있습니다. 커널 소스 Makefile에 변화가 생기면 패치 파일을 새로 만들어야 할 수도 있겠지만 지금까지는 별 문제 없습니다.

(2016.07.02. 16:45 추가)
써드 파티 커널 모듈 - 여기서는 D-Llink 802.11ac 와이파이 드라이버(USB 3.0 지원, 통신사에서 사은품으로 받은 것으로 테스트용) git 소스에서 Makefile에 EXTRA_CFLAGS와 EXTRA_LDFLAGS를 유사하게 추가한 뒤 컴파일하면 커널 모듈 8812au.ko를 만들 수는 있지만 아래와 같은 경고가 나타납니다.

cd /home/git/rtl8812AU_8821AU_linux
$ make
make ARCH=x86_64 CROSS_COMPILE= -C /lib/modules/4.7.0-rc4/build M=/home/git/rtl8812AU_8821AU_linux  modules
make[1]: Entering directory '/home/build/linux-4.7-rc4'
arch/x86/Makefile:133: stack-protector enabled but compiler support broken
Makefile:668: Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: -fstack-protector not supported by compiler
...
$ ls 8812au.ko
8812au.ko
$

(2016.07.02. 18:10 추가)
앞서 언급한 에러나 경고는 4.7-rc4 커널 소스가 제대로 패치되지 않은 게 제가 patch 적용 전 '--dry-run' 아규먼트를 써서 테스트해보고는 실제로는 적용하지 않았던 것으로 나타납니다. 조금 전 4.7-rc5 커널 컴파일 완료 후 부팅해서 확인해보니 여기에서는 제대로 적용되어 있습니다. 그러니 아래 패치는 최신 개발자 커널 소스에도 그대로 적용할 수 있습니다. 이 상태에서 써드 파티 커널 모듈의 Makefile에 'EXTRA_CFLAGS=-fno-pie', 'EXTRA_LDFLAGS='-no-pie' 등을 추가한 뒤 모듈을 컴파일하고 설치하면 됩니다.
좀 이상한 건, 4.7-rc4 커널 소스에는 no-pie 패치가 적용되지 않았는데 어떻게 컴파일해서 설치할 수 있었는지입니다. 최근 gcc-5가 5.4.0-5ubuntu1으로, gcc-6이 6.1.1-8ubuntu11로 업데이트되었는데 이것과 연관이 있는지도 모르겠습니다. 나중에 no-pie 패치를 적용하지 않고 테스트해보아야 겠습니다.
오늘 일시적 폭우 설거지하랴 이 문제에 골몰하느라 이래저래 헷갈리는군요. ^^

(2016.07.03 10:10 추가)
엊저녁에 테스해보니 이 no-pie 패치를 적용하지 않으면 우분투 16.10(알파) 시스템에서 4.7-rc4 커널 소스를 컴파일할 수 없었습니다. 불가사의지만 이건 통과... 그리고 커널 소스에 no-pie 패이를 적용하고 나면 8812au 모듈 소스의 Makefile은 건드릴 필요없습니다.
다만 우분투의 8812au 소스 패키지가 2015년 11월 이후 업데이트되지 않아 낡았으며 dkms 형태로 되어 있어서 그걸 손보느니 올해 6월 하순까지 업데이트되어 온 git 소스를 바로 컴파일하는 게 편해서 그렇게 했습니다. 4.7 개발자 커널에서도 문제 없습니다. readme.md 파일에 적힌 대로 하면 dkms를 통해 컴파일하고 설치할 수도 있습니다.

[yakkety,RFC,v1] disable -pie when gcc has it enabled by default
Submitted by Steve Beattie on April 29, 2016, 6:33 a.m.
...
From: Steve Beattie

In Ubuntu 16.10, gcc's defaults have been set to build Position
Independent Executables (PIE) on amd64 and ppc64le (gcc was configured
this way for s390x in Ubuntu 16.04 LTS). This breaks the kernel build on
amd64. The following patch disables pie for x86 builds (though not yet
verified to work with gcc configured to build PIE by default i386 --
we're not planning to enable it for that architecture).

The intent is for this patch to go upstream after expanding it to
additional architectures where needed, but I wanted to ensure that
we could build 16.10 kernels first. I've successfully built kernels
and booted them with this patch applied using the 16.10 compiler.

Patch is against yakkety.git, but also applies with minor movement
(no fuzz) against current linus.git.

Signed-off-by: Steve Beattie

...