Home Map Index Search News Archives Links About LF
[Top Bar]
[Bottom Bar]
Emiliano Ariel Lesende


들어 가는 글

리눅스 : 인터넷
운영체제

특징들

커널 컴파일 하기

커널의 비밀

요약: 리눅스 커널에 대해 짧게 살펴봅니다.


들어 가는 글

'리눅스 커널의 비밀'에 관한 기사 시리즈의 처음 글에 온 걸 환영한다. 아마 당신은 리눅스 커널 소스를 이미 본 적이 있을 것이다. 봤다면 처음 압축해서 100-kb였던 파일이 지금은 300 개가 넘는 파일이 있고, 소스 코드는 200만 줄이 넘고, 압축을 해서 9메가 이상이란 것을 알 것이다.

이 시리즈는 초보자를 위한 글이 아니고, 경험이 많은 프로그래머를 위한 글이다. 이 글을 읽는 것은 자유이다. 또한, 질문을 E-mail로 보내면 최대한 노력을 하여 답변할 것이다.

매일 새로운 버그가 발견되고, 그에 따른 패치가 계속 나온다. 현제에는 소스 코드 전체를 이해한다는 것은 거의 불가능하다. 매우 많은 프로그래머에 의해서 작성되는데 최대한 같은 코딩 스타일로 코딩을 하려고 한다. 하지만 코딩 스타일은 서로 다르다.

Linux: The Internet Operating System

리눅스는 인터넷을 통해서 자유롭게 배포되는, PC와 다른 아키텍쳐를 위한 운영 체제이다. POSIX 1003.1과 호환이 되며 Unix System V와 BSD 4.3의 많은 특징들을 가지고 있다. 이 시리즈에서 살펴 볼 커널 소스는 대부분 필란드 대학생이던 Linus Torvalds에 의해 작성되었다. 커널은 처음 1991년 11월에 발표되었다.

특징들

