OS를 만듭시다. 어때요~ 참 쉽죠? (1)

나빌레라의 이미지

OS. 영어로 풀어서 Operating System. 한자어로 번역해서 운영체제. 이것을 만든다고 하면 사람들은 굉장히 어렵게 생각한다. 리눅스나 윈도우같은 OS를 비교대상으로 본다면 OS를 만드는것은 정말 어렵고 힘들고, 개인이 만들기엔 어쩌면 불가능에 가까운 도전일지도 모른다. 하지만 OS의 기본 개념들은 대학교 학부과정에서 가르칠 정도로 이미 보편화 되어 있고 그 개념 자체들은 그다지 어렵지 않다. 개념 구현을 중심으로 동작하는 것 자체에 의미를 둔 OS를 만드는 것은 어쩌면 도전 해 볼만 한 가치가 있는 시도가 아닐까.

0. 준비

OS를 만들기로 결정했다. 그럼 그 다음에 해야 할 일은 무엇일까. 우리가 만들 OS가 동작하게 될 플랫폼을 결정하는 것이다. 물론 리눅스처럼 멀티플랫폼을 목표로 삼을 수도 있겠지만, 최초의 리눅스도 처음엔 PC에서만 동작했다.

인텔 x86기반의 OS제작에 관한 자료들은 생각보다 인터넷상이나 서적으로 많이 나와 있다. 그리고 그 자료들의 거의 공통점은 x86의 보호모드설명에 전체 내용의 거의 1/3 에서 2/3정도까지를 투입하고 있다. 그만큼 x86에서 OS를 만드는데 있어서는 보호모드에 대한 이해가 필수적이며 또한 설명을 그렇게 많이 한것 보면 보호모드라는 것이 쉽게 이해되는 부분이 아니라는 것을 알 수 있다. 보호모드에 대한 이해가 필수적이기는 하지만 그것은 어떻게 보면 보편적인 OS기본 개념과는 동떨어져 있는 것이고, 관점에 따라서 부차적인것으로 생각되기도 한다. 그리고 그 부차적인 것을 이해하기 위해 많은 시간을 투입하다 보면 때론 실질적인 개발을 하기도 전에 지쳐 포기 해 버리고 만다.

PC를 기반으로 개발하는 것이 개발환경을 구성하기도 편하고 추가적으로 비용이 들지 않는 다는 장점이 있긴 하지만, 보호모드라는 거대한 벽에 마주치게 된다. 그래서 다른 대안을 생각해 보다 결정한것이 x86만큼이나 보편적이고 많이 사용하고 있는 ARM기반에서 OS를 만들기로 결정 하였다. 물론 ARM개발보드를 구해야 하긴 하지만, 개발보드 한장 있으면 여러가지 재미 있는 프로젝트를 많이 시도 해 볼 수 있으므로 한장정도 가지고 있으면 여러가지로 많은 도움이 될것이라 생각한다.

이렇게 타겟플랫폼을 ARM 프로세서로 결정하면서 우리가 만들고자 하는 OS는 금새 임베디드OS 라는 하나의 범주에 속하게 되었다. 그렇다. 우리는 이제부터 임베디드OS를 만들게 될 것이다.

필자가 선택한 개발보드는 falinux사(falinux.co.kr)의 ez-x5 보드 이다. 상대적으로 가격이 저렴하고, 또한 중고를 구하기도 쉽기 때문이다. 그리고 제조사에서 필요한 여러가지 문서나 자료들을 비교적 우수하게 제공해 준다.

