Microsoft Word - u-boot porting to PXA270.doc

Similar documents
KEY 디바이스 드라이버

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

슬라이드 제목 없음

DE1-SoC Board

ISP and CodeVisionAVR C Compiler.hwp

휠세미나3 ver0.4

Microsoft Word - FS_ZigBee_Manual_V1.3.docx

[8051] 강의자료.PDF

PowerPoint 프레젠테이션

SRC PLUS 제어기 MANUAL

PowerPoint 프레젠테이션

Microsoft Word - FunctionCall

MAX+plus II Getting Started - 무작정따라하기

Microsoft PowerPoint - LN_2_Bootloader.ppt [호환 모드]

Mango220 Android How to compile and Transfer image to Target

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A634C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

untitled

목차 1. 제품 소개 특징 개요 Function table 기능 소개 Copy Compare Copy & Compare Erase

RealDSP UT 프로그램 메뉴얼

PowerChute Personal Edition v3.1.0 에이전트 사용 설명서

CD-RW_Advanced.PDF

Solaris Express Developer Edition

슬라이드 1

PowerPoint 프레젠테이션

CANTUS Evaluation Board Ap. Note

Sena Technologies, Inc. HelloDevice Super 1.1.0

PRO1_04E [읽기 전용]

강의10

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

Remote UI Guide

Microsoft Word ARM_ver2_0a.docx

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A636C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

Microsoft Word - 1. ARM Assembly 실습_xp2.doc

(SW3704) Gingerbread Source Build & Working Guide

PowerPoint 프레젠테이션

Microsoft Word doc

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

Mango-IMX6Q mfgtool을 이용한 이미지 Write하기

Microsoft PowerPoint Android-SDK설치.HelloAndroid(1.0h).pptx

APOGEE Insight_KR_Base_3P11

10X56_NWG_KOR.indd

API 매뉴얼

Here is a "PLDWorld.com"... // EXCALIBUR... // Additional Resources // µc/os-ii... Page 1 of 23 Additional Resources: µc/os-ii Author: Source: HiTEL D

Microsoft PowerPoint - ch07.ppt

Mango-AM335x LCD Type 커널 Module Parameter에서 변경하기

R50_51_kor_ch1

Mango-E-Toi Board Developer Manual

1

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

<4D F736F F F696E74202D C61645FB3EDB8AEC7D5BCBA20B9D720C5F8BBE7BFEBB9FD2E BC8A3C8AF20B8F0B5E55D>

2. GCC Assembler와 AVR Assembler의차이 A. GCC Assembler 를사용하는경우 i. Assembly Language Program은.S Extension 을갖는다. ii. C Language Program은.c Extension 을갖는다.

슬라이드 1

Microsoft Word - Armjtag_문서1.doc

Copyright 2012, Oracle and/or its affiliates. All rights reserved.,.,,,,,,,,,,,,.,...,. U.S. GOVERNMENT END USERS. Oracle programs, including any oper

API 매뉴얼

MPLAB C18 C

untitled

슬라이드 1

hd1300_k_v1r2_Final_.PDF

Microsoft PowerPoint - 02-Development-Environment-1.ppt

PowerPoint 프레젠테이션

지난시간에... 우리는 kernel compile을위하여 cross compile 환경을구축했음. UBUNTU 12.04에서 arm-2009q3를사용하여 간단한 c source를빌드함. 한번은 intel CPU를위한 gcc로, 한번은 ARM CPU를위한 gcc로. AR

Microsoft PowerPoint - 알고리즘_1주차_2차시.pptx

Chapter 1

본교재는수업용으로제작된게시물입니다. 영리목적으로사용할경우저작권법제 30 조항에의거법적처벌을받을수있습니다. [ 실습 ] 스위치장비초기화 1. NVRAM 에저장되어있는 'startup-config' 파일이있다면, 삭제를실시한다. SWx>enable SWx#erase sta

PRO1_09E [읽기 전용]

목차 1. 개요 USB 드라이버 설치 (FTDI DRIVER) FTDI DRIVER 실행파일 USB 드라이버 확인방법 DEVICE-PROGRAMMER 설치 DEVICE-PROGRAMMER

CPX-E-EC_BES_C_ _ k1

Microsoft PowerPoint - es-arduino-lecture-03

untitled

Chapter ...

Orcad Capture 9.x

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

untitled

Microsoft PowerPoint - ARM 개발 환경.ppt