리눅스는 현재 Unix 환경의 운영 체제의 특징을 거의 모두 구현했다.
  • Multitasking

    리눅스는 진정한 멀티 태스킹을 지원한다. 모든 프로세스는 독립적이다. 어떤 프로세스도 다른 프로세스를 실행시키기 위해서 CPU의 사용을 멈추지 않아도 된다.

  • Multiuser accessibility

    리눅스는 다중사용자(Multiuser)뿐만 아니라, 다중접근(multiuser accessibility) 도 지원한다. 여러 터미날을 이용해서 같은 호스트에 접근하여 호스트의 자원을 동시에 사용할 수 있다.

  • 필요한 부분만 메모리에 적재하기

    프로그램은 실행되기 위해서 전체가 메모리에 적재되지 않고, 부분적으로 메모리에 적재된다.

  • 메모리 페이징

    만약 시스템 메모리가 모두 소비되었다면, 리눅스는 4K 크기의 메모리 페이지를 찾는다. 그리고 그 페이지는 하드 디스크로 복사한다. 위의 페이지가 다시 사용될 때는 하드 디스크로부터 원래 위치로 복사하게 된다. MS windows를 포함한 구형 Unix system과 몇몇 플랫폼은 메모리를 하드 디스크로 스왑하게 된다. 이는 process와 관련된 모든 페이지가 하드 디스크에 저장된다는 것을 말한다. 하지만 이는 비효율적이다.

  • 동적 disk cache

    MSDOS 사용자는 SmartDrive를 사용하곤 했다. SmartDrive는 메모리의 일부 영역을 디스크 캐시를 위해 할당한다. 리눅스는 좀더 동적인 디스크 캐시를 제공한다. 메모리가 사용중이 아니라면 캐시는 늘어 나고, 메모리가 필요하다면 캐시는 줄어 들게 된다.

  • 공유 라이브러리

    라이브러리는 프로그램이 데이터를 처리하기 위해서 사용하는 루틴들의 집합이다. 여러 프로그램이 동시에 사용하는 표준 라이브러리들이 많이 있다. 이들 라이브러리는 프로그램이 실행될 때 메모리로 적재되는데, 구형 시스템에서는 같은 라이브러리를 사용하는 새로운 프로세스가 실행될 때 또 다시 메모리에 적재되게 된다. 이는 메모리를 낭비하는 일이다. 리눅스를 포함한 현대의 시스템에서는 라이브러리는 한번만 메모리에 적재되고, 다른 프로세스들은 이를 공유한다.

  • Standard POSIX 1003.1 100% 호환. System V와 BSD 특징들 지원.

    POSIX 1003.1은 유닉스 운영 체제를 위해서 표준 Interface를 정의했다. 이 인터페이스는 C 루틴들의 집합으로 묘사된다. Microsoft Windows NT도 POSIX 1003.1을 지원한다. 리눅스 1.2는 POSIX를 100% 따른다. 부가적으로 System V와 BSD 인터페이스를 지원하거나, 호환성을 위해 지원을 구현하고 있는 중이다.

  • 다양한 실행 파일 형식 지원

    누가 리눅스에서 DOS, Windows95, FreeBSD나 OS/2 응용 프로그램을 돌리는 것을 싫어 하겠는가? 그래서 DOS, Windows95 에뮬레이터가 개발 중에 있다. 또한 리눅스는 iBCS2(intel Binary Compatibiliy)를 따르는 intel 환경의 유닉스 플랫폼의 실행 파일을 실행시킬 수 있다.

  • 다양한 파일 시스템 형식

    리눅스는 많은 파일 시스템 형식을 지원한다. 가장 많이 쓰이는 형식은 Second Extended File System(Ext2)이다. 지원되는 다른 파일 형식은 도스에서 쓰이는 File Allocation Table(FAT)이다. 하지만, FAT는 설계상 보안이나, 멀티유저 접근을 사용하지 못한다.

  • 네트워킹

    리눅스는 지역 네트웍을 통해서 통합될 수 있다. Networked File System(NFS), remote login(telnet, rlogin) dial-up SLIP, PPP 등등 모든 unix 서비스를 지원한다. 파일 공유와 Macintosh, Netware 와 Windows 등에서 프린트를 할 수 있는 등 클라이언트/서버 환경을 지원한다.

  • System V IPC

    프로세스간 통신을 위하여 메시지 큐, 세마포어, 공유 메모리를 제공한다.

커널 컴파일 하기

커널 자체를 공부하기 전에 일단 커널 소스를 보자.

소스 트리 구조: 리눅스 커널 소스는 보통 /usr/src/linux/ 디렉터리에 존재한다. 뒤에서 나오는 모든 디렉터리는 위의 디렉터리 밑에 있는 디렉터리이다. 커널 버전 1.0 이후부터는 비인텔 계열 아키텍처로 포팅이 이루어 졌으므로 소스 트리 구조에 약간의 변화가 생겼다. 아키텍쳐에 의존적인 코드들은 arch 에 있다. Inter 계열의 프로세서를 위한 코드는 arch/i386/에 있고, arch/mips/는 MIPS를 기초한 시스템을 위한 디렉터리이고, arch/sparc/는 Sparc에 기초한 시스템을 위한 디렉터리이고 arch/ppc/PowerPS나 Powermacintosh 를 위한 디렉터리이다. Intel 아키텍처가 가장 리눅스와 가장 널리 쓰이므로 우리는 Intel 아키텍처만을 보도록 한다.

리눅스 커널은 단순히 C 프로그램일 뿐이다. 두 가지 차이점이 있을 뿐이다. 보통 C로 짜여진 프로그램은 main(int argc, char **argv)로 부터 시작을 하지만 리눅스 커널은 start_kernel(void)로 부터 시작을 한다. 시스템이 시작하고 커널이 적재될 때 프로그램 환경은 존재하지 않는다. 이것은 C 루틴이 처음 실행될 때 무언가가 선행되어야 한다는 것을 의미한다. arch/i386/asm/에 있는 어셈블리 코드가 이를 한다.