제조사의 홈페이지에 들어가서 보드스팩을 보면 ez-x5보드의 상세한 스팩을 볼 수 있다. 여기게 간단히 필요한 부분만 써 보자면 일단 인텔pxa255 프로세서를 사용하고 있다. ARM920 계열의 칩이라고 한다. ARM 칩은 각 계열과 코어명칭에 따라서 약간의 기능상의 차이가 있는데 그런것 까지 자세히 알지 않아도 우리가 목표로 하는 OS를 만드는데는 별 지장이 없다. 하드웨어적인 부분은 필요할때 그때 그때 설명하겠다. 그리고 무려 64메가의 RAM 이 있다. 64메가 밖에... 라고 생각 할 사람도 있을 지 모르겠지만 임베디드 환경에서 램이 64메가 라는 것은 매우 풍족한 용량이다. 또 64메가의 NAND플래시 메모리가 있다. 당초 리눅스 커널과 램디스크가 올라갈껄 예상하고 저렇게 많은 용량의 메모리를 보드에 붙였을 것이다. 우리가 만들 OS는 이미지 크기도 다 합쳐봐야 수십Kbyte 정도일터이니, 실상 무한에 가까운 광대한 용량이라고 볼 수 있다. 그외에 LED 도 있고 이더넷 칩도 있고 재미있는것들이 많이 달려 있다.

1. 일단 부팅하기

임베디드OS를 만드는 작업은 OS자체를 만드는 작업도 중요하지만, 실상 부트로더를 만드는 작업이 어쩌면 가장 어렵고, 절반에 가까운 시간을 잡아 먹는다. 하지만 부트로더를 만드는 작업은 타겟플랫폼에 거의 완전히 종속되는 작업이고, 하드웨어에 대해 많은 지식이 필요한 작업이다. 즉, 어렵다. 그래서 필자는 부트로더를 만들지 않기로 결정했다. 개발보드로 결정한 ex-x5보드에는 ezboot 라는 부트로더가 기본으로 제공된다. 부트로더는 그냥 이것을 사용하기로 한다. 이렇게만 해도 개발의 난이도가 절반으로 줄어든다.

ezboot는 ez-x5보드에 리눅스커널과 램디스크이미지를 올려서 부팅시키기 위한 목적으로 만들어 졌다. 그러므로 당연히 ezboot는 리눅스커널과 램디스크이미지를 NAND플래시에 기록해주는 기능을 가지고 있고, 부트초기화 작업을 마친후에는 RAM영역으로 커널이미지와 램디스크이미지를 올려주고 커널의 시작위치로 PC를 점핑해주는 로직을 반드시 가지고 있을 것이다.

우리가 만드는 임베디드OS는 ezboot에게 마치 리눅스 커널인양 행동하면 된다. 리눅스커널인양 NAND플래시에 기록되고, 리눅스커널이 올라가야할 위치에 올라가서 ezboot가 PC를 옮길때 우리가만든 OS의 시작위치로 옮기게끔 하면 되는 것이다. 사실 좀더 정확히 말하면 ezboot가 최종적으로 점핑하는 PC주소는 정해져 있고 바로 그 위치에 우리가만들게 될 OS커널의 엔트리포인트가 위치하게 될 것이다. 이것에 대한 내용은 이후에 설명 할 것이다.

무언가를 개발 할때 가장 빠르게 하는 방법은 기존에 이미 만들어져 있는 것중 내가 만들고자 하는 목적에 가장 가까운 것을 찾아서 그것을 내 목적에 맞게 고치거나, 필요한것을 가져다 쓰는 방법이다. 필자도 그러한 방법을 쓸 것이다. 그럼 우리의 목적에 가장 부합하는 '것'은 무엇일까? 고민의 여지가 별로 없다. 바로 ezboot 이다. falinux사의 홈페이지(www.falinux.co.kr)에서 ezboot의 소스코드를 다운로드 받자.

Makefile  eztiny  image  include  main  start

위와 같이 Makefile 과 다섯개의 디렉토리가 보일 것이다. eztiny는 일단 신경쓰지 말자. image 디렉토리는 ezboot의 최종 이미지파일이 들어간다. include 파일은 말 그대로 ezboot 소스가 사용하는 헤더파일들이 들어가 있다. main 과 start 디렉토리는 소스코드가 있다. start 디렉토리에는 어셈블리로 작성된 보드초기화 관련 코드들이 들어가 있다. 현시점에서는 역시 그대로 둔다. main 디렉토리에는 C언어로 작성된 코드들이 들어가 있다. 역시 현시점에서는 별로 건드릴 것이 없다. 다만 약간 참고해야 하는 부분은 있다.

