운영체제는 컴퓨터 하드웨어 바로 위에 설치되어 사용자 및 다른 모든 소프트웨어와 하드웨어를 연결하는 소프트웨어 계층이다.

그리고 컴퓨터 시스템의 자원을 효율적으로 관리하는데, 이때 자원은 크게 물리적인 자원과 추상적인 자원으로 구분할 수 있다.

  • 물리적인 자원: CPU, 메모리, 디스크, 터미널, 네트워크 등 시스템을 구성하는 요소 및 주변 장치
  • 추상적인 자원:
    • 물리적 자원을 운영체제가 관리하기 위해 추상화 시킨 객체 ex) 태스크(CPU 추상화), 세그먼트와 페이지(메모리 추상화), 파일(디스크 추상화), 통신 프로토콜과 패킷(네트워크 추상화)
    • 물리적인 자원에 대응되지 않으면서 추상적인 객체로만 존재하는 자원 ex) 보안 및 사용자 ID에 따른 접근 제어

운영체제는 일반적으로 커널 뿐만 아니라 각종 주변 시스템 프로그램을 나타내는 개념이지만, 좁은 의미로는 운영체제의 핵심 부분으로 메모리에 상주하는 커널을 의미하기도 한다.

 

커널은 이러한 자원들을 관리하는 여러 관리자들로 구성되어 있다.

CS746G. Kernel Subsystem Overview

  • 태스크 관리자: 태스크의 생성, 실행, 상태 전이, 스케줄링, 시그널 처리, 프로세스 간 통신 등
  • 메모리 관리자: 물리 메모리 관리, 가상 메모리 관리, 그리고 이들을 위한 세그멘테이션, 페이징, 페이지 폴트 처리 등
  • 파일 시스템: 파일의 생성, 접근 제어, inode 관리, 디렉터리 관리, 수퍼 블록 관리 등
  • 네트워크 관리자: 소켓 인터페이스, TCP/IP 와 같은 통신 프로토콜 등의 서비스 제공
  • 디바이스 드라이버: 디스크나 터미널, CD, 네트워크 카드 등과 같은 주변 장치를 구동하는 드라이버들로 구성된다.

 

리눅스 소스와 각 디렉터리의 내용을 조금 더 살펴보자면,

linux kernel source

 

# kernel

커널 핵심 코드를 포함하는 디렉터리로, 태스크 관리자가 구현된 디렉터리이다. 태스크의 생성과 소멸, 프로그램의 실행, 스케줄링, 시그널 처리 등의 기능이 구현되어 있다.

 

# arch

아키텍쳐 종속적인 코드를 포함하는 디렉터리로, CPU 타입에 따라 하위 디렉터리로 다시 구분된다. /arch/${ARCH} 아래에도 여러 디렉터리가 있다.

  • /boot: 시스템 부팅 시 사용하는 부트스트랩 코드 구현
  • /kernel: 태스크 관리자 중에서 문맥 교환이나 스레드 관리 등 구현
  • /mm: 메모리 관리자 중에서 페이지 폴트 처리 등의 하드웨어 종속적인 부분 구현
  • /lib: 커널이 사용하는 라이브러리 함수 구현
  • /math-emu: Floating Point Unit에 대한 에뮬레이터 구현

 

# fs

리눅스에서 지원하는 다양한 파일 시스템 및 파일 시스템 콜이 구현된 디렉터리로, 다양한 파일 시스템을 사용자가 일관된 인터페이스로 접근할 수 있도록 하는 가상 파일 시스템도 이 디렉터리에 존재한다.

 

# mm

메모리 관리자가 구현된 디렉터리로, 물리 메모리 관리, 가상 메모리 관리, 태스크마다 할당되는 메모리 객체 관리 등의 기능이 구현되어 있다.

 

# driver

리눅스에서 지원하는 디바이스 드라이버가 구현된 디렉터리로, 디스크/터미널/네트워크 카드 등 주변 장치를 추상화시키고 관리한다. 

  • 블록 디바이스 드라이버: 파일 시스템을 통해 접근
  • 문자 디바이스 드라이버: 사용자 수준 응용 프로그램이 장치 파일을 통해 직접 접근
  • 네트워크 디바이스 드라이버: TCP/IP를 통해 접근

 

# net

리눅스가 지원하는 통신 프로토콜이 구현된 디렉터리로, 리눅스 커널 소스 중 상당히 많은 양을 차지한다. 

 

# ipc

리눅스 커널이 지원하는 message passing, shared memory, semaphore 등 프로세스 간 통신 기능을 구현한 디렉터리이다.

 

# init

커널 초기화 부분, 즉 커널의 메인 시작함수가 구현된 디렉터리이다.

하드웨어 종속적인 초기화가 /arch/${ARCH}/kernel 아해의 head.s 와 mics.c에서 이루어진 후,

