Presentation is loading. Please wait.

Presentation is loading. Please wait.

(실습) 부트로더 [BootLoader]

Similar presentations


Presentation on theme: "(실습) 부트로더 [BootLoader]"— Presentation transcript:

1 (실습) 부트로더 [BootLoader]
네트워크 프로그래밍

2 EMPOS-II EMPOS-II

3 부트로더 실행 출력 메시지 EMPOS_boot에 관한 간단한 Copyright 정보
Ethernet을 사용하기 위해 장착된 LAN91C111 Controller의 초기화가 이상 없이 동작 kernel, ramdisk가 Flash에서 RAM 상으로 Copy가 이상 없이 진행되었다는 내용 Autoboot를 하지 않고 Command mode를 사용하기 위해서는 key를 입력하라는 내용 help 명령으로 현재 부트로더에서 사용 가능한 명령어를 확인하라는 내용 This is EMPOS_boot version 0.1 This is free software, and undered GNU GPL license Primary LAN91C111 is OK.! Copy kernel from ROM to RAM .... Copy ramdisk from ROM to RAM Autoboot in progress, press any key to stop. 1 * Type 'help' to get a list of commands * EMPOS #

4 부트로더의 명령어 EMPOS # help * The following commands are supported *
1. boot : Boot the kernel at ram 2. reset : Restart this bootloader at rom 3. bootp : Get IP by bootp 4. setip : Set IP on host and client 5. macwrite : Set MAC address on client 6. tftp : Download images by tftp 7. download : Download images by uuencode 8. read : Read value on a specific address 9. write : Write value on a specific address 10. flash : Write images that are previously downloaded 11. erase : Erase flash area 12. status : Print S/W, H/W and network status 13. help : Print help message for users to operate this program 14. test : Add your code in this function for S/W, H/W test * Use 'help command' to get help on a specific command * EMPOS #

5 reset - 롬의 Bootloader로 다시 시작
download - Serial을 이용하여 파일 다운 flash - 전송 받은 파일을 flash rom에 저장 status - 타겟 보드의 상태 표시 bootp - bootp를 이용하여 호스트 PC로부터 IP 전송 tftp - Ethernet을 통해 데이터(이미지) 전송 write - 레지스터의 값을 설정 read - 메모리 번지의 값을 표시 macwrite – MAC 어드레스 설정 setip - 임의로 IP 설정 test - 하드웨어 구성요소 테스트

6 status Flash 메모리내 해당 데이터(booter, kernel, ramdisk, usr)의 주소, 보드의 IP, tftp 서버의 IP, MAC 주소와 중요 레지스터의 값을 표시 EMPOS # status * Memory Map * bootloader) ROM : 0x , RAM : 0xA3D00000, LENGTH : 0x0000C000 kernel) ROM : 0x000C0000, RAM : 0xA00C0000, LENGTH : 0x ramdisk) ROM : 0x , RAM : 0xA , LENGTH : 0x usr) ROM : 0x , RAM : 0xA , LENGTH : 0x * Network Status * Host (server) Ethernet : 0xFFFF FFFF FFFF Host (server) IP : Client (target) Ethernet : 0x000B A A Client (target) IP : Primary (target) Ethernet : 0x000B A A Secondary (target) Ethernet : 0x000B A B * Registers Value * MDCNFG address : 0x value : 0x00001ACB MDREFR address : 0x value : 0x000BC018 ……. EMPOS #

7 setip IP 주소 설정 호스트 PC의 IP와 보드에 할당될 IP를 순서대로 입력
EMPOS # setip Host (server) IP : Client (target) IP : EMPOS #

8 tftp 고속전송이 가능한 Ethernet을 통해 이미지를 전송 EMPOS # help tftp
* Help for the 'tftp' * tftp [file] [position] : Download images by tftp * Arguments explain * 1. file : File name in tftp service directory 2. position {booter/kernel/ramdisk/usr} : Saving position at ram * Example use * tftp zImage kernel EMPOS #