ezboot의 실행순서는 일단 start 디렉토리에 있는 어셈블리 코드들이 컴파일되어 하나의 부분을 이루고, main 디렉토리에 있는 C코드들이 컴파일되어 하나의 부분을 이룬다. 메모리번지 0x0000_0000에 들어가는 코드는 start에 있으므로 보드에 전원이 들어오면 일단 start에 있는 코드들이 순서대로 실행이 된다. 그리고 나면 main 디렉토리에 있는 main()함수로 PC가 점핑한다. 이부분에 초점을 맞춰야 한다. main()으로 점핑하는 것. 우리가 만들 임베디드OS에도 main()함수는 존재하고, ezboot가 끝나면 우리의 OS에 있는 main()의 주소가 PC에 들어가게 해야 한다.

Makefile       entry.S           info_cmd.c      printf.c        vscanf.c
Makefile.bak  flash_29lvx.c    lib1funcs.S       ram_cmd.c   vsprintf.c
arp_cmd.c     flash_cmd.c     main-ld-script  serial.c        zmodem.c
config.c        go_cmd.c       main.c           string.c        zmodem_cmd.c
cs8900.c       gpio.c            nand.c           tftp_cmd.c
defaultlibs     help.c            net.c             time.c

main 디렉토리에 보면 파일이 많다. main.c 의 내용을 보면 알겠지만, 고맙게도 printf() 와 msleep()을 사용할 수 있다. 그렇게 되면 우리가 만들 OS의 첫 시작은 대충 그림이 잡힌다. 일단 간단하게 터미널프로그램을 통해서 hello world 를 찍는 것이다! (언제나 시작은 헬로월드다.) 소스코드의 내용은 다음과 같다.

#include <pxa255.h>
#include <time.h>
#include <gpio.h>
#include <stdio.h>
#include <string.h>
 
int main(void)
{
        while(1){
	        printf("hello world\n");
	        msleep(1000);
        }
}

부팅(아직 부팅이라고 명명하기엔 뭔가 민망스럽다.)이 완료되면 터미널화면에는 1초간격으로 hello world 가 찍힐것이다.

대충 파일명만 보고도 무엇을 남기고 무엇을 지워야 할지 알 수 있을 것이다. 그럼 새로운 디렉토리를 만들고, 상위디렉토리에 있던 include 디렉토리를 통채로 복사한다. 헤더파일들은 나중에 뭐가 더 필요할지 모르기 때문에 그냥 통채로 복사했다. 그리고 C소스파일은 아래의 것만 복사한다.

entry.S
gpio.c
lib1funcs.S
printf.c
serial.c
string.c
time.c
vsprintf.c
main.c
main-ld-script

main.c 함수는 위에 나온 코드로 바꾼다. 이제 코딩작업은 끝났다. 정말이다.

다음에 할 일은 개발환경을 구성하는 일이다. 윈도우에서는 ADS에서 이것저것 세팅하고 참 할일이 많다. 리눅스에서는 간단하게 arm-linux-gcc 패키지 압축파일만 받아다가 압축풀고 PATH를 설정해 주면 끝이다. arm-linux-gcc 패키지는 아래 주소에서 구할 수 있다.

http://www.applieddata.net/forums/topic.asp?TOPIC_ID=419
혹은
http://www.handhelds.org/download/projects/toolchain

여기서 arm-linux-gcc-3.3.2.tar.bz2 파일을 다운 받는다. 그리고 이 파일을 루트디렉토리(/) 에서 압축을 푼다. 그러면 /usr/local/arm/3.3.2 밑에 파일들이 복사된다. 그리고서 아래의 두 디렉토리를 PATH에 추가 한다. 압축푸는 방법및 PATH 추가하는 법은 굳이 설명하지 않겠다. OS개발에 도전 할 정도의 개발자라면 그정도는 능숙하게 할 수 있으리라 생각된다.

 /usr/local/arm/3.3.2/bin
 /usr/local/arm/3.3.2/sbin

개발 환경 구성이 끝났다. 정말이다.

