본문 바로가기

코드^학습/메모한 지식

리눅스 커널 심층분석 0x006

2_커널과의 첫만남

(아...ftp에서 구할수있는걸 모르고 3.12 버전으로 어떻게 공부하지...고민하다가

ftp로 들어가볼까? 하고 들어갔다가 책에서 다루는 2.6.10버전을 다운로드 받았다.

이걸로 계속하면 될거같다. 뭔가 당연한걸 생각하지 못하다니;;)


○커널 빌드하기

커널은 많은 기능을 포함하고 있고 엄청나게 다양한 하드웨어를 지원하기 때문에 설정해야 할 것이 많기는 하다. 커널 설정은 설정 옵션을 사용해 조절할 수 있는데, 설정옵션은 CONFIG로 시작하며 CONFIG_FEATURE의 형태를 갖는다.

 빌드 과정을 조절하는 옵션들은 불리언(Boolean)이나 3상 값을 갖는다. 불리언 옵션은 yea/no/module옵션을 가진다. yes는 해당 기능이 모듈이 아니라 메인 커널의 일부분으로 합쳐져 컴파일될 것임을 나타낸다. module은 값이 설정되어 있지만 해당 기능이 모듈(동적로딩이 가능한 분리된 개체)로 컴파일될 것임을 나타낸다. 주로 이러한 값들은 갖는 대상은 '드라이버'들이다.

 설정 옵션중에 문자열이나 정수값도 있는데 이는 빌드 과정 조절보다는 전처리 매크로를 통해 커널 소스가 접근할 수 있는 리소스 값을 설정하는데 쓰인다.(어렵다. 나중에 또 나오겠지) 정적으로 할당할 수 있는 배열의 크기 같은 설정 옵션이 바로 그런 예이다.(커널이 메모리에 접근하여 공간을 할당하는 것을 말하는 것인듯, 리눅스는 모든 것을 파일단위로 관리하므로 설정을 조절하는 것들은 모두 파일이다.)


 배포되는 커널들은 거의 모든 드라이버를 모듈로 갖고 있는 경우가 많다. 이는 쓰이기에는 배워나가야하는 우리에게는 적합하지 않다. 다행히 커널은 설정을 조작하기 위한 여러가지 도구들을 제공한다. 가장 간단한 것이 커맨드라인 도구(쉘)이다.


$ make config

$ make menuconfig

$ make xconfig 

$ make gconfig

$ make defconfig

$ make oldconfig

$ make : 이건 잘 알듯이 새 커널 빌드하기전에 컴파일...


(수많은 도구와 설명이 간략이 나와있지만 대부분은 처음보는 용어들이다. Makefile의 옵션으로 있는 것들 같은데 지금 당장 중요한 옵션은 아닌듯하니 넘어간다. 저 위에 설명이 길긴한데...지금 당장 자세히 알필요는 없는거 같다.)


-빌드 노이즈 최소화

빌드 노이즈란 컴파일 등을 하다보면 화면에 출력되는 수십수백의 줄을 말한다. 그러나 경고메시지마저 생략하면 매우 곤란하므로 다음과 같이 한다. 그럼 경고메시지는 보이고 다른 메시지는 최소화한다.

$ make > ../some_other_file

그러나 그 밑에는 이렇게 나와있다.

$ make > /dev/null

이건 익숙하다. 한번 들어가면 사라져버리는 /dev/null로 불필요한 메시지를 보내는 것이다. 다만 이건 모든 불필요한 출력을 보내버린다.(에러 메시지는 나온다는건가??)


-다중 빌드 기법

make에 옵션을 줘서 빌드 시간을 단축하는 방법이 나온다. 프로세서당 작업할 개수를 적어준다.(듀얼코어 -> 4개정도)

듀얼 코어 시스템일 경우 : $ make -j4


-커널 설치

널을 빌드하고 나면 설치해야 한다. 이는 아키텍처와 부트로더에 따라 많이 다르다. 메뉴얼에 따라 커널 이미지를 복사하여 부트하게 하는지 알아야 한다.


○다른 성질의 야수

-No libc

커널은 어떤 라이브러리와도 연결되지 않는다. 왜냐하면 속도때문이다. 커널에게는 C 라이브러리는 너무크고 비효율적이다. 대부분은 libc 함수들은 커널 안에 구현되어 있다.

linux/string.h를 추가하면 된다.

그리고 우리가 자주 쓰는 printf()가 아니라 printk()를 사용한다.


-GNU C

커널은 C로 작성되어 있지만 엄격하게 ANSI C로만 되어있는것이 아니라 여러가지 gcc 언어확장을 쓰고 있다. 자세한것은 나중에


-인라인 함수

함수의 호출 위치가 인라인으로 삽입될 수 있다. 이것은 함수 호출과 반환의 부담을 줄인다. 그러나 메모리와 명령어 캐쉬를 많이 사용한다는것이 단점. 자주 호출되거나 빠른 실행을 요하지 않는 경우라면 하지 않는게 좋다.


-인라인 어셈블리

이것은 일반 C하ㅣㅁ수 사이에 어셈블리 명령을 사용할 수 있게 허용한다. 이 기능은 특정 시스템 아키텍처에 의존적인 커널의 일부분에만 쓰인다.


-분기 표기

gcc C 컴파일러에는 조건부 분기가 일어날 가능성을 알려 최적화를 돕는 내장 지시어가 있다. 이때 분기는 확실한 것들이어야한다. 


-메모리 보호가 없음

유저 메모리 공간같은 경우 잘못된 메모리를 참조하는 경우, 커널에서 이 오류를 감지하여 SIGSEGV 시그널을 보냄으로 그 프로세스를 종료한다. 그러나 커널은 그런것이 없다.

커널 메모리는 페이징되지 않고 직접연결 되므로 1바이트를 쓰면 1바이트가 줄어든다.


-부동소수점 연산의 어려움

커널은 소수점을 계산하는 것은 trap(interrupt와 trap이 있다. 이건 운영체제 시간에 배움)을 사용하여 결과를 넘겨주는식으로 수행한다.


-작은 고정 크기의 스택

커널 스택은 크지도, 동적이지도 않다. 작고 고정적이다. x86계열에서는 컴파일시 스택 크기를 4or8KB로 정할 수 있다. 관습적으로는 32비트에서는 8KB 64비트에서는 16KB로 고정된다.


-동기화와 동시성

커널의 경우 공유 자원에 대한 동시접근을 허용하므로 경쟁을 방지하기 위한 동기화가 필요하다.


-이식성 : 여러가지 다른환경으로 옮겨가도 정상작동할 수 있어야한다.

잠