9 실습: tftp 호스트 PC에 이미지 복사 커널/램디스크 이미지 전송 # whoami root # mkdir /working
# cd /working # cp –r /run/media/com518/EMPOSII/Image/all-images . # cp all-images/empos-boot /tftpboot # cp all-images/zImage /tftpboot # cp all-images/ramdisk16.gz /tftpboot EMPOS # setip EMPOS # tftp zImage kernel EMPOS # flash kernel EMPOS # tftp ramdisk16.gz ramdisk EMPOS # flash ramdisk EMPOS # reset

10 부트로더의 명령어 read 특정 메모리 번지의 값을 확인 하기 위해 사용되는 명령
EMPOS # help read //* Help for the 'read' * read {b8/b16/b32} [address] [len] : Read value on a specific address * Arguments explain * 1. bit : read bit number per excute 2. address : Specific address to read 3. len : length to read, default is '0x1‘ * Example use * 1. read b32 0x xa 2. read b8 0x EMPOS # EMPOS # read b32 0x address : 0x value : 0x00001ACB

11 write 하나의 메모리 레지스터에 값을 변경하기 위해 사용 EMPOS # help write
* Help for the 'write' * write {b8/b16/b32} [address] [value] : Write value on a specific address * Arguments explain * 1. bit : read bit number per execute 2. address : Specific address to write 3. value : Value to write EMPOS # EMPOS # write b32 0x C 0x12BC5554 previous value address : 0x C value : 0x7FF17FF4 changed value address : 0x C value : 0x12BC5554 EMPOS #

12 H/W Address 7 SEGMENT LED Low (0x10300000) High (0x10400000)
TEXT LCD(0x ) LED(0x )

13 실습: wirte 명령어 타겟보드(EMPOS II)에 부착된 LED를 write 명령어를 사용하여 테스트
LED 물리주소 : 0x 부터 시작 ex) 0x00 일 경우 ( ) 모든 LED에 불이 꺼짐 ex) 0xff 일 경우 ( ) 모든 LED에 불이 켜짐 write 명령어를 사용하여, 첫번째 LED와 마지막 LED만 불이 켜지도록 테스트하라. EMPOS # write b8 0x x00 EMPOS # write b8 0x xff

14 부트로더의 소스 구성 Source Makefile - make 유틸리티에 사용되는 컴파일 스크립트
start.S - 처음 시작하는 코드로써 래지스터 세팅 main.c - 전체적인 부트로더 시퀀스 통제 commans.c - 대부분의 명령어 처리 lib.c - 소스에서 사용하는 여러 라이브러리 성격의 함수 제공 flash.c - flash 메모리에 데이터를 저장 serial.c - FFUART 초기화 및 모니터링을 위한 기본 함수 time.c - 부트로더에서 사용하는 타이머 담당 smc91111.c - 네트워크 디바이스파일로써 저수준 네트워크 통신 기능 net.c bootp.c - bootp 패킷의 구성과 전달 기능 tftp.c - tftp 패킷의 구성과 전달 기능

15 부트로드 다운로드 및 실행 부트로더 상에서 tftp 나 download 명령으로 부트로더를 다운로드 받은 후, 플래시 ROM에 부트로더를 저장

16 소스 코드 복사 압축 해제 부트로더 컴파일 # cd /working
# cp /run/media/com518/EMPOSII/Source/bootloader/empos_boot.tar.gz . # tar xvfz empos_boot.tar.gz # cd /working/empos_boot # make

17 tftp를 이용한 부트로더 퓨징 호스트 PC에서 부트로더 코드에 Copyright 정보를 추가하여 출력하도록 수정
타겟 보드에서 다운로드 Reset 명령을 수행하여 추가한 정보가 출력되는지 확인 # vi main.c SerialInit(); printf("\n\nThis is EMPOS_boot version 1.0\n"); printf("This is free software, and undered GNU GPL license\n"); printf("In network programming, by ahnjae\n"); //add by ahnjae # make # ls -al empos_boot # cp empos_boot /tftpboot EMPOS # setip EMPOS # tftp empos_boot booter EMPOS # flash booter