이제 컴파일러를 사용 할 수 있고, 코딩도 끝났으니 컴파일만 하면 된다. Makefile을 만들자. 그냥 아래의 소스를 그대로 복사해서 Makefile을 만들면 된다. ezboot의 Makefile 에서 불필요한 부분을 빼고, 필요한 부분을 수정 해서 작성 하였다.

CC = arm-linux-gcc
LD = arm-linux-ld
OC = arm-linux-objcopy
 
CFLAGS    = -nostdinc -I. -I./include
CFLAGS   += -Wall -Wstrict-prototypes -Wno-trigraphs -O2
CFLAGS   += -fno-strict-aliasing -fno-common -pipe -mapcs-32
CFLAGS   += -mcpu=xscale -mshort-load-bytes -msoft-float -fno-builtin
 
LDFLAGS   = -static -nostdlib -nostartfiles -nodefaultlibs -p -X -T ./main-ld-script
 
OCFLAGS = -O binary -R .note -R .comment -S
all: main.c
    $(CC) -c $(CFLAGS) -o entry.o entry.S
    $(CC) -c $(CFLAGS) -o gpio.o gpio.c
    $(CC) -c $(CFLAGS) -o time.o time.c
    $(CC) -c $(CFLAGS) -o vsprintf.o vsprintf.c
    $(CC) -c $(CFLAGS) -o printf.o printf.c
    $(CC) -c $(CFLAGS) -o string.o string.c
    $(CC) -c $(CFLAGS) -o serial.o serial.c
    $(CC) -c $(CFLAGS) -o lib1funcs.o lib1funcs.S
    $(CC) -c $(CFLAGS) -o main.o main.c
    $(LD) $(LDFLAGS) -o navilnux_elf entry.o gpio.o time.o vsprintf.o printf.o string.o serial.o lib1funcs.o main.o
    $(OC) $(OCFLAGS) navilnux_elf navilnux_img
 
clean:
    rm *.o
    rm navilnux_elf
    rm navilnux_img

위의 Makefile 을 보고 눈치 빠른 분들은 아셨을 것이다. 우리가 만들려고 하는 임베디드OS의 이름은 '나빌눅스' 이다. 물론 필자의 아이디를 따서 이름을 붙였다. 자기의 이름을 붙인 OS를 하나정도 가지고 있는 것은 기분 좋은 일이다. :)

저렇게 해서 Makefile을 만들고 나면 가벼운 마음으로 make를 쳐 보자. 별다른 문제 없이 컴파일이 완료 되고 navilnux_img 파일이 생성될 것이다. 별로 한것도 없이 ezboot 의 소스를 가져다가 복사하고, 수정이랄것도 없이, 거의 코드를 삭제만 했더니 우리의 첫번째 커널 빌드 이미지가 나왔다. 이렇게 OS 대충 만들어도 될까 싶을 정도다.

그럼 이제 ez-x5보드(이하 이지보드)를 켜고 부트로더 프롬프트모드로 들어가자 [space]를 누르면 된다. 이지보드와 같이 들어 있는 이지보드 메뉴얼에서 이지부트 부분을 보면 리눅스이미지를 올리는 방법이 설명되어 있다. 역시 따로 설명하지는 않겠다. zfk 명령을 이용해서 이미지를 올리면 된다. 램디스크 올리는 명령은 사용할 필요 없다. 그냥 간단하게 이지보드에서의 이미지 올리고 테스트하는 순서만 설명 하겠다.

* 미니컴 설정
* 이지보드전원켬
* 부팅화면에서 [space] 누름
* zfk 입력
* zmodem 으로 navilnux_img 다운로딩
* reset 스위치를 누르거나 보드를 껏다켜거나 rst명령 입력
* 그냥 기다리거나 [enter] 누름
* 결과 확인

위와 같은 순서로 작업 하면 된다. 해보자. hello world 가 나올것을 기대하고 재부팅을 해본다. 하지만, 기대했던 hello world 는 나오지 않는다. 시키는 대로 코딩하고 컴파일까지 완료해서 이미지파일 까지 다 만들어서 보드에 다운로딩 까지 했는데 왜 안나오는 것인가! 독자들 나름대로 약간의 시간을 두고 고민해 보기 바란다.

