본문 바로가기
기타/툴 관련(리눅스)

커널 컴파일

by WebHack 2009. 11. 13.

커널이란?

커 널이란 운영체제(Operating System)에서 가장 핵심적인역할인 자원 (메모리, 프로세서등)을 관리하며 시스템이 원활히 돌아갈 수 있도록 제어해 준다. 현재 우리가 리눅스(OS)라고하는것도 실제적으론 리눅스란 운영체제의 커널 이름을 말하는것인데 이것이 확장된 의미로 사용되어 현재의 '리눅스'란 OS를지칭하게도 된것이다. 그러므로 Linux = kernel이란 등식이 성립한다.

● 커널 컴파일은 언제 하나?
커널은 시스템을 운영하기 위한 가장 기본적인 코드가 포함되어 있어야 한다. 즉, 장치 혹은 시스템의 기능과 관련된 변화가 있을 경우 새로운 커널을 생성해야 한다. 현재 시스템은 어떠한 장치가 장착되어 있으며, 어떠한 목적으로 시스템을 운영할 것인가에 따라 커널의 구성요소가 달라질 수 있다는것을 의미하며, 현재 커널에는 어떠한 것들을 지원하는가에 대한 정보는 커널 소스 디렉토리에 존재하는 Documentation디렉토리에서 해당 정보를 얻을 수 있다. 만약 현재 시스템을 운영하기 위해 필요로 하는 장치에 대한 정보나 기능에대한 핵심 코드가 현재 커널에 존재한다면 굳이 커널을 업그레이드 하거나 새로 생성할 필요가 없다. 하지만 간혹 커널 자체에보안적 문제가 존재하기도 하는 데, 그러할 경우 꼭 커널 업그레이드를 해야한다.


● 커널은 어디서 구하나?
최신 버전의 커널을 www.kernel.org 에서 구할 수 있다.


● 커널 컴파일 방법
여러 가지 방법들이 있지만 저장된 커널 옵션 설정 파일이 있다면 oldconfig를 저장된 파일이 없다면 menuconfig를 추천한다.

make oldconfig 또는 make menucofig

make oldconfig를 하기위해선 다음과 같은 작업이 필요하다. 예전에 설정한 커널옵션이 kernel.config 란 이름으로 저장되어있다면 이 파일을 새 버전의 커널이 있는 /usr/src/linux 디렉토리에 .config란 이름으로 카피한다.
이 명령어는 새 버전의 커널이 있는 /usr/src/linux 디렉토리에서 하는 것이며, 대게의 경우 이전 버전의 설정파일 이름도 .config 이다.


● 모듈 컴파일 방법
모듈이 생성되는 디렉토리는 '/lib/modules/<커널버전>'이고 만약 현재 커널의 모듈을 다시 생성하려고 한다면 현재 커널의 모듈 디렉토리를 지우고 다시 컴파일 하기 바란다.

1. $make modules
2. $make modules_install


● Initrd 이미지 만들기
모듈을 만들고, 때에 다라서 initrd 이미지도 만들어줄 필요가 있다. (가령 ext2/3 vfs같은 fs를 모듈로 제작했을때) 그럴때엔 mkinitrd 를 사용하자.

$cd /lib/modules 해서 방을 옮긴후
$ls
해보면 2.X.X 식으로 나와있다. 2.X.X인지 정확히 기억해서 <커널버전>에 똑같이 넣어준다.

$mkinitrd /boot/initrd-<커널버전 혹은 원하는 이름>.img <커널버전>


●● 실제 컴파일 해보기
먼저 다운로드한 커널 소스를 /usr/src/ 디렉토리로 복사한다. 커널 컴파일은 /usr/src/<커널버전> 디렉토리에서 진행한다.

1. make mrproper : 이전의 컴파일시 설정되었던 설정을 제거
(최초 커널 컴파일시나 이전 설정한 컴파일 환경을 재사용한다면 생략 가능 )
2. make menuconfig : 텍스트 환경
혹은 make xconfig : x윈도우 환경
혹은 make oldconfig : 기존의 환경을 불러와서 새로운 것만 설정

3. make dep : 설정한 영역의 의존성 검사
4. make clean : 이전 컴파일시 생성된 파일을 삭제
( 4. 은 경우에 따라 생략할 수 있음 )

