OS/Linux

Ubuntu 16.04, 기본 설정에서의 Kernel Compile.

TechNote.kr 2016. 7. 7. 18:29
728x90

  지난 4월 26일자로 Ubuntu 16.04가 release 되었다. 

사실 Linux kernel compile에 있어서 Ubuntu 의 버전은 그다지 상관은 없지만, 나온지 얼마되지 않은 Ubuntu 16.04에서 Linux kernel compile할 일이 있어, 설치해야할 package등 정리하면서 작성해 보았다. 

시행착오 과정까지 모두 적은지라 결론만 보고 싶으신 분들은 제일 마지막 부분만 참고 하셔도 될 것 같다.


Linux kernel compile on Ubuntu 16.04


참고로 build에 사용된 Ubuntu 16.04는 Ubuntu.com에서 iso 다운로드 받고서 설치한 직후의 상태라 별다르게 설치된 package는 없는 상황이었다. 

 현재 사용하고 있는 Ubuntu 16.04와 동일한 설정의 Kernel 을 Compile한 후 내가 원하는 부분만 수정해볼 계획이어서 우선 현재 돌아가고 있는 Kernel 의 설정을 적용하고, 빌드하는 것이 이 글에서의 목적이 되겠다. 


1. Ubuntu 16.04의 Kernel Source 확보를 위한 Package List 설정 변경

 Kernel Source Code는 kernel.org에서도 구할 수 있지만 Ubuntu 16.04를 위해서 변경된 내용도 있기 때문에 소위 말하는 vanila kernel code는 받지 않고, package 서버에서 다운로드 받을 예정이다. package 서버 설정이 기본적으로 source code는 다운로드 받지 않도록 되어 있어 source code도 받을 수 있도록 설정을 변경해 주어야 한다. 

1-1) 왼쪽 ICON 메뉴에서 Ubuntu Software를 실행한다. 

1-2) 실행 후 상단 메뉴에서 Software & Updates 를 선택해 설정 화면이 나오도록 한다.

1-3) 설정 화면에서 체크가 해제되어 있는 "Source code" 항목을 선택한다. 선택하면 - 모양의 체크가 되게 된다.

1-4) 선택하게 되면 package list 가 바뀌므로 새롭게 업데이트하라는 팝업이 발생하게 되고, 업데이트를 진행하면 된다.


2. Ubuntu 16.04 Linux Kernel Source Code Download

위와 같이 Package Server List를 갱신하게되면 이제 Kernel Source Code도 apt-get 명령어를 통해 다운로드 받을 수 있게 된다.

# apt-get source linux-image-$(uname -r)

위의 명령어를 실행하게 되면 현재 돌아가고 있는 버전을 `uname -r`을 통해 확인하게 되고, 해당 버전의 Kernel Source Code를 명령어를 실행한 디렉토리 바로 밑에 다운로드하게 된다.

무결성(?) 체크하는 루틴에서 에러를 보이기도 하지만 실제적으로 빌드시에는 문제가 없어 큰 의미를 갖지 않아도 될 것 같다. 

아래와 같이 현재 디렉토리 밑에 linux-4.4.0 이라는 디렉토리가 생성된 것을 확인할 수 있다. 

3. 현재 돌고 있는 kernel 의 설정을 복사해 적용하고, Kernel compile하는 명령어인 make-kpkg 을 실행한다. 복사는 정상적으로 이루어졌으나 make-kpkg는 설치가 되어 있지 않아 동작하지 않는다.

~/linux-4.4.0# cp /boot/config-4.4.0-21-generic .config

4. apt-get 을 이용해 make-kpkg 명령어를 포함하고 있는 kernel-package를 설치해준다. make-kpkg가 없으니 kernel-package를 설치하라는 문구가 인상적이다. 

# apt-get install kernel-package

kernel-package만 설치하려고 했는데 의존성이 생각보다 많은가 보다 "Y"를 눌러 모두 설치하자.

설치 도중에 위와 같이 선택해 주는 창이 뜨기도 하지만 그냥 Enter 쳐주면 넘어간다. 

5. 설치 후 make-kpkg 를 해보니 정상적으로 실행이 된다. 여기서 사용한 make-kpkg의 자세한 명령어는 다음과 같다.

# make-kpkg -j2 --initrd --append-to-version=--test-kernel kernel_image

-jN은 compile시의 cpu 갯수를 의미하는데 여기서는 cpu 2개여서 -j2로 하였다.

--append-to-version=--test-kernel 은 kernel 이름에 추가적으로 붙일 이름을 의미하는데 변경 후 정상 변경 여부를 확인하기 위해 --test-kernel 이라는 이름을 추가해 주었다.

kernel_image 는 해당 명령어를 통해 kernel image를 deb로 만들어 설치할 수 있는 package 형태로 output을 만들겠다는 것이다. 실행하면 아래와 같이 진행된다.

6. Kernel이 Compile되다가 fatal error를 발생시키면서 멈추는데 libssl-dev의 설치가 필요하다.

[Error]

scripts/sign-file.c:23:30: fatal error: openssl/opensslv.h: No such file or directory
compilation terminated.
scripts/Makefile.host:91: recipe for target 'scripts/sign-file' failed

[Command]

# apt-get install libssl-dev

7. ssl 관련 error들을 넘어가더라도 다음엔 VBox 관련 error들이 발생하게 된다. ubuntu 디렉토리 밑에 있는 파일들인 것을 보니 ubuntu kernel 에만 포함된 내용으로 추정된다. header 파일을 제대로 찾지 못해 발생하는 문제인데, 간단히 link만 걸어주면 해결된다.

[Error]