자! 생각해 보았는가? 문제는 바로 링커옵션에서 주는 실행이미지의 로딩위치에 있다. 정적링크를 하기 때문에 링커스크립트에서 이미지의 로딩 주소를 직접 지정해 주어야 한다. 우리는 ezboot의 링커스크립트를 한줄 수정없이 그대로 사용했기 때문에, 당연히 navilnux의 커널 이미지는 어이없이 ezboot의 로딩영역으로 로딩된다. 칩 내부에서 어떤일이 벌어지는지는 알 수 없으나 아마 메모리영역이 중첩되거나 덮어쓰기되거나 충돌이나거나 하는 등의 비정상 혹은 의도하지 않은 동작이 일어나는 것이 분명하다. 그리고 계속 설명했듯이 ezboot는 부팅이 끝나고 나면 리눅스커널이 있어야만 하는 지정된 위치로 PC를 점프한다. 하지만 그 자리에는 아무것도 없다.(정확히는 쓰레기 값이 있다.) 당연히 아무것도 안보일 수 밖에 없다.

다시 이지보드의 메뉴얼에서 이지부트 부분을 보자. 이지부트의 메모리맵이 보인다. 아니면 이지부트의 main()함수를 살짝 살펴 보아도 된다. 일단 메뉴얼을 보면 RAM 부분의 메모리맵에 0xA0008000 부분 부터 리눅스커널이 시작된다고 나와 있다. (본 강좌에서는 최대한 그림을 그리지 않을 생각이다. 알아서 잘 찾아서 보기 바란다.) 그럼 이번엔 이지부트의 main() 함수를 보자

  case 0x0000 :
                // Autoboot =======================
                printf( "Quickly Autoboot [ENTER] / " );
                if( Cfg.BootMenuKey == ' ' )  printf( "Goto BOOT-MENU press [space bar]");
                else                          printf( "Goto BOOT-MENU press [%c]", Cfg.BootMenuKey );
 
                if ( getc_timed( Cfg.BootMenuKey, Cfg.AutoBootWaitTime*1000 ) )
                {
                    printf( "\n");
                    CopyImage();
                    GoKernel( 1, NULL );             
                }
                break;

위와 같은 코드조각이 보일 것이다. [ENTER]를 누르면 그냥 부팅이라고 했으니깐 printf() 메시지로 추정하건데 엔터를 누르면 위 코드가 수행되는 듯 하다. 쭉 훑어 봤을때 의심가는 부분은 바로 GoKernel() 함수이다. 이름에서 부터 무엇을 하는 함수인지 노골적으로 알려주고 있다. 함수의 코드는 go_cmd.c 에 있다.

int     GoKernelSingle( void )
{
        char buff[] = { 0,0,0,0,0 }; 
        void (*theKernel)(int zero, int arch);
 
    char kcmd[2048];
    int  len;
 
    memset( kcmd, 0, 2048 );
    len = GetKCmdStr( kcmd );
 
        printf( "Starting kernel [MARCH %d]...\n", Cfg.Kernel_ArchNumber );
 
        memcpy( (char *) DEFAULT_RAM_KERNEL_ZERO_PAGE, kcmd, 2048 );
 
        theKernel = (void (*)(int, int))DEFAULT_RAM_KERNEL_START;
        theKernel( ( long ) 0 , (long) Cfg.Kernel_ArchNumber );
 
        return 0;
}
 
int     GoKernel(int argc, char **argv)
{
    if ( Cfg.Watchdog )
    {
        SetWatchdog( Cfg.Watchdog*1000 );
    }
 
        GoKernelSingle();
        return 0;
}

GoKernel() 함수로 들어가고 나면 GoKernelSingle()함수로 가게 되고, GoKernelSingle()함수에서는 DEFAULT_RAM_KERNEL_START 번지의 함수포인터로 넘어간다. 즉 , DEFAULT_RAM_KERNEL_START번지를 PC에 넣어준다. DEFAULT_RAM_KERNEL_START 는 include 디렉토리에 mem_map.h 에 정의되어 있다.