5. make bzImage : 설정한 기준으로 새로운 커널을 생성, 커널이 생성된 이후 생성된 커널을 커널이 위치해야 할 디렉토리(/boot)로 복사하는 과정은 관리자가 cp 명령어를 이용하여 직접 옮겨야 한다.
커널 생성시 또 하나의 파일(System.map)이 생성되며, 이 파일 또한 /boot로 복사한다.
$cp arch/i386/boot/bzImage /boot/<커널 버전>
$cp System.map /boot/System.map
6. mkinitrd : 이 문서 위의 "● Initrd 이미지 만들기" 참조
( 5,6의 과정은 make install을 수행하면 자동으로 수행된다. 단, make install은  "8.make modules_install"명령어 후에 실행해야 정상적으로 동작한다. 이 과정후 /etc/grub.conf의 설정이 올바르게 되었나 확인해 본다. )

7. make modules : 모듈들을 만든다. (시간이 좀 오래 걸린다. -_-)
※모듈 : 부팅시 메모리에 적재되는 것이 아니라 부팅 과정 이후 설정에 따라 혹은 해당 장치 혹은 기능을 사용할 경우에만 메모리에 올려서 사용한 후 사용하지 않을 경우 메모리에서 삭제하므로 효과적으로 메모리를 관리할 수 있다.

8. make modules_install : 만들어진 모듈들을 설치한다.
모듈이 위치할 디렉토리(/lib/modules/<커널버전>)으로 이동시켜주는 역할도 한다.
※커널 버전마다 지원하는 장치나 기능이 다르므로 모듈의 경우 /lib/modules 디렉토리에 해당 커널 버전 디렉토리를 생성하여 커널 버전별로 관리하게 된다.


● 이 모든 명령어 한번에 실행 시키기
이 모든 명령어들을 한꺼번에 줄 수도 있다.

$make bzImage modules modules_install install 과 같이 한번에 끝낼수도 있다.

그러나
$make bzImage && make modules && make modules_install && make install
과 같은 방법을 추천한다. 이는 전단계에서 에러가 없을시에만 다음 단계로 넘어가는 방법을 취하기 때문이다.


● 커널 패치 방법
커널 소스 전체를 다운로드 하지 않고 변화된 영역만 제공하는 패치를 다운로드 할 경우 현재 소유하고 있는 커널 소스 이후 버전의 패치파일을 모두 다운로드 해야한다.
ex) patch-2.4.19.gz, patch-2.4.20.gz, ...

$patch -p0 < patch-2.4.19
$patch -p0 < patch-2.4.20
.
.
.

※ 단, 패치 가능한 커널소스는 kernel.org에서 배포하는 기본적인 소스이다.
예)Redhat9.0 의 커널 소스 (2.4.20-8) 과 같은 소스는 레드헷에서 kernel.org에서 배포하는 기본적인 소스를수정한 것이기 때문에 정상적인 패치가 불가능하다. 즉, kernel.org에서 받은 2.4.20 과 같은 커널소스가 정상적인패치가 가능한 소스라는 뜻이다.


◎ 최종 정리
1. make mrproper(최초 컴파일시 생략)
2. make menuconfig
혹은 make xconfig
혹은 make oldconfig
3. make dep
4. make clean (처음으로 컴파일 과정을 수행한다면 생략)
5. make bzImage
6. make modules
7. make modules_install
8. make install

※ make install의 역할 : initrd 이미지를 생성해주고, vmlinuz 커널이미지와 System.map 맵핑 파일을 /boot에 복사하고 심볼릭 링크 파일 생성, 그리고 grub.conf를 알맞게 수정.

※ 위의 과정을 모두 수행후에 리부팅을 했을 때
kernelpanic - not syncing : No init found, Try passing init = option to kernel 과 같은 에러 메세지와 함께 부팅이 안된다면 2. make menuconfig과정에서 file systems 중ext3 를 모듈<M>이 아닌 적재<*>로 바꾼 후 위의 과정을 반복한다.

★ 여기서 TIP : 윈도우XP를 마운트 하고 싶다면...
위의 과정중 2. make menuconfig과정에서 file systems중에 ntfs를 모듈<M>이나적재<*>로 설정한다. 모듈 적재에 대해서 잘 모른다면 속편하게 적재<*>로 하기를 권장한다.