Linux Kernel
Linux Kernel
커널은 하드웨어를 관리하고 시스템 자원을 분배하는 소프트웨어로 운영체제의 핵심이며 커널은 시스템의 다른 모든 부분을 위한 기본적인 서비스를 제공한다.
리눅스 커널의 역할을 간략하게 보자면 응용 프로그램으로부터 System Call이 요청되거나 HW로부터 interrupt가 요청되면 그 요청에 대응하는 처리를 수행하는 역할이다.
Kernel의 주요 기능
- 프로세스 관리 : 프로세스의 생성 및 소멸, CPU 스케쥴링
- 메모리 관리 : 가상 메모리 및 메모리 하드웨어를 관리
- 파일 시스템 관리 : 리눅스 커널에서는 가상 파일 시스템을 통해 실제 파일 시스템과 운영체제 사이에서 다양한 파일 시스템 유형을 제공하는 범용 인터페이스를 제공합니다.
- 디바이스 관리 : 키보드,마우스와 같이 주변 장치와 메모리 간의 자료 전송 및 인터럽트 요청을 처리
System Call
이러한 커널의 기능을 사용하기 위해서는 System Call Interface를 거쳐야 한다. System Call은 사용자가 접근하는 Application 영역에서 Kernel에 접근하기 위한 유일한 수단이다. System Call 자체는 내부적으로 사용자로부터의 입력을 받아 커널에게 이를 알리기 위해 SW Interrupt를 사용한다. SW Interrupt는 프로세서별로 상이한데 이는 exception이 발생하면 커널모드로 전환되며 exception handler가 실행되는 방식이다. 그리고 이러한 System Call이 호출이 되면 커널 코드가 사용자 프로세스 context 아래에서 동작한다.
Kernel Porting
Embedded OS를 올리기 위해서는 tool chain 환경 셋업과 Boot Loader 셋팅 이후에 커널을 올려야한다. 제한된 자원을 갖고 있는 임베디드 제품에 최적화된 커널 코드를 생성하고 제품이 필요로 하는 요소를 지원할 수 있도록 기존 커널 코드를 수정하거나 새로운 코드 추가하여 빌드하게 되는데 이를 커널 포팅이라고 한다. 이는 기본 커널 코드에 사용하는 HW 환경에 맞는 설정값을 셋팅하고 필요한 기능을 수정 및 추가하는 작업이다. Android OS 또한 기본 커널 코드인 vanila kernel code에 수정된 버전으로 볼 수 있습니다.
부팅 가능한 커널 이미지(ex. zImage)를 생성하기까지의 일련의 과정
- 1) 초기화
make distclean
: mproper 의 동작에 각종 백업 파일 등을 추가로 제거make mrproper
: .config 파일을 비롯한 여러 설정파일 및 오브젝트 파일들을 제거
- 2) 설정
- 자신의 시스템에 맞는 커널 요소들을 적절히 선택해가는 과정
make menuconfig
- 3) 빌드
- 커널 최상위 디렉토리에 있는 makefile을 통해 커널을 컴파일하고 바이너리들을 링킹하여 zImage를 생성
make zImage
menuconfig 화면
GUI 형식으로 제공되고 커널 설정을 마치면 .config라는 파일이 생성된다. 사실 커널 코드내에 SoC 제조사에서 제공하는 example config 파일이 있는 경우가 대부분이기 때문에 이를 사용하여 커널을 올릴 수도 있다.
커널 소스코드 수정 및 추가시에 주의해야할 점
- 커널 코드에서는 C 라이브러리에 접근할 수 없다. 커널용 라이브러리를 사용해야 한다.
- 커널 코드에는 User 공간에서와 같은 메모리 보호 기능이 없다.
- 잘못된 포인터를 사용하면 바로 “System Hang”
- 커널 메모리는 페이징(메모리에 올렸다 내렸다) 되지 않으므로 한번 올리면 못내린다.
- 커널은 부동 소수점 연산을 사용하기가 쉽지 않기에 Integer 사용을 권장한다.
- 커널은 작은 고정크기의 스택(2개 페이지 크기;8KB)을 가진다. local 변수할당보다는 동적 메모리 할당을 추천하나 항상 주의해서 사용해야 한다.
- 커널은 하나의 커다란 프로그램으로 프로세스간의 공유 자원을 사용하는 경우가 많기에 동기화 & 동시성을 항상 고려해야 한다.