#define DEFAULT_RAM_KERNEL_START        0xA0008000

이제 0xA0008000 에 리눅스 커널 엔트리포인트가 들어가야 하고 ezboot는 수행이 종료되면 무조건 0xA0008000으로 점프함을 알 수 있다. 그럼 이제 남은 일은 navilnux_img 가 로딩될때 0xA0008000 에 위치하게 하면 된다. Makefile을 유심히 본 독자는 알 수 있을 것이다. 링커옵션으로 들어간 main-ld-script 파일을 고치면 된다.

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_ram_entry)
SECTIONS
{
    . = 0xA0008000;
 
    . = ALIGN(4);
    .text : { *(.text) }
 
    . = ALIGN(4);
    .rodata : { *(.rodata) }
 
    . = ALIGN(4);
    .data : { *(.data) }
 
    . = ALIGN(4);
    .got : { *(.got) }
 
    . = ALIGN(4);
    .bss : { *(.bss) }
}

위와 같이 수정한다. 뭐 사실 딱 한줄만 수정하면 된다. 바로 시작 주소를 아까서부터 계속 설명한 0xA0008000으로 바꿔 준 것이다. 이제 다시 make 를 실행해서 이미지 파일을 만들고 zfk 로 다운로딩하고, 재부팅 해 보자.

반가운 hello world 가 1초간격으로 잘 나온다. 이렇게 얼렁뚱땅 OS제작을 위한 첫 걸음마를 떼었다. 다음 편에서는 보드의 LED를 켜 보도록 하겠다.

이글은 http://raonlife.com/navilera/blog/view/75/에 동시 연재 됩니다.

댓글

atie의 이미지

마치 고행석 만화 한 권을 본 듯 합니다. 재미있게 읽었습니다.
----
I paint objects as I think them, not as I see them.

----
I paint objects as I think them, not as I see them.
atie's minipage

OpenSnake의 이미지

잘보겠습니다... :)

근데요 include 부분에 헤더파일부분의 지워졌네요...

code 넣을시에는 키보드 M 오른쪽에있는 꺽쇠로 하면
안지워지더군요..

--------------------------------------------
혼자있고 싶습니다. 모두 지구밖으로 나가주세요.

--------------------------------------------
혼자있고 싶습니다. 모두 지구밖으로 나가주세요.

나빌레라의 이미지

그걸로 한건데 안나오네요..-_-;
lt; gt; 로 급수정..^^;

얇은 사 하이얀 고깔은 고이 접어서 나빌레라

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

codebank의 이미지

'참 쉽죠?'...

그림 그리시던 밥아저씨던가? 하여간 그아저씨 그림그리는거보면 '참 쉽게 그린다'라는 생각이 들긴했지만
막상 그렇게 안되었던 기억이 나네요.
그나저나 글이 재미있네요. :-)
------------------------------
좋은 하루 되세요.

------------------------------
좋은 하루 되세요.

junichel의 이미지

ez-x5는 한번 작업해본 보드라서 머릿속에 윗 글에서 하는 것이 그려지는군요.
+_+ez-x5보드로 작업하는 많은 사람들에게 도움되는 글이 될 것같습니다.
글에서 하나하나 살을 붙여나가 멋진 os가 되길바라겠습니다.+_+
----------------------------------
끝까지 타오르는거다!

--
끝까지 타오르는거다!

namhw의 이미지

궁굼했던 점들을 잘 정리해주셨네요. 감사합니다~ 드뎌 예전에 중고로 샀던 ez-x5를 사용해보게 됐네요.^^;; 그런데 따라하다가 보니 컴파일시 링크부분에서 에러가 발생하여 config.c와 flash_29lvx.c를 추가해야만 에러없이 컴파일이 되더군요. 다른분들은 어떤지 굼궁해서 리플 남깁니다. 그럼 나머지도 따라해봐야 겠네요.

촌놈.

촌놈.

나빌레라의 이미지

음..

다음 회 부터는 해당 연재분까지 구현된 코드를 같이 올리는게 좋을 것 같군요..