-. Data Field 의, 개수, data 등으로구성되며, 각 에따라구성이달라집니다. -. Data 모든 의 data는 2byte로구성됩니다. Data Type는 Integer, Float형에따라다르게처리됩니다. ( 부호가없는 data 0~65535 까지부호가있는

untitled

K7VT2_QIG_v3

Microsoft Word _whitepaper_latency_throughput_v1.0.1_for_

1. What is AX1 AX1 Program은 WIZnet 사의 Hardwired TCP/IP Chip인 iinchip 들의성능평가및 Test를위해제작된 Windows 기반의 PC Program이다. AX1은 Internet을통해 iinchip Evaluation

Microsoft Word - logic2005.doc

Microsoft Word - PEB08_USER_GUIDE.doc

chapter4

Microsoft PowerPoint - System Programming Lab Week1.ppt [호환 모드]

BY-FDP-4-70.hwp

슬라이드 1

MicrocontrollerAcademy_Lab_ST_040709

LCD Monitor

DSP_MON 프로그램 메뉴얼

vi 사용법

Microsoft PowerPoint - e7.pptx

-. emlinux,......,..,..,.

Transcription:

u-boot 1.1.2 Porting Guide for PXA27x v 0.01 2005.12.21 김기오 (gurugio@gmail_nospam.com) http://www.asmlove.co.kr http://wiki.kldp.org/wiki.php/gurugio

알림. 이문서는개인적인참고자료의모음과연구실내부에서신입생교육에사용될개인적인자료입니다. 혹시저작권이나기타위반사항등이발견되면언제라도연락주시면즉시바로잡도록하겠습니다. 이문서는개인적인참고용도로만사용될수있습니다. 김기오 (gurugio@gmail_nospam.com.nospam) update. 2005 년 12 월 18 일 kldp.wiki 등록 2005 년 12 월 20 일레지스터설명, 관련코드추가 v. 0.01

플래시프로그래머포팅 먼저인텔에서 jflashmm 프로그램을다운받는다. 이프로그램은윈도우전용이다. 먼저윈도우에설치해서보드를인식하는지테스트하고소스를리눅스로옮기고 Makefile 을만들어서포팅한다. JFlashmm 다운로드주소 http://www.intel.com/design/pca/applicationsprocessors/swsup/jflashmm.htm 인텔은다운로드주소를수시로바꾸므로인텔홈페이지에서검색한다. JFlash_MM_V5_01_007.exe 이라는프로그램을설치하면디렉토리안에 Flash_88XX~~.dat 라는설정파일들과 Source.zip 소스파일등이있다. 프로그램을설치한후에 RelNode_JFlashmm.htm 을읽으면서 giveio.inf 드라이버파일을윈도우에설치한다. 그래야프로그램이정상적으로작동된다. 그리고보드를만들때프로세서와플래쉬, 램등최소한의장치만조립하고윈도우에설치된 JFlashmm 로동작을테스트한다. 그런데한가지빠진파일이있는데 bulbcx.dat 파일이다. http://www.linuxgazette.com/node/9786 문서는 2.4 커널을 mainstone 보드에포팅하는문서인데 bulbcx.dat 에대해다음과같이말하고있다. Connect the parallel port connector to MAIN JTAG (J4) and parallel port on your computer. Secondly copy the bulbcx.dat and blob-smc files to the folder where the jflash is installed. Ex: C:\Program Files\Intel Corporation\JFlash_MM\ Bulbcx.dat: Has the information about the processor and the board. And it is provided by the board manufacturer. 이파일을인터넷에서구해서 jflash 폴더에복사한다. 그리고다음과같이실행해본다.

i 옵션으로실행해서플래시와프로세서를인식하는지를확인한다. 여기까지된다면프로세서와플래시메모리는동작하는것이다. 다음으로 Source.zip 과 *.dat 설정파일들을리눅스로복사한다. * jflashmm 을포팅하는것은수정할양이많으므로일단하이버스에서제공한시디에있는 jflashmm 을사용한다. 추후참고자료를구하거나시간이날때다시분석한다. 하이버스에서제공하는설정파일 pxa27x32.dat 는 bulbcx.dat 와같은파일이다. 따라서 bulbcx.dat 를사용한다. ** 리눅스로복사한소스중 Global_variable.h 에서 41 줄에있는 CABLE_TYPES 를 Parallel_Jtag 에서 Insight_Jtag 으로수정한다. 원래인텔에서제공하는 jflashmm 소스를보면이부분이 Insight_Jtag 으로되어있어서이렇게고친다. Parallel Jtag 타입으로컴파일하면인식을못하고 JTag 에서나오는신호가다르다.

Jflash.cpp 에는다음과같이 jtag 케이블타입에대해처리하는부분이있다. HYBUS 에서사용하는 jtag 은패러럴케이블을바로보드에연결하는형태인데프린터포트의 5 번이 ntrst, 2 번이 TCK, 3 번이 TDI, 11 번이 TDO, 4 번이 TMS 로사용되고있지만일반적으로현재연구실에서사용하는 jtag 케이블과다른것같다. 362 // Compare the selected cable name with all supported cables 363 if (!strcmp("ins", Cable_Type)){ 364 CableType = Insight_Jtag; 365 else if (!strcmp("par", Cable_Type)){ 366 CableType = Parallel_Jtag; 367 케이블타입에따라서출력하는신호가다르다. 938 if(cabletype == Parallel_Jtag) 939 { 940 // TMS is D2, TDI is D1, and TCK is D0, so construct an output b y creating a 941 // rising edge on TCK with TMS and TDI data set. 942 /* fixed */ 943 _outp(lpt_address, tms*4+tdi*2+8); // TCK low 944 _outp(lpt_address, tms*4+tdi*2+1+8); // TCK high 945 946 // if we want to read the port, set TCK low because TDO is sampl ed on the 947 // TCK falling edge. 948 /* fixed */ 949 if(rp == READ_PORT) 950 _outp(lpt_address, tms*4+tdi*2+8); // TCK low 951 if(rp == READ_PORT) 952 tdo =!((int)_inp(lpt_address + 1) >> 7); // get TDO data 953 954 else if (CableType == Insight_Jtag) 955 { 956 // There's some bit clearing here that isn't needed. It should m ake this 957 // code easier to understand. 958 959 //defines for the INSIGHT IJC-1 JTAG cable 960 961 /* the output port (lpt_address) */ 962 #define INSIGHT_DIN 0x01

963 #define INSIGHT_CLK 0x02 964 #define INSIGHT_TMS_IN 0x04 965 966 /* Output Enable for the standard JTAG outputs 967 (not TDO since this is an output from the 968 chip we want to talk to */ 969 #define ninsight_ctrl 0x08 970 #define ninsight_prog 0x10 /* This causes the TDO line to be driven. We'll leave it high.*/ 971 972 973 /*the input port (lpt_address + 1)*/ 974 #define TDO_INPUT 0x10 975 #define TDO_INPUT_BITPOS 4 976 977 int lpt_data; 978 979 //form the data we want to write to the parallel port 980 lpt_data = ninsight_prog; //Output to TDO off 981 lpt_data &= ~ninsight_ctrl; //Enable the outputs 982 983 if(tms == 1) lpt_data = INSIGHT_TMS_IN; 984 if(tdi == 1) lpt_data = INSIGHT_DIN; 985 986 // construct an output by creating a 987 // rising edge on TCK with TMS and TDI data set. 988 lpt_data &= ~INSIGHT_CLK; 989 _outp(lpt_address, lpt_data); // TCK low 990 991 lpt_data = INSIGHT_CLK; 992 _outp(lpt_address, lpt_data); // TCK high 993 994 // if we want to read the port, set TCK low because TDO is sampl ed on the 995 // TCK falling edge. 996 if(rp == READ_PORT) 997 { 998 lpt_data &= ~INSIGHT_CLK; 999 _outp(lpt_address, lpt_data); // TCK high??? Low? 1000 tdo = ((int)_inp(lpt_address + 1) & TDO_INPUT) >> TDO_INPUT_ BITPOS; // get TDO data 1001 1002 다음과유사하게출력되야 JFlashmm 과보드의프로세서와플래시메모리가동작한다는것을알수있다.

JTAG 동작을테스트하는방법 1. 프린터포트를이용하여 jtag 을사용할때프린터포트는 5V 로동작한다. jtag 은 3V 에서동작하기때문에이것을변환하는회로가필요하다. 다음은삼성에서만든 Secjtag 의회로도이다. 그리고다음은 falinux 의강좌일부를복사한것이다. 0.2 JTAG 회로이회로를보통은동글이라고말합니다. 그림 0.2.a JTAG에대해선설명하지않겠습니다. 유영창님강좌에넘잘나왔으니까...

대부분의칩들은동작전압이 3.3V 입니다. PC 의프린터포트는 5V 이구요.. 전압이틀린것을알수있죠. 틀리전압이만나면어떻게될까요.. 쎈넘이쎄다고 5V 가 3.3V 를밀어냅니다. 1.7V 의차만큼 3.3V 입장에서마이너스전원이걸리는셈이지요. 하지만칩들은 TR 의집합이므로이런전원이걸지지않습니다. 하지만데이타라인은약 4.3V 정도걸리지요.. 문제는이런것이아니고데이타버스가흔들리는것입니다. 이런흔들림에의해서인근의라일들까지잡음이끼게되지요 ( 높은물과낮은물이갑자기만나면물이흔들리는것과같은이치이지요.) 스코프를찍어보면이런파형이나옵니다. 그림 0.2.b 동글은전압이다른두칩의연결시이런잡음등으로칩을보호하는회로입니다. 보통은 74HC245, 74HC125 등의단전원칩을사용하기도하고 3.3V, 5V 의양전원이들어가는 74LV245 등을쓰기도합니다. 74HC245, 74HC125 는 3.3V 전원을인가하는데이것도어차피 5V 와만나면서잡음이발생합니다. 여기서잡음을최소화하기위해저항과콘덴서를연결합니다. 저항의효과는두전원의전압차를이저항이전압을갖게되는것이고콘덴서는항상쓰는방식대로흔들림을잡아주죠.. 저항값을 200 옴으로쓰는이유는잘모르구요.. 테스트한결과 100~200 이무난합니다. 다른회로도이값을씁니다. 콘덴서 220pF 을쓰는이유는프린터포트의속도가최대 1.5usec 이므로이시간에서큰값으로설정한것입니다. 어찌됬건 74HC 씨리즈는 CMOS 로폭넓은동작전원을가지고있어아주유용합니다. 여담 1: 저항을그저저항으로생각하지마시고... 전자라는넘이길을가다거치른저항을만나면힘이빠집니다. 잡음의폭이그만큼준다는야그지요.. 왜전압이약간떨어지니까.. 글구전자가저항을만나면진행속도가느려지죠.. 이건파형이그만큼늘어진다는야그고요 여담 2: 예전 MP3 플레이어중프린트포트를사용하는제품은이잡음땜에무지고생했습니당.. ㅡ. ㅡ 다음강좌는 DC/DC 전원에대해알아보겠습니다. 그럼전휘리릭 ~~~~ [ 소유권 ] 이문서지적소유권은 ( 주 ) 제이닷디엔티에있다. 문서에관련된문의사항이있다면 freefrug@falinux.com 으로연락바란다

이렇게살펴보고 jtag 케이블이회로에맞게설계되었는지전압이올바르게출력되는지를확인한다. 2. TDI, TMS, TCLK 의신호가발생하는가?\ 예를들어보드를켜지않은상태에서 jtab 을연결시키고다음과같은명령을실행한다면, jflashmm bulbcx testfile.bin i 오실로스코프를 1ms 단위정도로조정하고 TDI 와 TCLK 을측정하면아주짧게라도신호가나올것이다. 이정도신호가나온다면일단 jtag 케이블은동작이된다고판단해도좋다. 3. Bulberde 에서 ntrst 에 high 신호가인가되어있는지확인한다. 4. jflashmm bulbcx testfile.bin i 로실행해서 identification 이되는지확인한다. 5. 2005-11-25 현재 SKKU 보드를이와같은방법으로확인함

JTAG 동작확인후하드웨어테스트 JTAG 이동작한다는것은프로세서와플래시메모리가동작한다는것을뜻한다. 여기서보다확실하게보드가동작하는지또 JTAG 이프로그램을정상적으로퓨징할수있는지확인하기위해서간단하게 LED 를깜박이고시리얼에문자를출력하는프로그램을만들어본다. 꼭 LED 가있어야하는건아니고 GPIO 하나를골라서주기적으로신호를보내서오실로스코프로파형이발생하는지확인하면된다. Falinux 의 EZ-X5 보드는 4 개의 LED 를달아서실행도중오류에따라다르게 LED 를깜박거린다. 따라서어디에서오류가발생했는지짐작할수있게하였다. 보드를설계할때이렇게디버깅을위한고려도하면개발시간을아낄수있다. 가장먼저해야할일은적당한 GPIO 를고르는것이다. SKKU 보드에는따로보드동작을위한 LED 가없으므로임시로현재사용하지않는오디오칩에관련된 GPIO<30> 을사용한다. PXA270 의 GPIO 는입력과출력으로나눠지고입력과출력각각에따라 3 가지기능이있다. 즉하나의 GPIO 핀이 6 가지의기능을가지고있는샘이다. GPIO 를사용하기전에어떤기능으로사용해야할지를결정해서입출력을결정하는레지스터와기능을결정하는레지스터를설정해주면된다. Intel PXA27x Processor Family Developer s Manual 에 24 장 General-Purpose I/O Controller 에서 Table 24-2 를보면핀이름과기능들이나열되어있다. 회로에따라여기서기능을선택하여 GPIO 설정레지스터의값들을결정하면된다. GPIO 를설정하는레지스터는 GPLR, GPDR, GPSR, GPCR, GRER, GFER, GEDR, GAFR 이있다. Intel PXA27x Processor Family Developer s Manual 에서테이블 24-41 을보면끝부분에 96 번이상의 GPIO 를설정하는레지스터가따로있는것을알수있다. 이는 PXA270 에서 PXA250 부터사용된 GPIO 이외에추가됐기때문이다. 각레지스터를간략하게설명하면다음과같다. - GPLR : 읽기전용상태레지스터, High/Low 상태를알수있다. - GPDR : 입출력방향설정 - GPSR : Set, 하이신호인가 - GPCR : Clear, 로우신호인가 - GRER/GFER : Rising Edge 디텍트, Falling Edge 디텍스. GEDR 에디텍트된결과값이출력된다. 만약 Rising Edge 디텍트기능을사용한다면해당핀에 Rising edge 가발생할때마다 GEDR 의해당비트가 1 로셋팅되고이비트에 1 을쓰면 0 으로클리어하게된다. - GEDR : GRER/GFER 에설정한대로 Edge 를디텍트하면 1 로설정되고 1 을써주어서셋팅된값을클리어한다. - GAFR : 하나의 GPIO 마다 2 비트씩설정할수있다. 0 은 GPIO 로사용하는것이고 1~3 은테이블 24-2 에나온기능들을사용하도록설정하는것이다. 회로도에따라어떤기능을사용하는지세심하게결정해서이값을결정해야한다. 예를들어 GPIO<30> 에관련된설명을보면입력으로는따로사용되는기능이없고출력으로는 I2S_SDATA_OUT, AC97_SDATA_OUT, USB_P3_2 에사용된다고써있다. GAFR0_L 레지스터에서 28,29 번비트의설정값을 00 으로해주면이런기능들이아니라 GPIO 로사용된다. 그리고 GPDR0 의 30 번비트를 1 로셋팅해서출력으로설정해주면된다. GPSR0 의 30 번비트에 1 을써서하이값을출력하고잠시후에 GPCR0 의 30 번비트에 1 을써서로우값을출력하고잠시후에다시하이값을출력하는일을반복하면된다. 현재보드에는오디오에관련된칩을부착하지않고오직프로세서와메모리, 전원관련칩들만부착했으므로신경쓰지말고오실로스코프로오디오칩의 AC97_SDATA_OUT 핀을찍어보면서프로그램동작을확인하면된다. FFUART 를사용하기위해서테이블 24-2 와 SKKU 보드의회로도를보면 GPIO<34> ~ GPIO<41> 을사용하는것을알수있다. GPIO<34> ~ GPIO<38> 은입력으로, GPIO<39> ~ GPIO<41> 은출력으로사용된다. 각핀의사용법은다음과같다.

- GPIO<34> : FFRXD - GPIO<35> : FFCTS - GPIO<36> : FFDCD - GPIO<37> : FFDSR - GPIO<38> : FFRI - GPIO<39> : FFTXD - GPIO<40> : FFDTR - GPIO<41> : FFRTS PXA270 의 UART 에는 SUART(Standard UART) 와 FFUART(Full Function UART) 가있다. 이름에서알수있듯이 SUART 에는 TxD 와 RxD 만이있다. Mainstone 보드에는 FFUART 를사용하므로 SKKU 에도동일하게구성했다. 이후의프로그램소스와컴파일과정등은마이크로소프트 2003 년 10 월부터유영창님께서연재하신 ARM 부트로더제작기 를참조하여만들었다. gcc 버전에따라달라진내용과우리보드에맞게수정한내용을주로설명한다. 다음그림은오디오칩회로도의일부를나타낸것이다. AC97_SDATA_OUT 이 5 번핀으로되어있다.

다음그림은 UART 회로이다. 다음은 led.s 이다. 소스를자세히이해하기위해서는 ARM 관련서적을참조해서어셈블리명령어를익혀야한다. 그리고 GPIO 설정레지스터의주소값은 Intel PXA27x Processor Family Developer s Manual 에 24 장 General-Purpose I/O Controller 에서 24.6 Register Summary 를참조한다. 레지스터들의물리메모리주소를알수있다. 또 UART 의설정에대해서는 Intel PXA27x Processor Family Developer s Manual 의 10 장 UARTs 를읽어본다. 현재소스는간단한동작만을하므로 u- boot 1.1.2 에서 C 로작성된초기화함수와한문자출력함수를보고어셈블리로변경만해서작성한것이다. GPIO 관련레지스터들의시작주소는 0x40e00000 이다. Intel PXA27x Processor Family Developer s Manual 에서 24.6 Register Summary 에있는테이블에보면가장먼저 GPLR0 레지스터가있고시작주소가 0x40e00000 인것을알수있다. 그리고다른레지스터들의오프셋값도이테이블을참조하면알수있다. 각레지스터의주소값. GPIO<30> 은첫번째설정레지스터에서설정된다. 11 // GPIO Pin Direction register GPDR0/1/2/3 12 #define GPDR0 0x40e0000c 13 // GPIO Pin Output Set register GPSR0/1/2/3 => set high 14 #define GPSR0 0x40e00018 15 // GPIO Pin Output Clear register GPCR0/1/2/3 => set low 16 #define GPCR0 0x40e00024 17 GPIO<34> ~ GPIO<41> 은각기두번째레지스터에서설정된다. 18 #define GPDR1 0x40e00010 19 #define GPSR1 0x40e0001c 20 #define GPCR1 0x40e00028 21 #define GAFR1_L 0x40e0005c 22 GPIO 출력값을설정하고루프를돌면서대기하는횟수

23 #define WAIT_TIME_NOCACHE 0xf0000 GPIO 번호. 우리는 30 번 GPIO 를이용하므로 GPDR0 의 30 번비트를사용한다. 따라서 1<<30 으로값을설정한다. 24 #define DEBUG_LED (1<<30) 25 u-boot 1.1.2 소스에서복사한 FFUART 설정레지스터 26 /* Full Function UART (FFUART) */ 27 #define FFUART 0x40100000 28 #define FFRBR 0x40100000 /* Receive Buffer Register (read only) */ 29 #define FFTHR 0x40100000 /* Transmit Holding Register (write only) */ 30 #define FFIER 0x40100004 /* Interrupt Enable Register (read/write) */ 31 #define FFIIR 0x40100008 /* Interrupt ID Register (read only) */ 32 #define FFFCR 0x40100008 /* FIFO Control Register (write only) */ 33 #define FFLCR 0x4010000C /* Line Control Register (read/write) */ 34 #define FFMCR 0x40100010 /* Modem Control Register (read/write) */ 35 #define FFLSR 0x40100014 /* Line Status Register (read only) */ 36 #define FFMSR 0x40100018 /* Modem Status Register (read only) */ 37 #define FFSPR 0x4010001C /* Scratch Pad Register (read/write) */ 38 #define FFISR 0x40100020 /* Infrared Selection Register (read/write) */ 39 #define FFDLL 0x40100000 /* Divisor Latch Low Register (DLAB = 1) (read/write) */ 40 #define FFDLH 0x40100004 /* Divisor Latch High Register (DLAB = 1) (read/write) */ 41 클럭설정레지스터. FFUART 에들어가는클럭을활성화시킨다. 42 #define CKEN 0x41300004 /* Clock Enable Register */ 43 #define CKEN6_FFUART (1<<6) /* CKEN[6] = FFUART unit clock enable 44 FFLCR 의설정값 45 #define LCR_WLS0 (1) /* 46 #define LCR_WLS1 (1 << 1) 47 #define LCR_DLAB (1 << 7) 48 기타 FFUART 설정값 Baudrate 는 38400bps 로하고 8-N-1 로설정한다. 49 #define QUOT 24 /* 38400 */ 50 #define IER_UUE (1 << 6) 51 FFUART 를사용하기위한 GPIO 설정값. 반드시한비트씩확인해서이해할것 52 #define CFG_GPDR1_VAL 0x00000380 53 #define CFG_GPSR1_VAL 0x00000000 54 #define CFG_GPCR1_VAL 0x00000380 55 #define CFG_GAFR1_L_VAL 0x0000a950 56 57.text 58 59.global _start 60 61 _start: 62 63 b reset 64 b undefined_instruction 65 b software_interrupt 66 b prefetch_abort 67 b data_abort 68 b not_used 69 b IRQ 70 b FIQ 71 72 73 reset: 74 GPIO<30> 를출력으로지정 76 ldr r1, =DEBUG_LED

77 78 // set direction of 4th bit as output 79 ldr r0, =GPDR0 // r0 = PXA_REG_GP_BASE 80 str r1, [r0] // [r0+gpdr0] = r1 81 로우신호인가 82 // set 4th bit as low -> turn on LED 83 ldr r0, =GPCR0 84 str r1, [r0] // [r0+gpcr0] = r1 85 86 FFUART를위한 GPIO 설정 87 GPIO_init: 88 /* GPIO<34-41> are used for FFUART */ 89 /* GPIO<34-41> are controlled by GPLR1, GPSR1, GPCR1, CPDR1, 90 GRER1, GFER1, GEDR1, GAFR1_L */ 91 /* GPIO<34-38> are used as INPUT, Function 1 */ 92 /* GPIO<39-41> are used as OUTPUT, Function 2 */ 93 /* GPDR1 = 0x380 */ 94 /* GPSR1 = 0x0 */ 95 /* GPCR1 = 0x380 */ 96 /* GRER1,GFER1,GPLR1 = don't care */ 97 /* GAFR1_L = 0xa950 */ 98 ldr r0, =GPSR1 99 ldr r1, =CFG_GPSR1_VAL 100 str r1, [r0] 101 102 ldr r0, =GPCR1 103 ldr r1, =CFG_GPCR1_VAL 104 str r1, [r0] 105 106 ldr r0, =GPDR1 107 ldr r1, =CFG_GPDR1_VAL 108 str r1, [r0] 109 110 ldr r0, =GAFR1_L 111 ldr r1, =CFG_GAFR1_L_VAL 112 str r1, [r0] 113 FFUART를위한초기화과정 순서를이대로지켜서해야함 114 serial_init: 115 /* CKEN = CKEN6_FFUART */ 116 /* Enable FFUART clock */ 117 ldr r0, =CKEN 118 ldr r1, [r0] 119 ldr r2, =CKEN6_FFUART 120 orr r1, r1, r2 121 str r1, [r0] 122 123 /* FFIER = FFFCR = 0 */ 124 /* Disable interrupts and FIFOs */ 125 mov r0, #0 126 ldr r1, =FFIER 127 ldr r2, =FFFCR 128 str r0, [r1] 129 str r0, [r2] 130 131 /* FFLCR = LCR_WLS0 LCR_WLS1 LCR_DLAB */ 132 /* 8bit character, Access Divisor Latch registers (DLL, DLH) */ 133 mov r1, #LCR_WLS0 134 orr r1, r1, #LCR_WLS1 135 orr r1, r1, #LCR_DLAB 136 ldr r0, =FFLCR 137 str r1, [r0]

138 139 /*FFDLL = QUOT & 0xff, low byte of baudrate */ 140 mov r1, #QUOT 141 ldr r0, =FFDLL 142 str r1, [r0] 143 144 /* FFDLH = QUOT >> 8, high byte of baudrate */ 145 mov r1, #0 146 ldr r0, =FFDLH 147 str r1, [r0] 148 149 /* FFLCR = LCR_WLS0 LCR_WLS1 */ 150 /* Clear DLAB bit */ 151 mov r1, #LCR_WLS0 152 orr r1, r1, #LCR_WLS1 153 ldr r0, =FFLCR 154 str r1, [r0] 155 156 FFUART 동작시작 157 /* FFIER = IER_UUE */ 158 /* Enable UART unit */ 159 mov r1, #IER_UUE 160 ldr r0, =FFIER 161 str r1, [r0] 162 원본소스에는 mov 명령어를사용하지만 30번비트를조작하므로오퍼랜드범위가 12비트를 넘는다. ARM에서오퍼랜드의크기는 12비트가한계이므로 mov 명령어가아니라 ldr 명령어를 사용한다. 163 ldr r1, =DEBUG_LED 164 일정시간딜레이 165 B10: 166 mov r4, #WAIT_TIME_NOCACHE // r4 = WAIT.. 167 B20: 168 nop 169 nop 170 subs r4, r4, #1 // r4 = r4-1 & effect CPSR 171 bne B20 // if NE(not equal) is set (r4!= 0), branch to B20 172 GPIO<30> 에로우신호인가 173 // set 4th bit as high -> turn off LED 174 ldr r0, =GPSR0 175 str r1, [r0] // [r0+gpsr0] = r1 176 177 mov r4, #WAIT_TIME_NOCACHE // r4 = WAIT_TIME_NOCACHE 178 179 B30: 180 nop 181 nop 182 subs r4, r4, #1 183 bne B30 184 GPIO<30> 에하이신호인가 185 // turn on LED 186 ldr r0, =GPCR0 187 str r1, [r0] 188 시리얼에 0 출력 189 // serial_putc(0) 190 mov r2, #0x30 191 ldr r3, =FFTHR 192 str r2, [r3]

193 194 b B10 195 196 error_loop: 197 198 undefined_instruction: 199 software_interrupt: 200 prefetch_abort: 201 data_abort: 202 not_used: 203 IRQ: 204 FIQ: 205 206 b error_loop 207 208 // Here is end of program 다음은로더를위한스크립트파일 led-ld-script 이다. 어셈블을하고코드의시작주소를지정해주기위해서필요하다. ARM 은리셋직후 0x0 번지의명령어를실행하므로프로그램코드의시작주소가 0x0 이되도록로더를설정해야한다. 1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 2 OUTPUT_ARCH(arm) 3 ENTRY(_start) 4 SECTIONS 5 { 6. = 0x00000000; 7 8. = ALIGN(4); 9.text : { *(.text) 10 11. = ALIGN(4); 12.text : { *(.rodata) 13 14. = ALIGN(4); 15.text : { *(.data) 16 17. = ALIGN(4); 18.text : { *(.got) 19 20. = ALIGN(4); 21.text : { *(.bss) 22 다음은 Makefile 이다. 1 2 CC = arm-linux-gcc 3 LD = arm-linux-ld 4 OC = arm-linux-objcopy 5 6 INCLUDE = -nostdinc -I. -I$(TOPDIR)/include 7 8 CFLAGS = $(INCLUDE) 9 CFLAGS += -Wall -Wstrict-prototypes -Wno-trigraphs -O2 10 CFLAGS += -fno-strict-aliasing -fno-common -pipe -mapcs-32 gcc 버전이 3 이넘어가면서바뀐옵션이있다. short-load-bytes 옵션은이름이 alignment-traps 로바뀌고디폴트로설정된다. 또 Wa,mxscale 옵션은필요없다. PXA27x 는 armv5 명령어셋을사용하므로다음과같은옵션들이필요하다. 11 #CFLAGS += -march=armv5 -Wa,-mxscale -mtune=xscale -mshort-load-bytes -msoft-fl oat -fno-builtin 12 # in gcc-3.x, short-load-bytes is renamed to alignment-traps and seted as defau lt 13 # -Wa,-mxscale option should be removed for gcc 3.x

14 CFLAGS += -march=armv5 -mtune=xscale -msoft-float -fno-builtin 15 16 START_LDFLAGS = -p -X -T./led-ld-script 17 18 OCFLAGS = -O binary -R.note -R.comment -S 19 20 BOOT_IMAGE = ledtest_pxa270 21 22 SRCS = led.s 23 OBJS = led.o 24 25 TARGET = ledtest_org 26 PRE_TARGET = ledtest-elf32 27 28 %.o:%.s 29 @echo "Assembler compiling $<... " 30 $(CC) -c $(CFLAGS) -o $@ $< 31 32 #make image file 33 34 all:$(pre_target) 35 $(OC) $(OCFLAGS) $(PRE_TARGET) $(TARGET) 36 dd if=$(target) of=$(boot_image) bs=1k conv=sync 37 38 $(PRE_TARGET):$(OBJS) 39 $(LD) $(START_LDFLAGS) -o $@ $(OBJS) 40 41 clean: 42 rm -f *.o 43 rm -f $(PRE_TARGET) 44 rm -f $(TARGET) 45 혹시어셈블을할때 old and new-style option 이라는에러가나오면새로운버전의 gcc 에맞는옵션이아니라는것이므로옵션을수정해야한다. google 에서설정한옵션들을검색해보면같은에러에관해질문한내용들이많을것이다. 찾아서답변들을읽고고치거나삭제하면된다. 이제다음과같이퓨징을한다.

테스트프로그램을다운로드한후보드를리셋하고이핀을확인해서신호가출력되고시리얼을통해서문자도출력된다면 jflash 도정상적으로동작하고보드도정상적이라는것을알수있다. 이제최소한의하드웨어상태를알았으니부트로더를포팅할준비가끝났다. 2005-11-29 현재왜 verify 에러가발생하는지알아내지못함.

메모리관련회로이해 SKKU 의보드에서부트로더에필요한사항들을살펴본다. 먼저메모리에대해서살펴보면 SKKU 보드에는 2 개의플래시롬과 2 개의 SDRAM 이있다. 메모리컨트롤에관한사항은 Intel PXA27x Processor Family Developer s Manual 에서 chap 6 Memory Controller 를참조한다. 플래시롬은인텔의 Strata Flash 28F128K3 를사용한다. 이플래시메모리는 25ns 시간이소모되는비동기식접근과 13ns 시간이소모되는동기식접근이지원된다. 흔히사용하는 Strata Flash 28F128J3A 는비동기식접근만지원되는데반해이플래시는좀더빠른동기식접근과버스트모드를지원한다. 모델번호에서알수있듯이 128Mbit 의크기를가지며 128 블록으로구성되어있어서한섹터당크기가 1Mbit, 즉 256Kbyte 가되고 NOR 플래시이다. K3 는 3volt 전원이필요하다는것을나타낸다. 칩하나의크기가 128Mbit, 16Mbyte 이고두개를사용하므로 32Mbyte 의플래시롬을가지게된다. 다음은 SKKU 보드의플래시회로이다. 하나의 28F128k3 은 8M 개의워드로구성되므로 23 개의주소핀이필요하다. 그래서 A<24> 의연결을선택할수있도록했고 R113 을없애도된다. 버스폭이 32 비트이므로 MA<1:0> 은주소지정에필요없으므로 MA<24:2> 를사용한다. SCDLK0 을클럭으로사용하고 ncs0 으로칩셀렉트를하므로플래시롬의시작주소는 0x00000000 이된다. 즉롬을위한뱅크중에서첫번째뱅크로지정된다. SKKU 보드에서는비동기로사용하므로 WAIT 을연결하지않고 STS 에하이신호를인가한다. 또 VPEN 에하이신호를인가해서데이터를프로그래밍할수있도록한다. SDRAM 은삼성의 K4S561632C-TL75 를사용한다. 하나의칩이 4Mbit X 16bit X 4banks 로구성되어있어서크기가 256Mbit, 즉 32MByte 가된다. 하나의칩의데이터폭이 16 비트이고 4 개의뱅크로이루어져있다. 매뉴얼을확인하면 TL75 가최대 133MHz 로동작할수있다는것을나타낸

다고알수있다. 매뉴얼에서확인해야할사항들이 CAS latency 가 2&3 이고 64ms 의리프레시주기를가지며 CL=3 라는것을알아두어야한다. SDRAM 에관한기본적인사항들은 http://kelp.or.kr/korweblog/stories.php?story=04/12/15/5293387&topic=30 에조형기님의강좌를참조한다. 다음은 SKKU 보드의회로도중 SDRAM 에관한부분이다. 칩셀렉트핀인 ncs 에는 SDCS1 을연결했다. SDCS0 이아니라 SDCS1 을연결한특별한이유는없다. 어쨌든 SDCS1 을연결했으므로 SDRAM 의시작주소는 0xA4000000 이된다. PXA270 의 SDCS0~3 핀은 SDRAM 파티션을선택하기위한핀이다. SDCS0 은물리주소 0xA0000000 에서시작하고한파티션의크기는 64MByte 이다. 따라서다음파티션 SDCS1 은 0xA4000000 이고각각 0x04000000 씩떨어져있다 (Intel PXA27x Processor Family Developer s Manual 에서 Figure 6-2 참조 ). 클럭은 SDCLK1 이연결되어있고주소라인이 10 번핀부터 24 번핀이연결되어있다. 주소라인의연결은 Intel PXA27x Processor Family Developer s Manual 에서테이블 6-3 을참조한다. 이테이블은일반적인주소지정방식을사용하고 SDCLK<0> 과 SDCLK<3> 이플래시에사용되지않을때, 즉가장일반적으로사용되는 SDCLK 가 SDRAM 에만사용되고 ncs 가플래시롬에사용되는상황에서의주소라인사용에대해서나열되어있다. 보드에사용된 SDRAM 의매뉴얼에서 A0~A12 에관한내용을찾아보면 ROW 비트가 RA0~RA12 로 13 개, COLUMN 비트가 CA0~CA8 로 9 개, 데이터폭은 DQ0~DQ15 로 16 비트, 뱅크선택은 BA0~BA1 로 2 비트로구성되어있다는것을알수있다. 테이블 6-3 에서이런특성을찾아보면테이블가장위에 MA<24:10> 이사용되야한다는것이나와있고 MDCNFG 라는레지스터에서 STACK 항목의값이 00 이어야한다고나와있다. MDCNFG 레지스터에대한내용은부트로더설정에서살펴본다. 테이블에서진하게출력된핀번호 MA<24:23> 이뱅크설정을위한 BA0~BA1 핀이다. 즉 MA<24> 를 BA1 에 MA<32> 을 BA0 에연결해야한다. 자세한주소지정방식은 Intel PXA27x Processor Family

Developer s Manual 에서 6.4.2.3 SDRAM Memory Size Options 을참조한다. 현재대부분의 PXA270, PXA25x 보드가삼성의램을사용하므로비슷한설정을사용한다. 다른보드들에대한자료를찾아서비교해보면더잘이해할수있다. 그외의핀들에대한설명은 SDRAM 의매뉴얼과 Intel PXA27x Processor Family Developer s Manual 의 chap 6 을참조한다. 반드시각핀에대한역할을이해해야만부트로더설정을이해하고필요한값을찾을수있다.

부트로더에설정파일추가하기 u-boot 를사용하기위해서는 u-boot 와 u-boot 를컴파일하기위한크로스컴파일러패키지 ELDK 를준비해야한다. ELDK 에대한자세한사항은 http://www.denx.de/wiki/dulg/eldk 를참조한다. u-boot : http://sourceforge.net/projects/u-boot/ ELDK : http://www.denx.de/wiki/view/dulg/eldkavailability 하이버스에서제공하는 arm-linux-ld 를사용하면 libgcc.a uses VFP instructions, whereas u-boot does not 이라는에러가생기면서컴파일을할수없었다. ELDK 사이트에들어가서 arm 버전시디이미지를다운받는다. mount o loop arm- 버전.iso /media/cdrom 와같이 mount 명령어로마운트하고디렉토리에들어가서./install d /usr/local/eldk 명령어로설치한다. 간단하게설치할수있어서편하고 2.6 커널을지원한다. u-boot 는 1.1.3 버전까지개발됐고우리는 1.1.2 버전을사용한다. 먼저컴파일이잘되는지확인하기위한테스트로 lubbock 를위한설정과컴파일을해본다. 다음그림과같이먼저원하는보드타입에대한설정을해주고그다음에컴파일을실행하면된다. 우리는 board 디렉토리밑에 skku 라는디렉토리를만들고 PXA270 프로세서와우리보드에맞는코드들을추가할것이므로다음과같은명령어를사용하게된다. make skku_config make 그외에 make clobber 가있는데이는보드에대한설정파일들까지삭제하게된다. make clean 은일반적으로사용하는것과같이컴파일된목적파일들을지운다. 다음그림과같이 u-boot.bin 파일이생성되면컴파일이정상적으로완료된것이다. 이 u- boo.bin 파일이플래시롬에퓨징될바이너리코드이다. 이렇게바이너리코드가이상없이생성된다면크포스컴파일러가정상적으로설치된것이므로우리보드에대한설정을시작한다.

다음은우리보드에맞는설정을추가해주는것이다. 다음과정을순서대로실행하면된다. 1. Makefile 수정 Makefile 을열면다음과같은부분이있다. CROSS_COMPILE 이설정되지않은상태이다. 따라서현재설치된크로스컴파일러의경로를지정해준다.

그리고필요없는 example 부분을삭제한다. 그다음은 SKKU 보드에대한컴파일설정을추가한다. PXA250 프로세서를사용하는보드들에대한설정이있는데그밑에 PXA270 프로세서를사용하는 SKKU 보드에대한설정을추가한

다. arm pxa270 skku 라고된구문은 lib_arm/ 디렉토리를컴파일하고 cpu/pxa270/ 을컴파일하고 skku_config 를생성하도록하는문장이다. cpu/pxa270 디렉토리는직접만들어줘야한다. cpu/pxa 를복사해서만들고수정해서쓴다. 2. cpu/pxa270/ 디렉토리추가 cpu/pxa 디렉토리를복사해서 pxa270 디렉토리를만든다. 3. board/skku/ 디렉토리추가 Makefile 을수정한다음에는 SKKU 보드에맞는설정들을추가한다. 보드타입에따른파일들은 /board 디렉토리에각보드이름의디렉토리를만들어서저장하면된다. u-boot 1.1.2 버전은 Mainstone 보드를지원하지않으므로 PXA250 을사용하는가장비슷한보드인 Lubbock 보드의디렉토리를복사해서사용한다.

그리고 /board/skku/ 에있는 lubbock.c 파일을 skku.c 로바꾸고 Makefile 도 lubbock.o 를 skku.o 로바꾼다. skku.c 를열어보면다음과같이보드타입번호를지정하는부분이있다. LUBBOCK 로된부분을 SKKU 로수정한다. 4. board/skku/u-boot.lds 수정 cpu/pxa/start.o 를참조하도록된부분을 cpu/pxa270/start.o 로고친다.

5. include/asm-arm/mach-type.h 수정 include/asm-arm/mach-types.h 파일을열어보면각보드들에대한타입번호와보드타입을확인하기위한매크로들이들어있다. 여기에 SKKU 보드를추가한다. 보드번호는 HYBUS 보드번호를사용했다. 이번호는리눅스커널에넘기기위한것이다. 6. include/configs/skku.h 생성 include/configs/lubbock.h 를 skku.h 로복사한다. 이파일이 u-boot 를위한설정이들어있는파일이다. 일단 SKKU 보드를위한파일들을모두추가하고그다음에이설정을보드에맞춰서하나씩맞춰나간다. 지금은일단다음그림과같이보드이름만수정하고 #define CONFIG_LCD 1 설정을 #undef CONFIG_LCD 로고친다.

7. include/asm-arm/arch-pxa270 생성 include/asm-arm/arch-pxa 를복사해서 include/asm-arm/arch-pxa/arch-pxa270 디렉토리를만든다. 8. 컴파일옵션수정 cpu/pxa270/config.mk 를열어보면 PXA250 을위한컴파일설정이들어있다. 이것을 gcc 3.3.3 버전에맞고 PXA270 에맞도록다음과같이수정한다. 9. 이미지생성 make skku_config 명령으로 SKKU 보드관련설정을실행시키고 make 로컴파일을시작한다.

보드하드웨어에맞게부트로더설정하기 Lubbock 보드의파일들을복사해서사용하므로 Lubbock 보드의사양에맞게설정되어있다. 메모리맵설정과메모리컨트롤러설정, 네트워크디바이스등을주의해서설정파일들을수정해야한다. 또프로세서초기화코드들이 PXA250 에맞게작성되어있다. PXA270 프로세서도코어는 PXA250 코어를사용하므로크게달라진부분은없지만프로세서속도가빨라졌고이에따라클럭관련코드를수정해주어야한다. 결론적으로다음설정파일들을수정하게된다. board/skku/config.mk include/configs/skku.h 이설정파일들을수정하고 PXA250 에맞게작성된프로세서초기화코드를 PXA270 에맞게약간만수정하면포팅이끝난다. 이파일들을수정하기전에다음사항들에대해이해해야한다. - SDRAM 의시작주소와크기 시작주소 : 0xA400 0000, nsdcs1 으로파티션을선택하므로 0xA000 0000 이아니라그다음파티션인 0xA400 0000 이된다. 크기 : 0x0400 0000 (64MByte = 32MB X 2 개 ) - SDRMA 의속도설정 68 - 플래시메모리의시작주소와크기 시작주소 : 0x0000 0000, ncs0 을사용해서첫번째파티션이된다. 크기 : 0x0200 0000 ( 32MByte = 16MB X 2 개 ) - 플래시메모리의속도설정 - 부트로더가플래시에써지는시작주소와크기 0x0000 0000 - 부트로더가램으로복사되는시작주소와크기 0xA408 0000 ~ 0xA40995F4, BSS ~0xA40C DF0C - 부팅파라미터가리눅스커널로넘겨지는주소 0xa000 0100 - 커널이복사되는시작주소 0xA400 8000, 0x0004 0000-28F128K3 플래시의 CFI 인식번호 0x8802 프로세서의속도에대한설정은 Intel PXA27x Processor Family Developer s Manual 에서 Table 3-7 을본다. Core Turbo Freq 를 520MHz 로맞추기위한설정들이나와있다. 이테이블에따라서레지스터들을설정해주면된다. 가장먼저 include/configs/skku.h 를수정한다. 기본적으로 Lubbock 보드에맞게되어있지만이것을한줄씩 SKKU 보드에맞게수정해야하고 PXA250 용레지스터설정들을 PXA270 에맞게고

쳐야한다. 몇가지새로추가해야하는설정들은뒤에서소스들을살펴보면서이야기한다. 다음은 skku.h 의내용이다. lubbock.h 와비교하면서보면이해하기더쉽다. /* * (C) Copyright 2006 * SungKyunKwan Univ. Embedded LAb. gurugio@gmail.com * * (C) Copyright 2006 * * * * Configuation settings for the SKKU board. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #ifndef CONFIG_H #define CONFIG_H /* * If we are developing, we might want to start armboot from ram * so we MUST NOT initialize critical regs like mem-timing... */ start.s 파일을열어보면 CONFIG_INIT_CRITICAL 가선언되어있다면 cpu_init_crit 함수를호출하는부분이있다. 이함수는프로세서의속도나메모리컨트롤러등을설정하는일을하므로반드시호출해주어야한다. #define CONFIG_INIT_CRITICAL /* undef for developing */ /* * High Level Configuration Options * (easy to change) */ 특별히하는일은없다. 프로세서종류와보드이름을선언한다. #define CONFIG_PXA270 1 /* This is an PXA270 CPU */ #define CONFIG_SKKU 1 /* on an SKKU Board */ #define BOARD_LATE_INIT 1 IRQ 설정코드를실행시키지않는다. 부트로더에서는굳이 IRQ 가필요없다. #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ /* * Size of malloc() pool */ 전역변수를저장하기위해서미리약간의메모리영역을지정해놓는다. start.s 에서 SDRAM 을위한매모리맵을설정하는부분이있다. 부트로더자신을 SDRAM 으로복사하고그외에환

경설정이나전역변수등에대한영역, 스택메모리등의영역을설정하는데사용된다. #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) include/asm-arm/global_data.h 에는 gd_t 라는구조체가있다. 이구조체는부트로더초기설정을기록하기위해사용된다. 이구조체가저장되는영역의크기를결정한다. #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ /* * Hardware drivers */ SKKU 보드는네트워크장치로 CS8900를사용한다. 칩셀렉트핀에 ncs1을사용하므로 0x0400 0000 번지로접근할수있다. drivers/ 를보면다양한이데넷칩의드라이버가있다. #define CONFIG_DRIVER_CS8900 1 #define CS8900_BASE 0x04000000 #define CS8900_BUS16 1 /* * select serial console configuration */ 시리얼통신설정 #define CONFIG_FFUART 1 /* we use FFUART on SKKU */ #define CONFIG_BAUDRATE 115200 /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE u-boot에서지원하는명령어설정. README 파일을읽어보면가능한명령어들에대한목록이있다. NAND, DHCP등다양한명령들이있다. CONFIG_CMD_DFL은디폴트명령들을설정한다. #define CONFIG_COMMANDS (CONFIG_CMD_DFL CFG_CMD_FAT) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include <cmd_confdefs.h> 대기시간 #define CONFIG_BOOTDELAY 5 네트워크설정 #define CONFIG_ETHADDR 12:34:56:78:9a:bc #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 10.51.15.132 #define CONFIG_SERVERIP 10.51.15.126 대기시간이지나면실행하는명령. 커널주소를지정해주면자동으로커널로점프한다. 주석으로남기면자동으로부팅하지않고프롬프트를출력한다. #define CONFIG_BOOTCOMMAND "bootm 40000" 부팅옵션. 리눅스의부팅옵견과동일하게설정된다. #define CONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=jffs2 console=ttys0,115200" #define CONFIG_CMDLINE_TAG #if (CONFIG_COMMANDS & CFG_CMD_KGDB) #define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ #define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ #endif /* * Miscellaneous configurable options */ README 참조. #define CFG_HUSH_PARSER 1 #define CFG_PROMPT_HUSH_PS2 "> " #define CFG_LONGHELP /* undef to save memory */ #ifdef CFG_HUSH_PARSER

프롬프트텍스트설정 #define CFG_PROMPT "SKKU2005> " /* Monitor Command Prompt */ #else #define CFG_PROMPT "=> " /* Monitor Command Prompt */ #endif #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_DEVICE_NULLDEV 1 몇가지보드들은메모리테스트를한다. Lubbock 보드는실행하지않음. #define CFG_MEMTEST_START 0xa4000000 /* memtest works on */ #define CFG_MEMTEST_END 0xa4080000 /* 0 ~ 8 MB in DRAM */ #undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ 리눅스커널을 SDRAM 으로로드하는주소 #define CFG_LOAD_ADDR 0xa4008000 /* default load address */ /* interrupt.c -> get_tbclk(). number of time ticks per second */ cpu/pxa/interrupt.c 에는 udelay_masked 라는함수가있다. 이함수는 us 단위로대기하는일을한다. 이함수에 CFG_HZ 값이사용되는데이값을 OSCR 값과비교해서시간이측정한다. OSCR 은 Intel PXA27x Processor Family Developer s Manual 의 22.5.5 OSCR0 의설명에서보듯이 3.25MHz 클럭에따라값이증가한다. 결국 1 초에 3250000 증가하고 1us 에는 3 이증가하므로이값과비교하면 us 단위로딜레이를구현할수있다. #define CFG_HZ 3250000 /* incrementer freq: 3.25 MHz */ cpu/pxa/start.s 파일에서 CCCR 레지스터를이값으로설정한다. Intel PXA27x Processor Family Developer s Manual 의 3.8.2.1 CCCR 을참조한다. 매뉴얼의 Table 3-7 에따라프로세서를 520MHz 로동작시키기위해서는 CCCR[L] = 16, CCCR[2N] = 5, CCCR[A] = 1 이되어야한다. #define CFG_CPUSPEED 0x08000290 /* set core clock to 520 MHz */ /* ADDED BY GIO for start.s */ start.s에 PXA270의터보모드진입에관한코드를추가해야한다. PXA250에는없는코드이므로기타다른부트로더를참조하여코드를추가한다. Table 3-7에따라레지스터비트들을셋팅하면된다. CLKCFG 레지스터는 Coprocessor14에속한레지스터이므로일반레지스터와는약간다르게다루어야한다. #define CFG_CLKCFG_VAL 0x0000000b /* B=1, HT=0, T=1 F=1 in CP14*/ /* valid baudrates */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 /* * Stack sizes * * The stack sizes are set up in start.s using the settings below */ C 코드에서함수호출등을위해사용될스택의크기설정 #define CONFIG_STACKSIZE (128*1024) /* regular stack */ #ifdef CONFIG_USE_IRQ #define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ #define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ #endif /* * Physical Memory Map */ SKKU 보드에서는 nsdcs1 을사용해서 SDRAM 의파티션을선택하므로 2 번째뱅크가사용된다. #define CONFIG_NR_DRAM_BANKS 1 /* we have 1 banks of DRAM */

#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */ #define PHYS_SDRAM_1_SIZE 0x00000000 /* No SDRAM at 1st partition */ #define PHYS_SDRAM_2 0xa4000000 /* SDRAM Bank #2 */ #define PHYS_SDRAM_2_SIZE 0x04000000 /* 64 MB */ #define PHYS_SDRAM_3 0xa8000000 /* SDRAM Bank #3 */ #define PHYS_SDRAM_3_SIZE 0x00000000 /* 0 MB */ #define PHYS_SDRAM_4 0xac000000 /* SDRAM Bank #4 */ #define PHYS_SDRAM_4_SIZE 0x00000000 /* 0 MB */ /* * SKKU uses two '28F128K3', 128Mbit = 16MB * 128Blocks X 1Mbit(128KB) */ 28F128J3A 와 28F128K3 는 128KB 의섹터크기를가지며 128 개의블록으로이루어져있다. ARM 계열의프로세서들은리셋후메모리의 0 번지를참조하므로반드시 0 번지에롬을붙여야한다. #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ #define PHYS_FLASH_2 0x04000000 /* Flash Bank #2 */ #define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */ #define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Banks */ #define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */ #define CFG_DRAM_BASE #define CFG_DRAM_SIZE #define CFG_FLASH_BASE PHYS_SDRAM_2 PHYS_SDRAM_2_SIZE PHYS_FLASH_1 /* * FLASH and environment organization */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ #define FPGA_REGS_BASE_PHYSICAL 0x08000000 /* * GPIO settings */ GPIO 사용설정. 부트로더에서는 FFUART와최소한의장치만사용한다. #define CFG_GPSR0_VAL 0x00008004 #define CFG_GPSR1_VAL 0x00020080 #define CFG_GPSR2_VAL 0x0001FFFF #define CFG_GPCR0_VAL 0x00000000 #define CFG_GPCR1_VAL 0x00000380 #define CFG_GPCR2_VAL 0x00000000 #define CFG_GPDR0_VAL 0x0060A800 #define CFG_GPDR1_VAL 0x00000380 #define CFG_GPDR2_VAL 0x0001C000 #define CFG_GAFR0_L_VAL 0x98400000 #define CFG_GAFR0_U_VAL 0x00002950 #define CFG_GAFR1_L_VAL 0x0000a950 #define CFG_GAFR1_U_VAL 0x0005AAAA #define CFG_GAFR2_L_VAL 0xA0000000 #define CFG_GAFR2_U_VAL 0x00000002 PSSR[RDH] = 0, PSSR[PH] = 0 GPIO를활성화시킨다. PSSR[BFS] = 1 배터리폴트가발생하면프로세서를슬립모드로바꾼다. #define CFG_PSSR_VAL 0x20 /* * Memory settings */ ncs<1:0> 으로연결된플래시메모리에대한설정 #define CFG_MSC0_VAL 0x788912b3 /* for Flash */

ncs<5:2> 에는아무것도연결되지않음 #define CFG_MSC1_VAL 0x00000000 #define CFG_MSC2_VAL 0x00000000 /* * SDRAM partition 1 enable, * 2 banks X 13 ROWs X 9 Column X 16 bit width X 2 chips * 4 internal banks per 1 chips * trp=3, CL=3, trcd=3, tras=7, trc=11 * Normal addressing mode * MA<24:10> are used * */ #define CFG_MDCNFG_VAL 0x08000bca /* for SDRAM */ /* * SRAM uses SDCLK<1> * Flash uses SDCLK<0> * According to CCCR, CLK_MEM is 208MHz, * thus it should be divided by 2 to be used for SDRAM(104Mhz) -> K1DB2=1 */ #define CFG_MDREFR_VAL 0x0103801e /* These value is dummy value. * There value does not affect SDRAM setting */ #define CFG_MDMRS_VAL 0x00000000 /* Asynchronous flash memory for SKKU */ 비동기방식으로플래시를사용하므로모두 0 으로설정한다. #define CFG_SXCNFG_VAL 0x00000000 /* * PCMCIA and CF Interfaces */ #define CFG_MECR_VAL 0x00000000 /* No PC Card */ #define CFG_MCMEM0_VAL 0x00010504 #define CFG_MCMEM1_VAL 0x00010504 #define CFG_MCATT0_VAL 0x00010504 #define CFG_MCATT1_VAL 0x00010504 #define CFG_MCIO0_VAL 0x00004715 #define CFG_MCIO1_VAL 0x00004715 /* timeout values are in ticks */ #define CFG_FLASH_ERASE_TOUT (25*CFG_HZ) /* Timeout for Flash Erase */ #define CFG_FLASH_WRITE_TOUT (25*CFG_HZ) /* Timeout for Flash Write */ /* FIXME */ #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x1C000) /* Addr of Environment Sector */ #define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ /* clock */ 메모리컨트롤러, 48MHz 클럭, OS Timer, FFUART 클럭활성화 #define CFG_CKEN_VAL 0x00400a40 #endif /* CONFIG_H */ board/skku/config.mk 의내용은다음과같다. 부트로더가 SDRAM 에로드될주소를정해주면된다. 0xA4008000 에커널이로드되므로이보다충분히큰크기가되야한다.

프로세서와메모리초기화를위한레지스터이해 프로세서와메모리를초기화하기위한코드들에서설정한레지스터들에대해간단하게살펴본다. Intel PXA27x Processor Family Developer s Manual 에서다룬순서를따른다. 1. 클럭설정레지스터 - CCCR : 프로세서의코어클럭설정 L : 런모드클럭과오실레이터의비율 2N : 터보모드의클럭과런모드클럭의비율 A : 메모리컨트롤러클럭설정 CLKCFG[B] = 1, CCCR[A] = 0, L = 16 일때, 메모리컨트롤러는 13MHz * L / 2 = 104MHz 로동작한다. - CKEN : 프로세서내부모듈의클럭활성화 <22> : 메모리컨트롤러클럭 <16> : LCD 컨틀롤러클럭 <11> : USB 킅라이언트, 48MHz 클럭 <6> : FFUART 클럭 - CLKCFG : 클럭모드변경, Coprocesor 14 에들어있슴. T : 터보모드활성화 F : 클럭주기변경시작 HT : 하프터보모드 B : 시스템버스클럭을런모드클럭주기와같게한다. 520MHz 터보모드에서런모드클럭은 208MHz 이다. 2. 메모리컨트롤러레지스터 SDRAM 을컨트롤하는레지스터 - MDCNFG : SDRAM 의파티션에대한설정을한다. 0/1 파티션과 2/3 파티션으로나눠서각각설정한다. DE0 : SDRAM 파티션 0 활성화 DE1 : SDRAM 파티션 1 활성화 DWID0 : 0/1 파티션에서데이터버스폭 DCAC0 : 0/1 파티션에서주소비트의열개수 DRAC0 : 0/1 파티션에서주소비트의행개수 DNB0 : 0/1 파티션에서뱅크의개수 DTC0 : SDRAM 의 AC 타이밍을설정. 삼성에서출시하는대부분의 32MB 크기의 SDRAM 은 0b11 이나 0b10 둘다사용될수있다. DADDR0 : 주소지정모드 DSA1110_0 : SA-1110 주소지정방식호환모드 STACK0 : STACK1 비트와함께메모리에사용될주소핀을설정한다. - MDMRS : MDCNFG 레지스터를설정한다음에 MDMRS 레지스터를설정해야한다. 대부분의비트가메모리의동작상태를나타내는읽기전용비트이므로 MDCNFG 레지스터에대한설정을끝낸직후에 MDMRS 레지스터에 0x00000000 값을써주는것이일반적인사용법이다. - MDREFR : SDRAM 의리프레시시간과동작클럭을설정한다. SDCLK, SDCKE 를설정한다.

DRI : SDRAM 은한번에한행씩리프레시를해준다. 이리프레시의시간간격을지정한다. 16/32MB 의 SDRAM 은리프레시시간이 64ms 가되야한다. 따라서 CLK_MEM 이 104MHz 일때, 매뉴얼에나온공식대로 (64ms / 13rows * 104MHz - 31) / 32 = 15 로설정하면된다. K0RUN : SDCLK<0>/<3> 의활성화. SDCLK<0> 은주로동기플래시롬에사용된다. 만약비동기플래시롬만을사용한다면필요가없다. K0DB2 : SDCLK<0>/<3> 의속도설정 E1PIN : SDCKE 활성화 K1RUN : SDCLK<1> 활성화 K1DB2 : SDCLK<1> 속도설정 K2RUN : SDCLK<2> 활성화 K2DB2 : SDCLK<2> 속도설정 APD : Auto power down 활성화. 램이없거나사용하지않을때램관련동작들을멈춰서전력소모를줄인다. 보통사용하지않는다. SLFRSH : SDRAM 의 Self-refresh 를활성화한다. K0FREE : SDCLK<0>/<3> 의동작제어. 1 로설정하면동작함. 플래시메모리관련설정 - SXCNFG : 동기플래시메모리를사용하는경우에설정한다. SXEN0 : 0 번파티션을동기플래시메모리로설정 SXEN1 : 1 번파티션을동기플래시메모리로설정 - MSCx : 비동기플래시메모리설정. ncs<5:0> 으로플래시파티션을선택하는데 MSCx 레지스터한개가두개의 ncs 를설정한다. 즉 MSC0 이 ncs<1:0> 을설정하게된다. MSC0 을중심으로설명한다. RT0 : ncs0 의디바이스타입. RBW0 : ncs0 의버스폭 RDF0 : noe, nwe 의신호가 Assert 되는길이. RDN0 : 버스트모드일때사용된다. noe, new 가 Deassert 된후다시 Assert 될때까지의클럭수. 보통 RDF 와같다. RRR0 : 논버스트모드에서 ncs0 이액티브되고다음에액티브될수있는최소클럭수 RBUFF0 : 플래시를사용할때는 0 으로설정한다. 3. GPIO 설정레지스터 다음은 Intel PXA27x Processor Family Developer s Manual 에서 24 장 General Purpose I/O Controller 에있는테이블 24-2 를가져온것이다. SKKU 보드에서사용하는 GPIO 와사용되는기능을노락색으로색칠을했다. GPIO 관련설정을하기위해서는이렇게프로세서에있는 GPIO 들을놓고어떤핀이어떤기능으로사용될지를먼저결정하고그에맞춰서레지스터들의설정값들을계산하면된다.

다음은 GPIO 관련레지스터들의설명이다. - GPDR : 입출력방향을결정한다. GPDR0<0> 은 GPIO<1> 을설정한다. 마찬가지로 GPDR1<0> 은 GPIO<32> 를설정한다. 즉한비트에한핀을설정한다. SKKU 보드에서설정한값은다음과같다. GPDR<0> : 0xC0F393E4 GPDR<1> : 0xFCEFAB83 GPDR<2> : 0xE2F1FFFF GPDR<3> : 0xFE1FFFE5 - GPSR : GPIO 핀셋팅레지스터 GPIO 핀이출력으로설정되어있고 GPSR 에서해당핀이 1 로설정되면하이신호를내보낸다. SKKU 보드에서설정한값은다음과같다. GPSR<0> : 0x00008004 GPSR<1> : 0x00020080 GPSR<2> : 0x16C14000 GPSR<3> : 0x0003E000 - GPCR : GPIO 핀클리어레지스터 GPIO 핀이출력으로설정되어있고 GPSR 에서해당핀을 1 로설정하면로우신호를내보낸다. SKKU 보드에서설정한값은다음과같다. GPCR<0> : 0x0 GPCR<1> : 0x00000380, FFUART 에서로우신호가필요하다. GPCR<2> : 0x0 GPCR<3> : 0x0

GPCR 과 GPSR 에값을쓸때는가장마지막으로설정한값을따른다. 즉 GPCR<0> 과 GPSR<0> 을둘다 1 로설정해줘도 GPCR<0> 을나중에써줬으면로우신호가나가고 GPSR<0> 을나중에써주면하이신호가출력된다. - GRER : 상승엣지확인활성화 해당핀에서상승엣지가검출되면 GEDR 레지스터의해당비트를 1 로설정한다. SKKU 보드에서설정한값은다음과같다. GRER<0> : 0x0 GRER<1> : 0x0 GRER<2> : 0x00080000, MMC_CD 에서필요하다. GRER<3> : 0x0 - GFER : 하강엣지확인활성화 해당핀에서하강엣지가검출되면 GEDR 레지스터의해당비트를 1 로설정한다. SKKU 보드에서설정한값은다음과같다. GFER<0> : 0x00000001, On/Off 스위치에사용됨. GFER<1> : 0x0 GFER<2> : 0x04000000, PCMCIA 의인터럽트에사용 GFER<3> : 0x00000008, USB 의인터럽트에사용 - GAFR : GPIO 핀의기능설정 GPIO 핀이일반입출력이아니라프로세서내부의유닛에의해사용되도록설정한다. 보통세가지의기능을선택할수있고일반 GPIO 로사용할수있으므로총 4 가지경우가있다. 따라서한핀당두개의비트로설정한다. 예를들어, GPIO<0> 은 GAFR0_L<1:0> 으로설정할수있고 GPIO<16> 은 GAFR0_U<1:0> 으로설정한다. 또 GPIO<32> 는 GAFR1_L<1:0> 으로설정한다. GAFR0_L : 0x830C0000 GAFR0_U : 0xA520051A GAFR1_L : 0x999A955A GAFR1_U : 0xAAA5A0AA GAFR2_L : 0x6A8AAAAA GAFR2_U : 0x0109A002 GAFR3_L : 0x5400100A GAFR3_U : 0x00001409 - GPLR : 핀상태확인 현재핀의신호레벨을알수있다. 읽기전용레지스터이다. - GEDR : 엣지검출상태 GRER 이나 GFER 의설정에따라엣지가검출되면 1 로셋팅된다.

프로세서와메모리초기화 Intel PXA27x Processor Family Developer s Manual 은 PXA27x 프로세서로개발하기위한모든사항을담고있는문서이다. 그중에서도몇가지챕터를골라서요약하고중요한부분들을한글로번역해서정리한다. 프로세서초기화와 SDRAM, 플래시메모리의초기화과정을이해하도록한다. 1. 프로세서속도 page 3-20 Table 3-7 이테이블에서터보모드로진입하기위해서는 CLKCFG[T] = 1, CLKCFG[HT] = 0, CCCR[L] = 16, CCCR[2N] = 5 로설정해주면된다. 그다음은프로세서의모드이외에관련클럭들의설정이다. 예를들어, CLKCFG[B] = 1 이면시스템버스가 208MHz 가되고 0 으로설정하면 104MHz 가된다. 마찬가지로 CCCR[A] 가 1 이면메모리클럭설정에관련된 CLK_MEM 가 208MHz 가되는식이다. SDRAM 을 104MHz 로동작시키기위해서는 CCCR[A] 와 MDREFR[KxDB2] 가 1 이되어야한다. 현재 SKKU 보드에서는 CCCR[A] = 0, MDREFR[KxDB2] = 0 으로설정해서, CLK_MEM 을 104MHz 로동작시키고 SDRAM 을 52MHz 로동작시킨다. 일반적으로 PXA270 은 520MHz 로동작하는터보모드를사용한다. 이런터보모드를사용하기위해필요한레지스터설정을주의해서봐야한다. 다음장에설명하는시피유와메모리컨트롤러초기화코드를세밀하게살펴보고해당레지스터의설정에주의해야한다.

PXA270 에맞게초기화코드수정하기 u-boot 1.1.2 를포팅하기위해서는보통다음파일들을수정해야한다. 그외에코드들은큰흐름만파악하고있으면별다른문제없이보드에포팅할수있다. - board/skku/memsetup.s : 메모리컨트롤러설정. SDRAM 의속도와리프레시주기, 플래시메모리동작에대한설정을한다. - board/skku/skku.c : 특정보드에맞는하드웨어설정을한다. 커널에넘기기위한부팅파라미터의주소를설정하고 SDRAM 의시작주소와크기를설정한다. ARM 용리눅스커널에서는주로 SDRAM 의시작주소 + 0x100 번지에파라미터를넘긴다. - board/skku/flash.c : 보드에서사용하는플래시메모리의동작에관련된함수들. u-boot 에서는 flash_init, flash_erase, flash_print_info, write_buff 을공통적으로작성해야한다. 이함수들은보드마다공통적으로존재해야하고그내부코드는보드에사용된플래시에따라다르게작성해주면된다. common/flash.c 와 common/cmd_flash.c 파일에서이소스에작성된함수들을사용한다. - cpu/pxa270/start.s : 프로세서의속도설정과 SDRAM 으로부트로더자신을복사하는일을한다. 실행되는순서는 start.s 에서 memsetup.s 파일을호출한다. 그리고메모리컨트롤러설정이끝나면부트로더자신을 SDRAM 으로복사하고 SDRAM 으로점프한다. 그러면 lib_arm/board.c 파일에들어있는 start_armboot 함수가실행되고 include/configs/skku.h 에서설정한내용에따라나머지하드웨어들에대한설정을하고사용자의명령을기다린다. 사용자가커널을로드하도록명령하면 lib_arm/armlinux.c 에있는 do_bootm_linux 함수가호출되고커널이미지를로드하고커널로점프한다. 다음은 SKKU 보드를위해 Lubbock 보드의코드를수정해서만든소스들이다.

cpu/pxa270/start.s /* * armboot - Startup Code for XScale * * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> * Copyright (C) 2000 Wolfgang Denk <wd@denx.de> * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de> * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net> * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de> * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <config.h> #include <version.h>.globl _start _start: b reset ldr ldr ldr ldr ldr ldr ldr pc, _undefined_instruction pc, _software_interrupt pc, _prefetch_abort pc, _data_abort pc, _not_used pc, _irq pc, _fiq _undefined_instruction:.word undefined_instruction _software_interrupt:.word software_interrupt _prefetch_abort:.word prefetch_abort _data_abort:.word data_abort _not_used:.word not_used _irq:.word irq

_fiq:.word fiq.balignl 16,0xdeadbeef /* * Startup Code (reset vector) * * do important init only if we don't start from RAM! * - relocate armboot to ram * - setup stack * - jump to second stage */ _TEXT_BASE:.word TEXT_BASE.globl _armboot_start _armboot_start:.word _start /* * These are defined in the board-specific linker script. */.globl _bss_start _bss_start:.word bss_start.globl _bss_end _bss_end:.word _end #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */.globl IRQ_STACK_START IRQ_STACK_START:.word 0x0badc0de /* IRQ stack memory (calculated at run-time) */.globl FIQ_STACK_START FIQ_STACK_START:.word 0x0badc0de #endif /****************************************************************************/ /* */ /* the actual reset code */ /* */ /****************************************************************************/ reset:

mrs r0,cpsr /* set the cpu to SVC32 mode */ bic r0,r0,#0x1f /* (superviser mode, M=10011) */ orr r0,r0,#0x13 msr cpsr,r0 /* * we do sys-critical inits only at reboot, * not when booting from ram! */ #ifdef CONFIG_INIT_CRITICAL bl cpu_init_crit /* we do sys-critical inits */ #endif relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */ copy_loop: ldmia r0!, {r3-r10 /* copy from source address [r0] */ stmia r1!, {r3-r10 /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop /* Set up the stack */ stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */ clbss_l:str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 bne clbss_l ldr pc, _start_armboot

_start_armboot:.word start_armboot /****************************************************************************/ /* */ /* CPU_init_critical registers */ /* */ /* - setup important registers */ /* - setup memory timing */ /* */ /****************************************************************************/ /* Interrupt-Controller base address */ IC_BASE:.word 0x40d00000 #define ICMR 0x04 /* Reset-Controller */ RST_BASE:.word 0x40f00030 #define RCSR 0x00 /* Operating System Timer */ OSTIMER_BASE:.word 0x40a00000 #define OSMR3 0x0C #define OSCR 0x10 #define OWER 0x18 #define OIER 0x1C /* Clock Manager Registers */ #ifdef CFG_CPUSPEED CC_BASE:.word 0x41300000 #define CCCR 0x00 cpuspeed:.word CFG_CPUSPEED #else #error "You have to define CFG_CPUSPEED!!" #endif /* RS:??? */.macro CPWAIT mrc p15,0,r0,c2,c0,0 mov r0,r0 sub pc,pc,#4.endm cpu_init_crit: /* mask all IRQs */ ldr r0, IC_BASE mov r1, #0x00 str r1, [r0, #ICMR]

#if defined(cfg_cpuspeed) setspeed_done: #endif /* set clock speed */ ldr r0, CC_BASE ldr r1, cpuspeed str r1, [r0, #CCCR] //mov r0, #2 ldr r0, =CFG_CLKCFG_VAL /* for Turbo mode */ mcr p14, 0, r0, c6, c0, 0 /* enter the frequency change sequence */ /* NOW Turbo-mode is on! */ /* * before relocating, we have to setup RAM timing * because memory timing is board-dependend, you will * find a memsetup.s in your board directory. */ mov ip, lr bl memsetup mov lr, ip /* Memory interfaces are working. Disable MMU and enable I-cache. */ ldr r0, =0x2001 /* enable access to all coproc. */ mcr p15, 0, r0, c15, c1, 0 CPWAIT mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */ CPWAIT mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */ CPWAIT mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */ CPWAIT /* */ /* Enable the Icache */ mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #0x1800 mcr p15, 0, r0, c1, c0, 0 CPWAIT mov pc, lr

/****************************************************************************/ /* */ /* Interrupt handling */ /* */ /****************************************************************************/ /* IRQ stack frame */ #define S_FRAME_SIZE 72 #define S_OLD_R0 68 #define S_PSR 64 #define S_PC 60 #define S_LR 56 #define S_SP 52 #define S_IP 48 #define S_FP 44 #define S_R10 40 #define S_R9 36 #define S_R8 32 #define S_R7 28 #define S_R6 24 #define S_R5 20 #define S_R4 16 #define S_R3 12 #define S_R2 8 #define S_R1 4 #define S_R0 0 #define MODE_SVC 0x13 /* use bad_save_user_regs for abort/prefetch/undef/swi... */.macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12 /* Calling r0-r12 */ add r8, sp, #S_PC ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack ldmia r2, {r2 - r4 /* get pc, cpsr, old_r0 */ add r0, sp, #S_FRAME_SIZE /* restore sp_svc */ add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r4 /* save sp_svc, lr_svc, pc, cpsr, old_r */ mov r0, sp.endm

/* use irq_save_user_regs / irq_restore_user_regs for */ /* IRQ/FIQ handling */.macro irq_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12 /* Calling r0-r12 */ add r8, sp, #S_PC stmdb r8, {sp, lr^ /* Calling SP, LR */ str lr, [r8, #0] /* Save calling PC */ mrs r6, spsr str r6, [r8, #4] /* Save CPSR */ str r0, [r8, #8] /* Save OLD_R0 */ mov r0, sp.endm.macro irq_restore_user_regs ldmia sp, {r0 - lr^ @ Calling r0 - lr mov r0, r0 ldr lr, [sp, #S_PC] @ Get PC add sp, sp, #S_FRAME_SIZE subs pc, lr, #4 @ return & move spsr_svc into cpsr.endm.macro get_bad_stack ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack str lr, [r13] @ save caller lr / spsr mrs lr, spsr str lr, [r13, #4] mov r13, #MODE_SVC @ prepare SVC-Mode msr spsr_c, r13 mov lr, pc movs pc, lr.endm.macro get_irq_stack ldr sp, IRQ_STACK_START.endm.macro get_fiq_stack ldr sp, FIQ_STACK_START.endm @ setup IRQ stack @ setup FIQ stack /****************************************************************************/ /* */ /* exception handlers */ /* */ /****************************************************************************/

.align 5 undefined_instruction: get_bad_stack bad_save_user_regs bl do_undefined_instruction.align 5 software_interrupt: get_bad_stack bad_save_user_regs bl do_software_interrupt.align 5 prefetch_abort: get_bad_stack bad_save_user_regs bl do_prefetch_abort.align 5 data_abort: get_bad_stack bad_save_user_regs bl do_data_abort.align 5 not_used: get_bad_stack bad_save_user_regs bl do_not_used #ifdef CONFIG_USE_IRQ irq: fiq:.align 5 get_irq_stack irq_save_user_regs bl do_irq irq_restore_user_regs.align 5 get_fiq_stack irq_save_user_regs /* someone ought to write a more */ bl do_fiq /* effiction fiq_save_user_regs */ irq_restore_user_regs #else irq:.align 5 get_bad_stack

bad_save_user_regs bl do_irq fiq:.align 5 get_bad_stack bad_save_user_regs bl do_fiq #endif /****************************************************************************/ /* */ /* Reset function: the PXA250 doesn't have a reset function, so we have to */ /* perform a watchdog timeout for a soft reset. */ /* */ /****************************************************************************/.align 5.globl reset_cpu reset_cpu: reset_endless: /* FIXME: this code is PXA250 specific. How is this handled on */ /* other XScale processors? */ /* We set OWE:WME (watchdog enable) and wait until timeout happens */ ldr r0, OSTIMER_BASE ldr r1, [r0, #OWER] orr r1, r1, #0x0001 /* bit0: WME */ str r1, [r0, #OWER] /* OS timer does only wrap every 1165 seconds, so we have to set */ /* the match register as well. */ ldr r1, [r0, #OSCR] /* read OS timer */ add r1, r1, #0x800 /* let OSMR3 match after */ add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */ str r1, [r0, #OSMR3] b reset_endless

board/skku/memsetup.s /* * Most of this taken from Redboot hal_platform_setup.h with cleanup * * NOTE: I haven't clean this up considerably, just enough to get it * running. See hal_platform_setup.h for the source. See * board/cradle/memsetup.s for another PXA250 setup that is * much cleaner. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <config.h> #include <version.h> #include <asm/arch/pxa-regs.h> DRAM_SIZE:.long CFG_DRAM_SIZE /* wait for coprocessor write complete */.macro CPWAIT reg mrc p15,0,\reg,c2,c0,0 mov \reg,\reg sub pc,pc,#4.endm /* * Memory setup */.globl memsetup memsetup: mov r10, lr

/* Set up GPIO pins first ----------------------------------------- */ ldr r0, =GPSR0 ldr r1, =CFG_GPSR0_VAL str r1, [r0] ldr r0, =GPSR1 ldr r1, =CFG_GPSR1_VAL str r1, [r0] ldr r0, =GPSR2 ldr r1, =CFG_GPSR2_VAL str r1, [r0] ldr r0, =GPCR0 ldr r1, =CFG_GPCR0_VAL str r1, [r0] ldr r0, =GPCR1 ldr r1, =CFG_GPCR1_VAL str r1, [r0] ldr r0, =GPCR2 ldr r1, =CFG_GPCR2_VAL str r1, [r0] ldr r0, =GPDR0 ldr r1, =CFG_GPDR0_VAL str r1, [r0] ldr r0, =GPDR1 ldr r1, =CFG_GPDR1_VAL str r1, [r0] ldr r0, =GPDR2 ldr r1, =CFG_GPDR2_VAL str r1, [r0] ldr r0, =GAFR0_L ldr r1, =CFG_GAFR0_L_VAL str r1, [r0] ldr r0, =GAFR0_U ldr r1, =CFG_GAFR0_U_VAL str r1, [r0] ldr r0, =GAFR1_L ldr r1, =CFG_GAFR1_L_VAL str r1, [r0] ldr r0, =GAFR1_U ldr r1, =CFG_GAFR1_U_VAL

str r1, [r0] ldr r0, =GAFR2_L ldr r1, =CFG_GAFR2_L_VAL str r1, [r0] ldr r0, =GAFR2_U ldr r1, =CFG_GAFR2_U_VAL str r1, [r0] ldr r0, =PSSR /* enable GPIO pins */ ldr r1, =CFG_PSSR_VAL str r1, [r0] /* ---------------------------------------------------------------- */ /* Enable memory interface */ /* */ /* The sequence below is based on the recommended init steps */ /* detailed in the Intel PXA250 Operating Systems Developers Guide, */ /* Chapter 10. */ /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* Step 1: Wait for at least 200 microsedonds to allow internal */ /* clocks to settle. Only necessary after hard reset... */ /* FIXME: can be optimized later */ /* ---------------------------------------------------------------- */ 1: ldr r3, =OSCR /* reset the OS Timer Count to zero */ mov r2, #0 str r2, [r3] ldr r4, =0x300 /* really 0x2E1 is about 200usec, */ /* so 0x300 should be plenty */ ldr r2, [r3] cmp r4, r2 bgt 1b mem_init: ldr r1, =MEMC_BASE /* get memory controller base addr. */ /* ---------------------------------------------------------------- */ /* Step 2a: Initialize Asynchronous static memory controller */ /* ---------------------------------------------------------------- */ /* MSC registers: timing, bus width, mem type */ /* MSC0: ncs(0,1) */ ldr r2, =CFG_MSC0_VAL str r2, [r1, #MSC0_OFFSET]