18 부트로더에서 H/W 테스트 보드에 내장된 8 LED를 on/off 시키는 code를 해당 함수에 넣어 간단한 하드웨어 테스트
main.c에서 명령어를 추가, commands.c 명령처리 루틴을 추가 # vi main.c } else if (!StrCmp(argv[0], "test")) { suc = DoTest(argc, argv); //test 명령이 들어왔을 경우 DoTest를 실행 한다. # vi command.c bool DoTest(int argc, char **argv) { if(StrCmp(argv[1], "led") ==0){ u16 val; if (!HexToInt(argv[2], &val, 8)){ return false; } __REG8(0x ) = val; return true;

19 타켓의 부트로더 환경에서 test 실행 0x11값을 변경하여 테스트
EMPOS # test led 0x // 1,5 LED on

20 실습 : 7 SEGMENT 제어 7segment_low =0x1030 0000 7segment_high =0x1040 0000
4개의 7 segment LED로 구성된 write 구조 4개의 7 segment는 8개의 출력 bit로 구성 32bit CPU 제어를 위해 2개의 7 segment 단위(16bits)로 제어 7 segment LED 정보 지속을 위해 latch 구조 회로 7segment_low =0x 7segment_high =0x

21 Code BCD-to-7segment Decoder Activate signal: positive, negative
Display: 0-1 figures Code 1: 0bc0 0000 2: ab0d e0g0 a b c d e f g dp 표시 7 세그먼트 비트 값 데이터 값 dp g f e d c b a 1 0x3f 0x06 2 0x5f 3 0x4f 4 0x66 5 0x6d 6 0x7d 7 0x27 8 0x7f 9 0x6f