링크에러라니....

config.c 같은 경우는 코드에서 특정 줄을 삭제해버리고 컴파일 하면 되었던것 같고..

flash저녀석은 왜 나는거지..흠..

강좌가 허접해서 죄송합니다... (--)(__)

---
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

namhw의 이미지

허접하다뇨!! 감사하게 잘 보고 있습니다. 얼마전부터 ARM을 공부하면서 어떻게 재미있게 공부할 수 있을까라는 고민중에 이 강좌를 보고 기뻐했습니다.^^;; 그럼 지속적인 강좌 부탁드리겠습니다.

촌놈.

촌놈.

greatgw의 이미지

make 하니깐

Makefile:15: *** 분리기호 이(가) 빠졌음. 멈춤.

라고 뜨는데요...

나빌레라의 이미지

그냥 긁어다 붙이면 에디터에 따라서 탭문자를 공백으로 바꿔버려서
Make 가 Makefile 의 탭구분자를 인식안해 에러가 나기도 합니다.

1,2,3 회차 강좌까진 그냥 읽으시고,

4회차 강좌부터 첨부되는 소스코드 타르볼을 풀어서

연습해주세요..^^

감사합니다.
----
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

greatgw의 이미지

방금 문제를 해결하고 글 삭제하려고 왔는데 벌써 답글을 달아주셨네요... 감사합니다..ㅋ
잘 보고갑니다~ 그런데 궁금한게.. 언제쯤 강의가 끝나나요??ㅋㅋ

greatgw의 이미지

보드가 고장나서 한동안 작업을 못하다가 다시 시작했는데,

궁금한게 있어서요.. 지금 이 강좌에서는 이지부트를 수정해서 만들고있잖아요,

그런데 부트로더를 손대고 있으면 보드에 다운로드할때 zfk가 아닌 zfb로 부트로더를 올려

줘야 되는거 아닌가요? zfk로 올리는건 커널을 올리는거 아닌가요..??

나빌레라의 이미지

1회차 강좌인 이번 강좌에서는 부트로더를 수정하지 않고

그냥 zfk 로 커널이미지만 올립니다.

이후 강좌에서 부트로더의 Exception Vector Table 로부터 점핑하는 주소를 수정하는데

그때는 이지부트를 수정하고 다시 빌드한 다음 JTAG를 이용해서 보드에 writing 합니다.

감사합니다..^^
--------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

corone의 이미지

좋은 글 올려주셔서 정말 감사합니다
이에 관심을 갖고 있던 터인데 좋은 글을 발견했네요

직접 올리신 것인지 퍼오신 것인지 모르지만
쓰신 분 대단하시네요
설명도 참 잘하시고..

그래도 학생입장에서 봤을 땐 역시 밥아저씨 같아요^^;;

아무튼 좋은 글 다시 한번 감사드립니다

나빌레라의 이미지

직접 쓴겁니다.

인터넷 상에서 본 강좌와 같은 내용의 글을 발견하신거라면

해당 게시물을 올린 사람이 제 글을 불법으로 퍼 간것입니다.

-----
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

wertyu의 이미지

요즘은 한글로 된 글을 읽어도 머리에 도통 들어오질 않았는데, 이 강좌는 머리에 쏙쏙 들어옵니다.

OS에 관심많던 10년 전 학생 시절에 이 글을 읽었으면 더욱 좋았겠지만요^^

훌륭한 글 잘 읽었습니다.

감사합니다.

tomahawk28의 이미지

강좌 잘 봤습니다. ex-x5로 이런저런 것도 다해보니 신기하고 재밌네요..
그런데 주신 makefile로 탭처리까지 문제없이 했는데 막상 돌리려고 보니

 
arm-linux-ld -static -nostdlib -nostartfiles -nodefaultlibs -p -X -T ./main-ld-script -o navilnux_elf entry.o gpio.o time.o vsprintf.o printf.o string.o serial.o lib1funcs.o main.o
serial.o(.text+0x140): In function `SerialInit':
: undefined reference to `Cfg'
make: *** [all] Error 1