cc1: fatal error: ./ubuntu/vbox/vboxguest/include/VBox/VBoxGuestMangling.h: No such file or directory
compilation terminated.
scripts/Makefile.build:258: recipe for target 'ubuntu/vbox/vboxguest/VBoxGuest-linux.o' failed

[Command]

~/linux-4.4.0# cd ubuntu/vbox

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./r0drv/include

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./vboxsf/include

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./vboxguest/include

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./vboxvideo/include

비록 error는 vboxguest에서 발생하였지만 어짜피 다른데서도 발생하니 r0drv, vboxsf, vboxvideo에 대해서도 미리 symbolic link를 만들어두면 된다.

8. Symbolic link를 모두 걸어주고 다시 kernel build 명령어를 실행하면 또 다른 Error 가 발생한다. 

한번더 symbolic link를 걸어서 해결해주면 된다.

[Error]

make[4]: *** No rule to make target 'ubuntu/vbox/vboxguest/r0drv/alloc-r0drv.o', needed by 'ubuntu/vbox/vboxguest/vboxguest.o'.  Stop.

[Command]

~/linux-4.4.0# cd ubuntu/vbox/vboxguest

~/linux-4.4.0/ubuntu/vbox/vboxguest# ln -s ../r0drv/


9. 위의 Error까지 잡아내고 나면 아래와 같이 Kernel Compile이 모두 완료된다.

10. cd .. 해서 상위 디렉토리로 이동해 보면 아래와 같은 이름으로 kernel image deb package가 생성되어 있음을 확인할 수 있다. 

linux-image-4.4.13--test-kernel_4.4.13--test-kernel-10.00.Custom_amd64.deb

--test-kernel 이라는 이름이 포함된 것을 보니 내가 빌드해서 생성된 kernel image package가 맞는 것 같다. 하나 이상한 점은 받은 Source Code의 디렉토리 이름은 4.4.0 인데 빌드 결과물은 4.4.13이다. 좀 더 살펴보니 kernel source 와 같이 다운로드되는 diff file에서 버전을 바꾸고 있었다.

-SUBLEVEL = 0

+SUBLEVEL = 13

사실 Source Code를 다운로드 받기 위해서 했던 아래 명령어가 현재 시스템의 kernel version (uname -r)을 확인해서 동일한 kernel source code를 다운로드 받는 걸로 이해하고 있었는데 아무래도 잘못 알고 있었나 보다. (다시 해봐도 동일하다.)

# apt-get source linux-image-$(uname -r)

우선은 동일한 설정의 kernel 을 빌드하였으므로 해당 kernel 로 부팅을 해보면 다음과 같다.

11. 아래와 같은 명령어로 설치하면된다.

# dpkg -i linux-image-4.4.13--test-kernel_4.4.13--test-kernel-10.00-Custom_amd64.deb

 설치한다고 바로 kernel 이 적용되는 것은 아니다. uname -a 를 해보면 아직 이전의 것이 적용되어 있음을 알수 있다. 새로운 커널의 적용을 위해서는 재부팅을 해야 한다.

12. 재부팅을 하면 아래와 같이 변경되었음을 알 수 있다.

kernel version 명 안에 --test-kernel이 확인된다.


Kernel 설정의 변경


 기본 설정만으로 빌드하는 것은 이것으로 완료되었고, 이번에는 kernel defconfig를 변경해서 기존 설정과는 다른 커널을 만드는 방법을 알아보고자 한다. 

1. kernel 설정을 변경하기 위해서는 아래 명령어를 실행한다. 

# make menuconfig

2. 하지만 Error가 발생한다.

[Error]

scripts/kconfig/lxdialog/dialog.h:38:20: fatal error: curses.h: No such file or directory
compilation terminated.
scripts/Makefile.host:108: recipe for target 'scripts/kconfig/mconf.o' failed

[Command]

# apt-get install libncurses5-dev


3. 이제는 make menuconfig를 하면 정상적으로 kernel defconfig를 수정할 수 있는 화면이 나오게 된다. 여기서 체크를 하고 빌드는 위에 가이드했던 방법대로 진행하면 된다.


Ubuntu kernel compile 정리


1. Ubuntu 16.04의 Kernel Source 확보를 위한 Package List 설정 변경 in Ubuntu Software

2. 기존 설정 복사

~/linux-4.4.0# cp /boot/config-4.4.0-21-generic .config

3. kernel compile을 위한 package 설치

# apt-get install kernel-package

# apt-get install libssl-dev

# apt-get install libncurses5-dev

4. Ubuntu kernel Code 내 깨진 symbolic link 생성

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./r0drv/include

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./vboxsf/include

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./vboxguest/include

~/linux-4.4.0/ubuntu/vbox# ln -s ../include ./vboxvideo/include

~/linux-4.4.0/ubuntu/vbox/vboxguest# ln -s ../r0drv/

5. make-kpkg 를 통한 kernel image package 생성

# make-kpkg -j2 --initrd --append-to-version=--test-kernel kernel_image

6. 생성된 package 설치

# dpkg -i linux-image-4.4.13--test-kernel_4.4.13--test-kernel-10.00-Custom_amd64.deb

7. 재부팅


 사실 일반 사용자의 경우 Linux 를 쓸 상황도 별로 없고, Linux를 쓰더라도 kernel 개발자가 아니라면 kernel compile을 할 일은 더더욱 없을 것이다. Linux의 경우 Windows와 달리 이렇게 kernel 도 개인이 compile해서 사용할 수 있다는 정도만 이해하면 좋을 것 같다.


8. Kernel module build


# make -C $(pwd) M=$(pwd)/net/wireless modules 

728x90