22 7 SEGMENT를 제어하는 프로그램 작성 #vi command.c
bool DoTest(int argc, char **argv) { if(StrCmp(argv[1], "led") ==0){ ….. } else if(StrCmp(argv[1], "segment") ==0){ u16 val; if (!HexToInt(argv[2], &val, 16)){ return false; if(StrCmp(argv[3], "low") ==0){ __REG16(0x ) = val; if(StrCmp(argv[3], "high") ==0){ __REG16(0x ) = val;

23 부트로더 컴파일 Tftp를 이용한 부트로더 다운로드 7segment 테스트 0x0000값을 변경하여 테스트
#cd /working/empos_boot #make clean #make #cp empos_boot /tftpboot EMPOS # setip EMPOS # tftp empos_boot booter EMPOS # flash booter EMPOS # reset EMPOS # test segment 0x0000 low EMPOS # test segment 0x0000 high

24 실습 : Text LCD 제어 TEXT LCD를 제어하는 프로그램 작성
dptr1 = 0x // lcd 레지스터 시작 물리주소 Lib.c에 정의되어 있음 #vi command.c bool DoTest(int argc, char **argv) { if(StrCmp(argv[1], "led") ==0){ ….. } else if(StrCmp(argv[1], “segment”)==0) { else if(StrCmp(argv[1], “textlcd") ==0){ u16 val; //dptr1 = 0x ; if (!HexToInt(argv[2], &val, 16)){ printf("hextoint error\n"); return false; printLCD(val, argv[3]);

25 부트로더 컴파일 tftp를 이용한 부트로더 다운로드 textlcd 테스트 TEST값을 변경하여 테스트
#cd /working/empos_boot #make clean #make #cp empos_boot /tftpboot EMPOS # setip EMPOS # tftp empos_boot booter EMPOS # flash booter EMPOS # reset EMPOS # test textlcd 0 TEST EMPOS # test textlcd 1 TEST

26 실습 응용 1 DoTest 함수의 lcd 제어 코드에서 Text LCD가 clear된 후에 입력된 문자들이 출력될 수 있도록 수정하시오 Void clearLCD(void) 함수를 lib.c에 추가 이후에 command.c에 clearLCD()를 추가 //add by ahnjae void clearLCD(void) { LCD_word(CTRL,0x0401); // allclr LCD_word(CTRL,0x0001); } void printLCD(int line, char *printchar) else if(StrCmp(argv[1], “textlcd") ==0){ u16 val; if (!HexToInt(argv[2], &val, 16)){ printf("hextoint error\n"); return false; } clearLCD(); printLCD(val, argv[3]);

27 실습 응용 2 DoTest 함수에서 seg_al 명령을 추가하여, 4개의 7 SEGMENT가 A, B, C, D를 표시 하는 프로그램을 작성하시오 EMPOS# test seg_al a  4개의 7세그먼트에 A가 출력 표시 7 세그먼트 비트 값 데이터 값 dp g f e d c b a A 1 0x77 B 0x7c C 9 0x39 D 0x5e

28 실습 응용 2 command.c

29 부트로더 프로그램 main.c start.S 의 어셈 파일의 마지막에서 c언어 함수인 c_main 함수를 호출할 때 불려지는 c_main()함수 SerialInit() 함수를 사용하여 시리얼을 초기화한 다음 현재의 부트로더 정보를 직렬포트를 통해 호스트 컴퓨터의 시리얼 프로그램에 전송 #include <config.h> ... void c_main(void) { int i; int autoboot=1; int timeout; char commandline[200]; SerialInit(); printf("₩n₩nThis is EMPOS_boot version 0.1₩n"); printf("This is free software, and undered GNU GPL license₩n");

30 main.c Peripheral Control Register라는 타겟보드 레지스터의 값을 세팅하고 타겟 보드에 있는 각종 I/O 디바이스를 테스트, ethernet 디바이스를 초기화 한 후 플래시 ROM에 커널과 램 디스크를 램으로 복사 __REG(0x ) =0x9000; user_wait(100*556); __REG(0x ) =0x1f00; user_wait(250*556); IoTest(); //Board의 각종 IO를 테스트 한다, eth_init(); //이더넷을 초기화 한다. /* 메모리 copy */ printf("₩nCopy kernel from ROM to RAM "); MemCpy32((u32 *)KERNEL_RAM_BASE,(u32*)KERNEL_ROM_BASE,KERNEL_LENGTH/4); printf("₩nCopy ramdisk from ROM to RAM "); MemCpy32((u32*)RAMDISK_RAM_BASE,(u32*)RAMDISK_ROM_BASE,RAMDISK_LENGTH / 4);

31 Serial 초기화 void SerialInit(void) {
__REG(FFUART_BASE + FFLCR) = 0x ; // 8-bit, 1 stop, no parity 세팅. __REG(FFUART_BASE + FFFCR) = 0x ; // Reset tx, rx FIFO. clear. FIFO enable __REG(FFUART_BASE + FFIER) = 0x ; // UART Enable Interrupt __REG(FFUART_BASE + FFLCR) |= 0x ; // DLAB set=latch registers, //DLAB clear=일반 포트. __REG(FFUART_BASE + FFDLL) = SERIAL_SPEED_RATE; // baud rate 설정. __REG(FFUART_BASE + FFLCR) &= 0xFFFFFF7F; // DLAB clear, 일반 포트로 전환. // Transmit Shift Register, Transmit Holding Register, FIFO에 // 데이타가 없을때까지 기다린다. while(! __REG(FFUART_BASE + FFLSR) & 0x ); return; }

32 부트로더에서 오토 부팅,명령어 모드 부팅 while 문을 돌면서 시리얼 포트에서 입력이 있으면, autoboot 프래그(flag)를 false로 주어 명령어 모드로 들어 가도록 구성 명령어 모드로 들어가면 while로 무한 루프를 돌면서 GetCommand() 함수로 명령을 받고 RunCommand() 함수로 명령 구성 /* 오토 부팅을 결정 */ printf("₩nAutoboot in progress, press any key to stop. "); for (i=0; i<BOOT_DELAY; i++){ timeout = GetTime()+1; // 1초간 Delay printf("₩b"); printf("%d",BOOT_DELAY‐i); while (GetTime()<timeout){ if ((__REG(FFUART_BASE + FFLSR) & 0x )){ __REG(FFUART_BASE + FFRBR); autoboot = false; break; } if (autoboot==false) break; if(autoboot) boot_kernel(); // 커널 로딩 //오토 부팅 FALSE일 경우 printf("₩n₩n₩t* Type 'help' to get a list of commands *"); while(1){ printf("₩nEMPOS # "); if(GetCommand(&commandline[0])) RunCommand(&commandline[0]);

33 RunCommand() 함수 입력 받은 문자열 즉 commandline 문자열을 명령어와 매개 변수로 분리한 다음 명령어에 따른 함수를 호출 하는 형식 void RunCommand(char* commandline){ char *argv[10]; char malloc[10][50]; int argc=0; int command_i=0, arg_i=0; int i=0; for(i=0;i<10;i++) argv[i] = &malloc[i][0]; while(1){ if(commandline[command_i]=='₩0') { argv[argc][arg_i]='₩0'; argc++; break; } I if(commandline[command_i] ==' '){ if(arg_i ==0){ command_i++; continue; if (argv[argc][arg_i‐1] ==' '){ }else{ argv[argc][arg_i] = '₩0'; arg_i=0;

34 부트로더에서 tftp가 동작이 되지 않는 경우
1) 보드의 MAC 주소 확인 EMPOS II의 초기 MAC 주소는 보드 상단에 부착되어 있음 status로 primary의 MAC 주소값을 확인하고, 보드 상단에 부착되어 있는 MAC 주소와 다르면 macwrite 명령어로 수정 이후에, tftp 동작을 다시 확인 EMPOS # help macwrite * Help for the ‘macwrite’ * macwrite {pri/sec} [MAC addr] : Set MAC addr on client * Arguments explain * 1. target client : target to change MAC 2. MAC addr : Client MAC address in using * Example use * 1. macwrite pri 000ba EMPOS # status ……… EMPOS # macwrite pri [보드 상단에 부착되어있는 eth0값]

35 부트로더에서 tftp가 동작이 되지 않는 경우
2) tftp-server 경로 재설정 일반적으로 tftp-server의 디렉토리 경로로 /tftpboot를 많이 사용한다. 하지만, tftp-client에 따라서 이를 접근하지 못하는 경우가 있다. 이를 해결하기 위해, tftp-server의 경로를 /var/lib/tftpboot로 바꾼다. vi /etc/xinetd.d/tftp systemctl restart xinetd.service 이후에, tftp 동작을 다시 확인 service tftp { protocol = udp socket_type = dgram wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /var/lib/tftpboot disable = no per_source = 11 cps = 100 2 flags = IPv4 }

36 부트로더에서 tftp가 동작이 되지 않는 경우
3) Serial을 이용한 파일 전송 타겟보드에서의 download 명령어와 호스트 PC의 uuencode 명령어를 통해 Serial로 파일을 전송할 수 있다. 전송속도가 매우 느리다. EMPOS # help download * Help for the 'write' * download [position] : Download images by uuencode * Arguments explain * 1. position {booter/kernel/ramdisk/usr} : Saving position at ram * Example use * 1. <client> download kernel <host> uuencode zImage zImage > /dev/ttyS0

37 부트로더에서 tftp가 동작이 되지 않는 경우
Host PC에서 uuencode 명령어가 없다면, yum으로 설치 타겟보드에서 download 명령어로 이미지 수신 준비 호스트 PC에서 uuencode 명령어로 이미지 전송 타겟보드에서 이미지 수신 완료 (오래 걸림) # yum install –y sharutils EMPOS # download kernel * Translate image by using uuencode in host PC * # uuencode zImage zImage > /dev/ttyUSB0 EMPOS # download kernel * Translate image by using uuencode in host PC * ……………………………………………………………………………………………………………………………………………………………………………… Received bytes : 0x000EBAEC EMPOS # flash kernel EMPOS # reset


Download ppt "(실습) 부트로더 [BootLoader]"

Similar presentations


Ads by Google