이런 에러를 내네요.. =_=; serial.c에 포함되있던 variable이던데 거기서
앞에 있는 extern 보고는 힘이 빠지네요;;


Can't stop watching this;;

tomahawk28의 이미지

아 윗분말대로 Makefile에 flash_29lvx.c랑 config.c를 넣어야했군요;;
자문자답이 되어버렸네요 ^_^;
좋은 강좌 감사합니다~


Can't stop watching this;;

aceofsc의 이미지

entry.o(.text+0x0): In function `_ram_entry':
: undefined reference to `main'

entry.S
.globl _ram_entry
_ram_entry:
bl main // C 함수의 main함수를 호출한다.
b _ram_entry // main 함수의 호출이 끝났다면 재 호출한다.
이부분의 에러는 어떻게 수습하나요

chillin2의 이미지

책 9쪽에 arm-linux-3.3.2.tar.bz2 를 설치하고

에디터 프로그램을 사용해서 홈 디렉터리의 .profile 파일에 아래 한 줄을 추가한다. 라고 되었는데..

.profile 파일을 찾을 수가 없습니다.

전 페도라 9에서 실습중이구요.

그리고 20페이지에서

$ make distclean

$ make gumstix_config

$ make all

에서

make all하면 error가 납니다....


어떻게 해결해야 하나요..??

dbckdgns의 이미지

저도 잘 모르지만 책을 사서 이제 시작하고있거든요.
.profile은 숨겨진 파일이니까 ls -a 하시면 보일텐데요.
그래도 없으신가요? 없어도 기냥 홈폴더에서 vi .profile 하시면 뭔가 작성된 내용이 보이실거에요.
그리고 에러내용이 어떻게되나요?

xylosper의 이미지

없으면 만드시면 됩니다.

익명 사용자의 이미지

윈도우에서 시그윈 설치하고 있는데로 다따라 하고 책에있는데로다하고 마지막에 qemu폴더에 navilnuximg 파일 넣고 실행시키고 다

시cmd창열어서 telnet 127.0.0.1 2848 로 들어가면 enter critical section mutex , enter critical section semaphoer가

번갈아가면서출력되네요 으허허허허 왜이럴까요 ㅠㅠ

익명 사용자의 이미지

안녕하세요 도전 임베디드 OS 책을 보면서 이제 막 공부를 시작한 새내기입니다.

책 내용대로 main 폴더의 소스들 편집하고 지울 것들 지우고 makefile까지 만들어 모든 준비를 마친 후 make를 실행하면...

다음과 같은 에러 메세지가 뜹니다.

/usr/local/arm/3.3.2/lib/gcc-lib/arm-linux/3.3.2/../../../..arm-linux/bin/ld: cannot find -lfloat
collect2: ld returned 1 exit status
make: *** [all] Error 1

구글링으로 찾아보면 툴체인 패치 얘기가 나오고, lfloat에 관한 내용을 찾아보려고 해도 마땅한 답이 나오질 않네요. 찾아도 이 책으로 처음 리눅스를 접하는 것과 다름이 없는 처지라 이해가 잘 안 가서 해결을 못하고 있는 것 같습니다.

이렇게 찾아 헤메이다가 저자님의 홈페이지를 찾게 된 것 같네요..

조언 부탁드리겠습니다...

익명 사용자의 이미지

좋은 자료 감사드립니다

익명 사용자의 이미지

OS를 만듭시다. 어때요~ 참 쉽죠? (20) - 완결
https://kldp.org/node/92193#comment-607465

nshlny의 이미지

entry.o(.text+0x0): in function ‘_ram_entry’:
: undefined reference to ‘main’
vsprintf.o(.text+0x130): in function ‘number’ :
: undefined reference to ‘__umodsi3’
vsprintf.o(.text+0x140): in function ‘number’ :
: undefined reference to ‘__umodsi3’
vsprintf.o(.text+0x574): in function ‘vsprintf’ :
: undefined reference to ‘strnlen’
make: *** [all] 오류 1

어떻게 해결해야 될까요? vmware 에 fedora7 입니다..

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.