제8장 커널 & 파일 시스템 분석
목 차 8.1 커널 컴파일 8.2 커널 환경설정 8.3 파일 시스템 8.4 부팅 과정 분석
8.1 Kernel Compile 커널이란 운영체제의 핵심을 이루는 요소로서 컴퓨터내의 자원을 사용자 프로그램이 사용할 수 있도록 관리하는 프로그램이다. 이런 커널의 역할은 사용자가 작동시키는 응용프로그램과 하드웨어간의 조정자 역할을 맡는다. 동시에 수행되는 여러 응용프로그램들(엄밀히 말하자면 프로세스들과 쓰레드들이다.)을 위해 메모리 관리를 해 주며 컴퓨터 자원을 배분하는 역할을 해 준다. 컴파일이란 컴파일러를 이용하여 프로그램 소스로부터 수행 가능한 바이너리 코드를 만드는 과정을 말한다. 리눅스 소스는 거의 대부분 C 언어로 작성되었으며 약간의 어셈블리 코딩을 가지고 있다. 다음에 오는 과정은 이 커널을 X-Hyper270-TKU 보드에 맞게 설정하고 컴파일하는 것을 설명한다.
8.1 Kernel Compile 필요한 파일 (CD 에 있는 내용) <보드용 리눅스 커널> - X-Hyper270-TKU Kernel : linux-2.6.11-h270-tku_v1.1 커널을 압축시킨 파일 X-Hyper270-TKU Kernel : linux-2.6.11-h270-tku_v1.1.tar.gz
arch/시스템type/Kconfig 8.1 Kernel Compile 일반 커널 컴파일 순서 <comfile 옵션 생성> arch/시스템type/Kconfig Fusing & Booting (make mrprobe) make menucofnig (make clean) make zImage <커널 이미지 생성> arch/시스템type/zImage Fail(kernel panic)
8.1 Kernel Compile 커널 이미지 생성과정 “ELF” file “BIN” file 커널의 Boot 코드 (압축 해제 코드) Compressed & Stripped Kernel Image (vmlinuz) “piggy.o” zImage Uncompressed (vmlinux) Kernel Source “ELF” file “BIN” file
8.1 Kernel Compile X-Hyper270-TKU Kenel인 linux-2.6.11-h270-tku_v1.1.tar.gz로 compile 하여 zImage(커널 이미지)를 생성 (CD 참조) Kernel source가 있는 디렉토리로 이동한다. 먼저 아래 그림처럼 X-Hyper270-TKU 설정을 한 후 menuconfig 화면으로 이동한다. “make xhyper270tku_defconfig”는 kernel 컴파일 옵션을 TKU보드에 맞추어 주는 일을 한다. /Kernel]# cd linux-2.6.11-h270-tku_v1.1 /linux-2.6.11-h270-tku_v1.1]# make xhyper270tku_defconfig /linux-2.6.11-h270-tku_v1.1]# make menuconfig Xhyper270-tku에 맞게 Kconfig를 변경시켜준다.
8.1 Kernel Compile make menuconfig로 kernel configuration 한다.
8.1 Kernel Compile 이미 기본적인 설정은 되어있으니, Exit로 저장만 하고 빠져나오면 된다
8.1 Kernel Compile make zImage로 Kernel image를 생성 (10~20분 소요) 컴파일 후, arch/arm/boot에 생성된 zImage 확인 및 tftpboot directory 에 복사한다.
8.2 커널 환경설정 각 컴파일 과정 살펴보기 X-Hyper270-TKU의 Kernel 환경 설정은 menuconfig를 이용한다. 커널 컴파일하는 3가지 설정 방법중 하나로써 가장 많이 쓰이는 방법 중에 하나이다. 이는 메뉴식 환경설정이어서 menuconfig라 하고 나머지중 하나인 config는 행단위 설정이며 또다른 하나인 xconfig는 X-윈도우 환경에서 사용할 수 있다.
<make menuconfig> 8.2 커널 환경설정 Configuration language Konfig <make menuconfig> tristate [y][m][n] : 모듈타입 선택 가능 bool [y][n] :boolean 타입/모듈 X make menuconfig 에서 나오는 선택 text
8.2 커널 환경설정 Configuration language Makefile obj-y : 조건에 상관없이 포함 obj-$(CONFIG_SAMPLE) :심볼에 따라 포함
8.2 커널 환경설정 Main Menu
8.2 커널 환경설정 Code maturity level options ---> [*] Promprt for development and/or incomplete Code/drivers - 커널 코드의 성숙도를 선택하는 부분으로 개발버전 수준의 소스를 사용하게끔 선택해 주는 것이다. 이것은 알파버전들을 커널에 포함시킬 것인지 묻는 항목.
8.2 커널 환경설정 Loadable module support ---> [*] Enable Loadable module Support version 1.2 이후부터 리눅스 커널은 모듈 기능을 이용한다. 모듈을 이용하면 자주 쓰이지 않는 장치 드라이버나 기능들을 커널 바깥에 모듈로 만들어 두었다가 필요할 때에만 동적으로 메모리에 적재하여 사용한다. 작업이 끝나면 메모리에서 다시 제거하므로 메모리를 효율적으로 사용할 수 있고, 커널 크기가 감소한다. 또한, 모듈은 스스로가 컴파일되어 독자적인 기능을 가지므로 모듈로 설정한 기능에 변화가 있더라도 전체 커널에는 손대지 않을 수도 있다. 파일시스템, 장치 드라이버, 바이너리 포맷 등 많은 기능이 모듈을 지원합니다. 반드시 [*]를 선택한다. [*]Module unloadig / [*] Force module unloading 선택
8.2 커널 환경설정 System Type ---> ARM system type(PXA2xx-based) 시스템 Type 중 X-Hyper PXA의 CPU 타입을 설정하는 창으로 PXA2xx- based선택하여 그 안의 PXA2xx-based 기본으로 설정 된것을 확인한다.
8.2 커널 환경설정
8.2 커널 환경설정 System Type ---> Intel PXA2xx Implementations --->
8.2 커널 환경설정 아래와 같이 X-Hyper270-TKU를 선택한다
8.2 커널 환경설정 General setup ---> 네트워킹과 버스 프로토콜, 절전기능 등 시스템에 전반적으로 영향을 주는 설정들입니다.
8.2 커널 환경설정 General setup ---> PCMCIA/CardBus support ---> CardBus는 PC-카드를 위한 32 비트 버스 매스터링 아키텍쳐입니다. (원래 PCMCIA 표준 제품들은 16 비트 와이드 버스밖에 없습니다) 새로 나온 PC-카드 대부분은 CardBus 카드들입니다. PC-카드를 사용하려면 먼저 이 기능을 지원하는 소프트웨어를 (David Hind"s pcmcia-cs 패키지) 설치해야 합니다.
8.2 커널 환경설정 Memory Technology Devices (MTD) ---> 32-bit buswitch, 2-chip, Untel/Sharp flash chips 선택 8.2 커널 환경설정 Memory Technology Devices (MTD) ---> RAM/ROM/Flash chip drivers --->
8.2 커널 환경설정 Memory Technology Devices (MTD) ---> Mapping drivers for chip access --->
8.2 커널 환경설정 Network device support ---> [*] Network device support 자신의 컴퓨터가 네트워크에 연결되어 있거나 SLIP이나 PPP를 사용하려면 선택합니다.
8.2 커널 환경설정 Networking options ---> < > Packet socket: mmapped IO 이 옵션을 활성화하면 패킷 프로토콜 드라이버는 더 빠른 통신을 지원하는 IO 메커니즘을 사용할 것입니다. <*> Unix domain Sockets
8.2 커널 환경설정 [*] TCP/IP networking 리눅스 시스템이 TCP/IP 네트워크가 되게 지원해주는 기능입니다. TCP/IP 는 지역 네트워크 및 인터넷 표준 프로토콜이며, 인터넷을 통하지 않는 Standalone 컴퓨터라 할지라도, TCP/IP 는 필요합니다. term과 XWindow 같은 프로그램은 TCP/IP 프로토콜을 사용하기 때문입니다. [*] IP: kerneL LeveL autoconfiguration : [*] IP: DHCP Support [*] IP: BOOTP Support [*] IP: RARP Support 클라이언트 시스템이 부팅할때 DHCP 나 BOOTP 서버로부터 네트워크 설정 정보를 가져오는 기능입니다. 디스크가 없이 부트하는 시스템에 쓰이며, "NFS를 통한 루트 파일시스템" 항목도 역시 [Y]를 선택해야 합니다.
8.2 커널 환경설정
8.2 커널 환경설정 Network device support ---> Ethernet (10 or 100Mbit) ---> <*> SMC 91C9x/91C1xx 1 support X-Hyper270-TKU Ethernet 카드중 10/100 Base-T인 SMC91C111을 지원 <*> SMC 91C9x/91C1xx 2 support X-Hyper270-TKU Ethernet 카드중 10 Base-T인 CS8900을 지원 <*> CS8900 support
8.2 커널 환경설정 ATA/ATAPI/MFM/RLL support ---> ATA/(E)IDE and ATAPI units에 대한 설정
8.2 커널 환경설정 <*> X-Hyper27x IDE daughter board support X-Hyper-TKU의 IDE Interface를 선택합니다.
8.2 커널 환경설정 Character devices ---> 터미널, 비디오 어뎁터, 마우스, 프린터 등 문자 단위로 데이터를 다루는 다양한 장치들을 지원합니다. [*] VirtuaL terminaL 하나의 물리적인 터미널 위에 여러 개의 가상 터미널을 실행하는 기능입니다. 가상 터미널은 여러 개의 X 세션을 띄울 수도 있으며 모니터 여러 개를 동시에 사용할 수도 있습니다. [*] Support for conSoLe on virtuaL terminaL 시스템 콘솔은 모든 커널메시지와 경고 메시지를 수취하고, 단독 사용자 모드에서 로그인을 허용하는 장치입니다.
8.2 커널 환경설정 Character devices ---> 터미널, 비디오 어뎁터, 마우스, 프린터 등 문자 단위로 데 이터를 다루는 다양한 장치들을 지원합니다. [*] ADS78843 Touch Screen Ads7843 터치스크린 장치 추가 [*] Standard/generic (dumb) SeriaLSupport 모뎀과 시리얼 마우스, 시리얼 디바이스를 사용하는 기능
8.2 커널 환경설정 [*] PXA serial port support [*] console on PXA Serial port 직렬 포트를 시스템 콘솔로 쓸 수 있는 옵션이다. (시스템 콘솔은 커널 메세지와 경고들을 받아 뿌려주고 싱글 유저 모드로 로긴할 수 있게 해주는 디바이스입니다.) 가령 직렬 포트 프린터 등으로 여러 메시지들을 기록할 수도 있습니다. 여기서 [Y]를 설정해도 커널 패러미터를 조정하지 않으면 /dev/tty0가 시스템 콘솔로 그대로 잡혀 있습니다. 예를 들어 두번째 시리얼 포트를 시스템 콘솔을 바꾸려면 커널 명령 라인에 "console=ttyS1" 명령을 씁니다. "man bootparam"이나 부트 로더용 문서들을 보면 부트 로더(lilo나 loadlin)가 부팅할 때 어떤 옵션을 넣어야 하는지 알 수 있습니다.
8.2 커널 환경설정 [*] Legacy (BSD) PTY Support PTY는 소프트웨어로 구동되는 의사 장치입니다(pseudo terminal). 매스터와 슬레이브 두 부분으로 구성되어 있는데 물리적 터미널과 똑 같이 동작하며 슬레이브는 터미널을 흉내냅니다. 매스터 디바이스는 슬레이브로부터 데이터를 읽거나, 혹은 슬레이브에 데이터를 쓸 때에 사용합니다. 전형적인 매스터 사이드 프로그램은 telnet 서버나 xterm 입니다.
8.2 커널 환경설정
8.2 커널 환경설정 File systems ---> 리눅스에서 접근할 수 있는 다양한 파일시스템에 대한 설정. 모든 운영체제는 고유한 파일시스템 형식을 가지고 있다. 일반적으로 다름 운영체제의 파일시스템으로부터 읽거나 쓰는 작업을 위해서는 특별한 응용프로그램들을 설치해야 한다. 그러나 리눅스에서는 커널 모듈을 통해 이런 일들이 가능하다.
8.2 커널 환경설정 File systems ---> YAFFS support ---> NAND Filesystem으로 가장 많이 사용하는 YAFFS를 선택 * 참고: http://www.aleph1.co.uk/yaffs
8.2 커널 환경설정 <*> Second extended fs support [*] Ext2 extended attributes <*> Ext jounalliing file system support [*] Ext3 extended attributes Linux에서 가장 많이 사용하는 Ext2와 저널링 기능이 추가된 Ext3를 사용
8.2 커널 환경설정 Graphics support ---> Consule display driver support ---> <*> Framebuffer Console support 콘솔에서 그래픽 기능을 사용할 수 있도록 커널자체가 지원하는 기능입니다. 잘못 설정하면 모니터나 비디오 카드에 물리적인 손상을 줄 수도 있습니다. 확실하지 않으면 [N]을 선택합니다. 프레임 버퍼는 리눅스에서 지원되는 여러가지의 하드웨어 종류에 대해 동일하게 접근하도록 만들어 주기 때문에 응용 프로그램 작성이 매우 쉽고, 이식성이 좋은 환경을 제공합니다. 프레임 버퍼의 모든 기능을 완전히 사용하기 위해서는 이름이 fbset인 유틸리티 프로그램이 필요합니다. XHYPER270은 PXA LCD를 지원합니다.
8.2 커널 환경설정
8.2 커널 환경설정 Sound ---> 사운드 장치들을 지원합니다. <*>Open Sound System(DEPRECATED) <*>PXA Audio <*>PXA AC97 audio support Intel에서 제공되어지는 PXA27x용인 AC97 를 지원합니다.
8.3 File System
8.3 파일 시스템 타겟보드의 filesystem은 사양에 맞게 여러가지를 선택적으로 사용할 수 있다. 종류 Ramdisk Jffs Jffs2 Cramfs Ramfs Yaffs 각각의 장단점이 있으니 개발자의 사양에 맞게 사용을 하면 된다.
8.3 파일 시스템 Root filesystem(“/”)에는 커널이 동작하기 위한 공간과 library, util등이 포함된다. Root filesystem으로 JFFS2파일시스템을 사용하면, x image등의 크기가 큰파일들을 플래시메모리에 저장하여 SDRAM의 여분을 늘리고, mount 할때는 jffs2를 사용한다. Root filesystem크기가 작고 시스템의 빠른 접근이 필요할 때는 Ramdisk 파일시스템을 사용한다. 파일시스템은 개발할 시스템에 알맞게 구현하여야 할 것이다.
8.3 파일 시스템 JFFS(Journalling Flash File System) JFFS2 개요 JFFS2파일시스템은 MTD드라이버에 의해 flash 메모리에서 구현되는 filesystem이다. JFFS2는 file을 압축하여, 용량의 극대화를 이룰 수가 있습니다. Kernel configuration 플래시 메모리를 jffs2파일시스템으로 사용하기 위한 설정.
8.3 파일 시스템 General Setup 설정값 “console=ttyS0, 115200 console=tty0 mem=128M root=1F02 rw” root=1f02 루트파일시스템(“/”)의 주번호 1f(31), 부번호 02(3번째)의 장치파일 "console=ttyS0,115200“ 사용할 시리얼 장치와 속도 설정 JFFS2를 사용하기 위해서는 먼저 MTD Driver를 활성화 해주어야 한다.
8.3 파일 시스템 MTD드라이버로써 플래시 메모리 디바이스 드라이버를 메뉴컨피그에서 활성화 해야 한다.
8.3 파일 시스템 RAM/ROM/Flash chip drivers를 선택한 하위 항목 32-bit busswitch, Untel/Sharp flash chip
8.3 파일 시스템 CFI Flash device mapped on XHyper2xx xscale evalboard를 선택 플래시 메모리의 공간을 사용하는 타겟보드의 설정으로 사용한다. 위의 선택으로 drivers/mtd/maps/xhyper270tku.c파일이 컴파일된다.
8.3 파일 시스템 drivers/mtd/maps/xhyper270tku.c파일 NOR FLASH 메모리(32MB)를 위한 파티션 크기를 define해 놓았다.
8.3 파일 시스템 mtd디바이스가 선택되면 JFFS2파일시스템을 선택할 수 있게 된다 . Jffs2 image는 mkfs.jffs2 라는 유틸을 통해 image로 만든다.
8.3 파일 시스템 mkjffs2 사용법 스크립트의 내용은 다음과 같다. 생성된 rootfs.img 이미지를 bootloader를 이용해 다운로드 한 후 에는 필히 flash에 write해 주어야 한다.
8.4 부팅 과정 분석 $KERNEL_SRC/arch/arm/boot/compressed/ head.S Head-armv.S b SYMBOL_NAME(start_kernel) $KERNEL_SRC/init/main.c start_kernel() 커널 초기화 시작
8.4 부팅 과정 분석 $KERNEL_SRC/init/main.c start_kernel() 1. lock_kernel() 다른 부분에서 커널로의 진입을 방지 2. setup_arch() Architecture에 의존적인 내용들(프로세서, 보드)을 설정 a. setup_processor() b. setup_architecture() 3. paging_init() Page Table 설정, Memory Map 초기화 4. trap_init() 커널이 사용하게 될 예외상황(Exception*) 처리 부분 초기화 * Exception 종류 : Reset, Software Interrupt, IRQ, … 5. init_IRQ() 인터럽트를 나타내는 descriptor 구조체인 irq_desc[] 초기화, irq_arch_irq() 호출 : Architecture에 의존적인 인터럽트 초기화 init_dma() 호출 : DMA를 사용하는 디바이스들 초기화 6. sched_init() 스케줄러 초기화 (주로 Bottom Half*에 대한 초기화) Bottom Half : Kernel 2.4.X 버전부터 “tasklet” tasklet : softirq_init() 이 담당
8.4 부팅 과정 분석 7. time_init() 6. sched_init() 8. console_init() Timer 인터럽트 초기화 6. sched_init() 8. console_init() 콘솔(console) 초기화 (디버깅 정보 혹은 시스템 정보 출력) 커널 설정 시 “CONFIG_MODULES” 가 정의되어 있을 때 호출됨 커널의 모듈 설정과 관련된 부분 초기화 수행 9. init_modules() 전체 커널 메모리 공간에서 가지는 커널 object를 위한 cache를 연결 리스트(linked list) 형태로 유지 : “cache_chain” 10. kmem_cache_init() 11. mem_init() 메모리 시스템 초기화, 얼마 정도의 메모리가 사용 가능한지 알려줌 12. proc_root_init() /proc 이하의 메모리 내에 존재하는 파일 시스템 생성 ...... proc_net = proc_mkdir(“net”, 0); proc_mkdir(“sysvipc”, 0); proc_sys_root = proc_mkdir(“sys”, 0); proc_root_fs = proc_mkdir(“fs”, 0); proc_root_driver = proc_mkdir(“driver”, 0); proc_tty_init(); proc_device_tree_init(); proc_bus = proc_mkdir(“bus”, 0); 각 시스템 정보들에 대한 Entry
8.4 부팅 과정 분석 13. kernel_thread() 12. proc_root_init() 14. cpu_idle() 커널에서 사용할 쓰레드(Thread) 생성 : “init()” 호츌 12. proc_root_init() 14. cpu_idle() 시스템에서 어떤 이벤트(event)가 발생하기를 무한정 기다림 ...... cpu_idle() { while(1) while(!current->need_resched) idle(); }
8.4 부팅 과정 분석 $KERNEL_SRC/init/main.c init() 1. lock_kernel() 다른 부분에서 커널로의 진입을 방지 2. do_basic_setup() start_kernel() 에서 다 처리하지 못한 시스템의 나머지 부분들을 초기화 : PCI, IrDA, PCMCIA, … * 여기까지 수행하면 Machine에 관한 초기화는 끝! sock_init() Initrd 가 설정되어 있다면 initial RAM disk 설정 filesystem_setup() mount_root() 디바이스에 대한 파일 시스템 설정 : 디바이스들에 대한 것을 파일 시스템과 같은 구조로 만들기 위해 사용 (UNIX는 모든 디바이스들을 파일로 처리) mount_devfs_fs()
8.4 부팅 과정 분석 파일시스템에 init파일 내용을 수행 3. free_initmem() 시스템 초기화에만 사용하고, 이후에는 사용하지 않는 메모리 영역을 해제하여 메모리를 증가시킴 2. do_basic_setup() 하위 레벨에서의 부팅 및 커널 초기화 과정 종료!!! 4. unlock_kernel() “init” daemon 생성 과정 5. execve(“/sbin/init”, ...) execve(“/etc/init”, ...) execve(“/bin/init”, ...) execve(“/bin/sh”, ...) 시스템 콜 (System Call) 파일시스템에 init파일 내용을 수행 만약 4개의 ‘init’ 중 아무 것도 실행이 안된다면, 6. panic(“No init found. ...”) init daemon PID == “1” 모든 프로세스의 부모 프로세스 /etc/inittab 내용들을 수행 init daemon 생성
8.4 부팅 과정 분석 etc/inittab inittab에서 수행하는 내용