조교: 이주평(jplee@core.kaist.ac.kr) 컴퓨터 응용 실험 컴퓨터공학 연구실 2005년 11월 10일 실험10 : Linux 2.6 포팅 조교: 이주평(jplee@core.kaist.ac.kr) 컴퓨터 응용 실험 컴퓨터공학 연구실 2005년 11월 10일 Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST 차례 Linux 2.4 vs. Linux 2.6 Linux 2.6 포팅 : 준비사항 Booting ARM Linux : Passing Kernel Parameters Kernel Startup Entry Point Ethernet 장치 드라이버 설정 예비레포트 문제 결과레포트 문제 참고문헌 Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST Linux 2.4 vs Linux 2.6 preemptible kernel O(1) scheduler reverse mapping anticipatory I/O scheduler Advanced Linux Sound Architecture (ALSA) New POSIX Thread Library (NPTL) Unified Device Model 새로운 하드웨어 지원 64bit PowerPC, 64bit AMD Opteron, Embedded Processor ... 새로운 파일시스템 지원 JFS, XFS, NFSv4, AFS ... ※ 참고문헌을 참조하여 직접 정리해 보시오. (예비레포트) Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST Linux 2.6.10 포팅: 준비사항 크로스 컴파일러 재설치 arm-linux-gcc version 3.4.3 (홈페이지에서 다운로드) 리눅스 2.6.10 커널 표준 배포판 다운로드 ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.10.tar.gz # tar -zxvf linux-2.6.10.tar.gz # cd linux-2.6.10 # vi Makefile .... ARCH ?= arm CROSS_COMPILE ?= arm-linux- ARM에 맞게 컴파일함. arm-linux-gcc , arm-linux-ld, ... 이용 Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST /arch : hardware dependent source code들이 모여있다. /arch/arm : arm 계열 CPU에 종속적인 source code /arch/arm/mach-s3c2410 : arm 기반 S3C2410 CPU에 종속적인 source code /arch/arm/mach-s3c2410/mach-core2410.c : S3C2410 CPU기반 CORE2410 보드에 종속적인 source code (본 실험에서 새롭게 생성) S3C2410 기반 보드들이 공통적으로 사용하는 소스코드들 /arch /alpha /arm /mach-pxa /i386 /mach-s3c2410 /mach-smdk2410.c .... /mach-sa1100 /mach-h1940.c .... /mach-rx3715.c /cpu.c, irq.c, time.c, gpio.c, clock.c, .... /mach-core2410.c Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST SMDK2410 보드와의 유사성 이용 표준커널에 포함된 S3C2410 기반 보드들 가운데 SMDK2410 보드가 CORE2410 보드와 가장 유사 SMDK2410 의 기본설정, 소스코드를 이용하여 포팅! make menuconfig 초기화 SMDK2410의 기본설정 이용 # make smdk2410_defconfig arch/arm/configs/smdk2410_defconfig 를 커널 루트 디렉토리의 .config로 카피한다. vi .config CONFIG_ARM = y CONFIG_MMU = y ... CONFIG_ARCH_S3C2410=y CONFIG_ARCH_SMDK2410=y arch/arm/configs : 각각의 ARM 기반 보드에 적합한 초기 매크로세팅 정보를 담고 있다. .config : 커널 컴파일때 참조하는 매크로 들에 대한 설정 파일 Computer Engineering Research Lab, EECS, KAIST
/arch/arm/mach-s3c2410/mach-core2410.c 생성 마찬가지로 smdk2410 보드와의 유사성 이용 make menuconfig에 CORE2410 추가시키기 # cp arch/arm/mach-s3c2410/mach-smdk2410.c arch/arm/mach-s3c2410/mach-core2410.c vi arch/arm/mach-s3c2410/Makefile vi arch/arm/mach-s3c2410/Kconfig ... obj-$(CONFIG_ARCH_CORE2410) += mach-core2410.o ## 추가 ## menu "S3C24XX Implementations" ... config ARCH_CORE2410 ## 추가 ## bool "CORE2410" select CPU_S3C2410 Computer Engineering Research Lab, EECS, KAIST
Booting ARM Linux : Passing Kernel Parameters (1/5) 부트로더로부터 리눅스 커널로의 정보 전달 가정 모든 하드웨어 setup은 부트로더가 담당하고 커널은 부트로더로부터 하드웨어 정보를 전달받는다. 다음 정보들의 전달이 필요 리눅스 머신 타입 … 커널은 타입에 맞는 함수들을 실행 메모리: 전체크기, 시작주소 커널이미지의 주소(physical address), 전체크기 램디스크 위치(physical address), 전체크기 커널 커맨드라인(CMDLINE)의 위치 예: CMDLINE=“root=/dev/nfs ip=### console=### mem=128M” Computer Engineering Research Lab, EECS, KAIST
Booting ARM Linux : Passing Kernel Parameters (2/5) 부트로더로부터 리눅스 커널로의 정보 전달 전달방법 램디스크나 커널 이미지가 overwrite하지 않는 메모리 영역에 parameter들을 저장하고 커널이 이를 읽어감. 일반적으로 (physical RAM start address + 0x100) 에 저장 커널 소스코드 : 매크로를 이용하여 설정 … … compressed ramdisk image 0x30800000 … compressed kernel image 0x30008000 … booting parameters 0x30000100 BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) BOOT_PARAMS(0xa0000100) … booting parameter의 위치 MAPIO(iwuc_map_io) INITIRQ(iwuc_init_irq) INIT_MACHINE(iwuc_init) Computer Engineering Research Lab, EECS, KAIST
Booting ARM Linux : Passing Kernel Parameters (3/5) 본 실험에서의 가정 현재 부트로더는 리눅스 커널의 부팅을 위한 아무런 사전동작을 취하지 않는다. 부트로더에서 kernel parameter를 passing하지 않으므로 커널 내부에서 manual하게 이를 세팅해야 함. Computer Engineering Research Lab, EECS, KAIST
Booting ARM Linux : Passing Kernel Parameters (4/5) vi arch/arm/kernel/setup.c 본 실험에서는 이 init_tags를 이용하여 kernel parameters를 세팅한다. void __init setup_arch(char **cmdline_p) { struct tag *tags = (struct tag *)&init_tags; setup_processor(); mdesc = setup_machine(machine_arch_type); machine_name = mdesc->name; if (mdesc->param_offset) tags = phys_to_virt(mdesc->param_offset); if (tags->hdr.tag != ATAG_CORE) convert_to_tag_list(tags); tags = (struct tag *)&init_tags; if (mdesc->fixup) mdesc->fixup(mdesc, tags, &from, &meminfo); if (tags->hdr.tag == ATAG_CORE) { if (meminfo.nr_banks != 0) squash_mem_tags(tags); parse_tags(tags); } 앞서 지정한 주소 (0x30000100)에서 kernel parameter를 읽어온다. 유효한 tag가 없으면 init_tags를 default로 로딩한다. kernel parameter tag를 해석한다. Computer Engineering Research Lab, EECS, KAIST
Booting ARM Linux : Passing Kernel Parameters (5/5) vi arch/arm/kernel/setup.c static struct init_tags { .... } init_tags __initdata = { { tag_size(tag_core), ATAG_CORE }, { 1, PAGE_SIZE, 0xff }, { tag_size(tag_mem32), ATAG_MEM }, { 64*1024*1024, PHYS_OFFSET }, { tag_size(tag_ramdisk), ATAG_RAMDISK }, { 0, 10*1024, 0 }, { tag_size(tag_initrd), ATAG_INITRD }, { __phys_to_virt(0x30800000), 8*1024*1024}, { 0, ATAG_NONE } }; 메모리 사이즈는 64M 이다. 압축이 풀린 램디스크는 10M (이하) 이다. 압축된 램디스크는 8M (이하) 이다. 이는 0x30800000 에 위치한다. 이상적으로는, 이러한 하드웨어 관련 초기화가 모두 부트로더에서 이루어지고 설정된 결과만 kernel parameter 형태로 커널로 넘어옴으로써, 커널은 하드웨어 초기화에 관여할 필요도 없고, 하드웨어 관련 설정이 변경되어도 커널을 수정할 필요가 없는 형태일 것이다. Computer Engineering Research Lab, EECS, KAIST
Kernel Startup Entry Point 로딩된 커널이미지의 압축이 풀린 후 가장 먼저 시작되는 entry point vi arch/arm/kernel/head.S ENTRY(stext) mov r12, r0 mov r0, #PSR_F_BIT | PSR_I_BIT | MODE_SVC msr cpsr_c, r0 bl __lookup_processor_type teq r10, #0 moveq r0, #'p' beq __error bl __lookup_architecture_type teq r7, #0 moveq r0, #'a' beq __error bl __create_page_tables adr lr, __turn_mmu_on add pc, r10, #12 SVC mode로 진입, IRQ를 끈다. processor ID를 읽어와 올바른지 체크 architecture_type을 읽어와 올바른지 체크 page_table 생성 MMU를 켠다. 이 entry point 진입 이전에 부트로더가 r1 register를 통해 machine_nr를 넘겨주어야 한다. 여기서는 부트로더가 이를 안해준다고 가정한다. Computer Engineering Research Lab, EECS, KAIST
Kernel Startup Entry Point vi arch/arm/mach-s3c2410/mach-core2410.c MACHINE_START(CORE2410, "CORE2410") vi arch/arm/mach-s3c2410/mach-core2410.c #define MACHINE_START(_type,_name) \ const struct machine_desc __mach_desc_##_type \ __attribute__((__section__(".arch.info"))) = { \ .nr = MACH_TYPE_##_type, \ .name = _name, vi arch/arm/tools/mach-types core2410 ARCH_CORE2410 CORE2410 627 vi arch/arm/kernel/head.S ENTRY(stext) mov r1, #627 Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST Ethernet 장치 드라이버 설정 CS89x0 항목이 보이지 않는다. drivers/net/Kconfig config CS89x0 tristate "CS89x0 support" depends on NET_PCI && (ISA || ARCH_IXDP2X01) ## 삭제 ## Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST Ethernet 장치 드라이버 설정 CS89x0 장치를 위한 address space, IRQ 설정 CORE2410 보드에서 CS89x0 은 bank3 (0x18000000)에 연결됨 IRQ는 EINT9 에 연결됨 arch/arm/mach-s3c2410/mach-core2410.c static struct map_desc smdk2410_iodesc[] __initdata = { { 0xF1300000, 0x18000000, 0x00100000, MTDEVICE }, /* virtual addr, physical addr, addr space */ }; drivers/net/cs89x0.c ... #elif defined(CONFIG_ARCH_CORE2410) static unsigned int netcard_portlist[] __initdata = { 0xF1300300, 0}; /* 장치주소의 시작번지 (virtual addr) */ static unsigned int cs8900_irq_map[] = { IRQ_EINT9, 0, 0, 0}; /* 장치의 IRQ number */ On power up, the default value of the I/O base address is set at 300h. Note that 300h is typically assigned to LAN peripherals. Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST Ethernet 장치 드라이버 설정 cs89x0.c 추가로 수정될 부분 실험교재 참조 GPIO 세팅 필요함 테스트 # mount /proc # /sbin/ifconfig eth0 143.248.xxx.xxx netmask 255.255.255.0 up 이를 실행하면 kernel panic이 발생함 (수강생이 각자 해결; main-report 문제) Computer Engineering Research Lab, EECS, KAIST
make menuconfig 수정, 최종 컴파일 System Type > S3C24XX Implementation : CORE2410 선택 General Setup > Default kernel command string "root=/dev/ram rw init=/bin/bash console=ttySAC0" Let's compile it ! make zImage Kernel Image, Ramdisk loading ramdisk : 0x30800000 (same as before) kernel image : 0x30f00000 (same as before) Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST 예비레포트 참고문헌 (Wonderful World of Linux 2.6)을 참조하여 2.4와 2.6에서 어떤 점들이 달라졌는지 간단히 나열해 보시오. 특별히 관심이 있는 한 가지를 선택하여 2.4의 코드와 2.6의 코드를 비교해가며 코드 수준에서 그 변화를 설명해 보시오. Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST 결과레포트 지금까지의 설명을 참조하여 CORE2410보드에 linux 2.6.10을 포팅하여 프롬프트가 뜨는 것 까지를 확인하시오. 그리고 ethernet 장치가 잘 인식되어 TCP/IP 통신이 잘 이루어지는지를 확인하시오. 잘 되었다면 linux 2.6.10 표준 배포 커널과 수정된 커널 사이에서 diff 연산을 수행해서 자신만의 커널 패치를 생성하여 보시오. (이 커널 패치를 데모시 제출바람) ifconfig up을 할 때 kernel panic이 발생하는 문제를 해결해 보시오. (+) 보드에 physical memory가 연속적으로 있는 것이 아니라 Bank6 (0x3800_0000) 에 64M , Bank7 (0x4000_0000) 에 64M가 붙어있다고 가정하자. 이를 리눅스에서 정상적으로 인식하여 128M 모두를 사용하기 위해서는 어떻게 코딩해주어야 겠는가? 설명하시오. Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST 결과레포트 (+) 현재 램디스크를 루트 파일 시스템으로 하여 2.6.10을 부팅하였다. NFS를 루트파일시스템으로 하여 부팅해 보시오. (+) Pre-report에서 특별히 관심이 있는 부분을 선택해서 2.4와 2.6을 비교해 보았을 것이다. 그 성능차이를 볼 수 있는 간단한 실험을 설계해 보시오. 그리고 지금까지 사용했던 2.4.18 커널과 이번에 새롭게 만든 2.6.10 커널에 대해 실험을 수행하고 그 결과를 비교해 보시오. 원하는 결과가 나오는가? Computer Engineering Research Lab, EECS, KAIST
Computer Engineering Research Lab, EECS, KAIST 참고문헌 "Linux Device Driver", Allessandro Rubini 저, O'reilly 출판사 "Booting ARM Linux", www.simtec.co.uk/products/ SWLINUX/files/booting_article.html "Wonderful World of Linux 2.6 - Joe Pranevich" www.kniggit.net/wwol26.html S3C2410 User's Manual Computer Engineering Research Lab, EECS, KAIST