어셈블리 루틴은 커널을 메모리의 절대주소 0x100000(1 Mbyte)로 옮기고, 인터럽트 서비스 루틴과 Global file descripter Table과 Interrupt descriptor Table 을 설치한다. 이 순간부터 프로세서는 보호모드로 전환된다. init/ 디렉터리는 커널을 초기화하는데 필요한 것들을 가지고 있다. 여기에는 start_kernel()도 있는데 이는 커널을 적절히 초기화 하고, 부트 파라미터로 넘어 온 것들을 포함한다. 처음으로 만들어 지는 프로세스는 system call을 사용하지 않고 생성된다(시스템 자체도 아직 적재되어 있지 않다.). 이것이 바로 유명한 idle process이고, 어떠한 프로세스도 실행되지 않을 때 이 프로세스가 실행되게 된다.

kernel/arch/i386/kernel/ 디렉터리는 이름에서도 알 수 있듯이 커널에서 가장 중요한 부분을 담고 있다. 중요한 system call들이 여기에 있다. time handler와 스케줄러, DMA manager, interrupt handler, signal controller 등이 구현되어 있다.

시스템 메모리에 관련된 소스 코드는 mm/arch/i386/mm/에 있다. 여기에는 프로세스에 메모리를 할당하고 해제하는 등의 일을 하는 코드가 구현되어 있다. 또한 메모리 페이징에 관한 것도 여기에 구현되어 있다.

Virtual File System(vfs)는 fs/에 있다. 지원되는 각각의 파일 시스템 형식은 각각 서브 디렉터리에 있다. 가장 중요한 파일 시스템은 Ext2와 Proc 파일 시스템으로 다음에 더욱 자세하게 알아 볼 것이다.

모든 운영 체제는 하드웨어를 위해서 드라이버가 필요하다. 리눅스에서는 drivers/에 드라이버에 관한 코드가 있다.

ipc/에서는 리눅스에서 구현한 System V IPC에 관한 코드를 볼 수 있다.

다양한 네트웍 프로토콜과 socket , internet domain 등은 net/에서 볼 수 있다.

표준 C 루틴의 일부는 커널 자체가 C 프로그래밍을 사용하기 위해서 lib/에 구현되어 있다.

커널 컴파일 도중 만들어진 모듈들은 modules/에 있지만, 커널 컴파일을 처음 하기 전까지는 그 안에는 아무것도 없을 것이다.

프로그래머에게 가장 많이 사용되는 디렉터리인 include/에는 커널이 사용하는 모든 헤더 파일 들이 있다. 인텔 플랫폼에 관련된 헤더 파일은 include/asm-386/에 있다.

컴파일 하기: 새로운 커널은 보통 다음과 같은 세 가지 단계를 거쳐서 만들어 진다:

  • 먼저 "make config"를 이용하여 옵션을 설정한다."make menuconfig"나 "make xconfig"도 사용 가능하다.
  • 그리고, "make depend"를 이용하여 의존성 검사를 한다.
  • 그리고, "make"를 이용하여 실제 컴파일을 한다.

다음 기사에서 우리는 이러한 스크립트가 어떻게 작동하는지와 새로운 옵션을 만들기 위해서 어떻게 수정해야 하는지 등을 자세하게 배울 것이다.

필자는 독자가 이 글을 즐겼으면 하는 바이다. 당신의 조언이나 충고 혹은 비평 등이 담긴 메일은 언제나 환영이다. elesende@nextwork.net으로 보내면 된다.

더 알고 싶으신 분은:

  • Kernel-HOWTO를 읽어보세요.

번역 : 허정수


본 웹사이트는 Miguel Angel Sepulveda씨에 의해 관리됩니다.
©Emiliano Ariel Lesende 1998
LinuxFocus 1998