/init 아래에 구현되어 있는 start_kernel() 으로 커널 전역적인 초기화를 수행한다.

 

# include

리눅스 커널이 사용하는 헤더 파일들이 구현된 디렉터리로,

헤더 파일들 중에서 하드웨어 독립적인 부분은 /include/linux 아래에 정의되어 있으며

하드웨어 종속적인 부분은 /include/asm-${ARCH} 디렉터리 아래에 정의되어 있다.

 

# others

  • documentation: 리눅스 커널 및 명령어들에 대한 자세한 문서 파일 등
  • lib: 커널 라이브러리 함수들이 구현
  • scripts: 커널 구성 및 컴파일 시 이용되는 스크립트 정의

 


리눅스 커널은 위 커널 소스들을 gcc로 컴파일 해서 만들 수 있으며, 

리눅스 커널을 만드는 과정은 크게 kernel configuration, kernel compile, kernel installation 세 단계로 이루어진다.

  • kernel configuration: 새로 만들어질 리눅스 커널에게 현재 시스템에 존재하는 하드웨어 특성, 커널 구성 요소 , 네트워크 특성 등의 정보를 알려주는 과정이다. 커널 구성 단계에서 사용자는 모듈 사용 여부와 시스템 정보, 그리고 시스템에 존재하는 디바이스들의 특성 등에 대한 질문에 답하게 된다. 이러한 선택 사항은 /include/linux/autoconf.h 와 .config 파일에 저장된다. 
    • make config
    • make menuconfig
    • make xconfig
    • 커널 구성은 위 명령어 들을 사용해서 할 수 있으며 텍스트 기반 설정인지 gui로 제공되는지 등에 따라 명령어가 나뉜다.
  • kernel compile: 커널 소스파일을 이용하여 실행가능한 커널을 만들게 되는데, 컴파일 과정에서 아까 만들었던 /include/linux/autoconf.h 와 .config 파일이 사용되며, 커널 컴파일이 끝나면 새로운 커널이 /kernel/arch/${ARCH}/boot 디렉터리에 생성된다.
    • make bzImage
    • make zImage
    • 커널 버전 2.6 이후부터는 그냥 `make` 명령어만 사용해도 된다. 
    • bzImage vs zImage? bzImage는 Big zImage를 의미한다. zImage는 최대 크기 512k만 가능한데, 커널이 컴파일 후 512k 크기를 넘어가면 bzImage로 만들어야 한다. 
  • kernel installation: 생성된 커널로 시스템이 부팅될 수 있도록 만드는 과정으로, 생성된 커널 이미지를 루트 파일 시스템으로 복사 후 모듈 설치 및 부트 로더 수정을 통해 이루어진다. 이로써 모듈로 구성된 커널 내부 구성 요소를 알려주고, 이후 그 구성 요소들이 사용될 때 자동으로 커널에 적재될 수 있도록 설정하는 단계이다. 
    • make modules: 커널 환경설정에서 모듈로 설정한 기능들을 컴파일
    • make modules_install: 컴파일 된 모듈을 /lib/modules 아래 설치
    • make install: 커널 설치

 

커널 소스 컴파일 시 파일 생성 단계는 아래 게시글에 잘 설명되어 있다.

http://www.iamroot.org/xe/index.php?mid=Kernel&document_srl=24595

그림의 내용을 간단히 정리하자면

(1, 3, 6) 커널 소스들을 컴파일하여 .o(오브젝트 파일) .a(라이브러리 파일)을 생성하고, 이들을 링킹하여 vmlinux 파일을 생성한다.

(2) vmlinux 파일에서 .note와 .comment 섹션을 삭제하고 재배치 정보와 심볼 정보를 삭제한 뒤 바이너리 포맷의 파일(Image)을 출력한다.

(4) 이를 gzip 압축 알고리즘을 이용하여 piggy.gz를 생성한다.

(5) 여기서 디버깅 정보 등을 삭제하여 piggy.o를 생성한다.

 

(3, 6, 7) 다음으로 커널의 압축을 해제시켜주는 코드 (head.S, misc.c)를 커널 앞부분에 덧붙여 링커를 통해 bvmlinux 또는 vmlinux 파일을 생성한다. 

(8) bvmlinux 또는 vmlinux가 bzImage 또는 zImage가 되는 것이다. 만약 물리 메모리의 1M 위치에 로드될 수 있는 작은 크기의 커널인 경우 zImage 형태로 파일을 생성하며, 그렇지 않은 경우 bzImage 형태로 파일을 생성한다.

 

 

이러한 단계를 지나 새로운 커널을 만든 후, 모듈로 선택한 커널 구성 요소를 컴파일하고 설치하면 새로 만들어진 리눅스 커널을 이용해 시스템을 부팅할 수 있다.

'CS > OS + Linux' 카테고리의 다른 글

[운영체제] 메모리 관리  (0) 2022.07.19

+ Recent posts