close
티루트 . 처음 . 목록 . 전시 . 앨범 . 찾기 . 방명록 . 링크 . 흔적 . 일기장 . 관리자



+ 최근 글

  • ` 통진당 난장판의 긍정효과.. (1)
  • ` 이재오는 왜 나왔을까?.
  • ` 제임스 갈브레이드.
  • ` 영화들... (6)
  • ` 담담한 하우스 푸어 기사.



  • + 최근 댓글

  • ` 정말 그렇군. *vividian
  • ` 난 배트맨 비긴즈는 좋아해염... 뭔가 오덕스러운... *dawnsea
  • ` 아.. 기사 윌리엄이 히스 레저였구나.. OTL ... *dawnsea
  • ` 브라이언 싱어의 슈퍼맨은 렉스루터도 매력없어요... *코젯
  • ` 아니 뭐 내가 뭘 알고 쓰는 건 아니고 영화라고는... *dawnsea



  • + 최근 엮인글

  • ` dawnsea의 생각 *dawnsea's me2day
  • ` [파이어폭스,팁] 파이어폭스 포터블 업데이트, 쓰... *월풍도원(月風道院) - Delight on the Simple Life
  • ` 일룸 옷장 전시품 판매합니다~~(일룸올리) *iloom1님의 블로그
  • ` 색깔 심리 테스트 *활자중독증
  • ` 티에프의 생각 *tfurban's me2DAY

    임베디드

    1. 2011/07/25 커널 부팅 초기 디버그
    2. 2011/06/09 우분투만의 독특한 커널 개발 환경
    3. 2011/05/06 glibc build 정리 중.. (2)
    4. 2011/05/06 gcc 4.6 build 하기. (1)
    5. 2011/03/30 SVN Store password unencrypted (yes/no)?
    6. 2011/03/30 우분투에서 tortoise 처럼 svn 쓰기, nautilus 확장
    7. 2011/03/25 우분투만 설치해서 grub 메뉴가 안 나올 때.
    8. 2011/03/24 fork, wait, exit
    9. 2011/03/21 우분투 커널 컴파일, 설치 완전 쉽네;; (1)
    10. 2011/01/25 svn mirroring
    11. 2011/01/14 이 죽일 놈의 .svn 디렉토리
    12. 2011/01/13 printk 수다 레벨 조정 (1)
    13. 2011/01/12 build 시간 구하기, 시스템 수행 시간 구하기 @ linux (1)
    14. 2011/01/03 Embedded Linux Wi-Fi
    15. 2011/01/03 wpa supplicant 없이 wi-fi 간이 설정
    16. 2010/12/29 kernel jiffies read (1)
    17. 2010/12/23 linux ramdisk image making
    18. 2010/12/21 qt, qmake build environment
    19. 2010/12/20 arp arm cross build
    20. 2010/12/17 Embedded Linux nfs client mounting 문제
    21. 2010/12/17 mdev의 문제점.
    22. 2010/12/17 tmpfs 를 쓰자.
    23. 2010/12/14 Linux Kernel Porting @ 2.6.XX
    24. 2010/12/14 Linux Pipe, STDIN, STDOUT, STDERR
    25. 2010/12/09 DirectFB debug를 떠봅시다. (2)
    26. 2010/12/09 DirectFB 1.4.9 configure help capture
    27. 2010/12/08 glib arm cross build v2.26.1
    28. 2010/12/08 커널 부팅, kernel booting, nfs, rfs, uboot
    29. 2010/12/07 리눅스 커널 모듈 컴파일.
    30. 2010/12/07 Introduction to GCC Inline Asm By Robin Miyagi
    커널 부팅 초기 디버그
    2011/07/25 12:37


    linux, kernel, debug, boot, console, serial, uart





    커널 부팅 극초기의 상황을 시리얼로 찍고 싶다면?

    커널 컨피그에서
    커널 해킹 -> 커널 디버깅 -> 커널 로우 레벨 디버깅 펑션을 활성화

            adr     r0, my_string
            bl      printascii   ## 문자열 찍음
            b       __error      ## 스톱 시킴

    my_string : .asciz  "\nfucking kernel crash!!"
             .align

    ... 띄엄띄엄 추억속의 그녀를 회상하자니 이름도 생각이 나질 않아 검색해보니 아주 잘 정리한 글이 있습니다..

    http://bmfrog.tistory.com/entry/2628-% ··· 5b6%259c

    일타삼피님 감사합니다.


    dawnsea
    2011/07/25 12:37 2011/07/25 12:37
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2623

    우분투만의 독특한 커널 개발 환경
    2011/06/09 14:09


    ubuntu


    요즘은 커널 원본을 받아다 이런저런 실험을 하기가 어렵다.
    다들 데스크탑 리눅스를 쓰기 때문이다.
    뭐라도 하나 망가지면 시스템이 작살날 뿐더러..
    현 시스템의 커널 설정을 마이그레이션 하기도 어렵다.
    .config만 복사한다고 될 일이 아니로다.
    이게 커널인지 나비가 나인지..

    우분투의 경우 몇 가지 룰을 알고 있으면 커널 실험(개발)이 쉽다.

    각설하고..

    apt-get source linux-image-$(uname -r)


    이 작업은 현재 자신이 쓰고 있는 시스템과 같은 버전의 커널 소스를 우분투 레파짓에서 긁어온다.
    여기에 우분투 패치까지 알아서 다 해준다.

    이제 /usr/src/linux-2.6.38 디렉토리가 생기며 커널 소스가 깔렸다.


    apt-get install linux-headers-$(uname -r)

    커널 헤더를 받는다. 물론 커널 소스에도 있지만. 이것은 현 시스템의 커널 빌드가 반영된 헤더다.
    /usr/src/linux-headers-2.6.38-8 이 생겼다.
    거의 모든 파일이 심볼릭 링크로 연결되어 있을 것이다.

    이때 /lib/modules/2.6.38-generic 도 생긴다.
    이 디렉토리는 알다시피 모듈 버전등을 관리한다.

    이제 /lib/modules/2.6.38-generic/build 심볼릭 링크가 /usr/src/linux-headers-2.6.38-8 에 연결되어 있는지 확인한다.
    제대로 연결되어 있어야 한다.


    /lib/modules/2.6.38-generic/build 를 들어가보면 source라는 끊어진 심볼릭 링크가 보인다.


    /build/buildd 를 /usr/src/linux-2.6.38 에 심볼릭 링크로 연결한 후
    source를 /build/buildd 로 연결한다. 왜 이렇게 하는지는 모르겠다. 그냥 직빵 연결해도 되는 듯.
    우분투 기본 값이 그렇다.

    커널 풀빌드를 하려면 /boot/config ... 를 .config로 복사한다.
    모듈 빌드만 빠르게 하려면 make modules 해도 느린 편이므로...

    http://www.troot.co.kr/tc/2591


    ..를 참고한다. 정말로 필요한 모듈만 빌드 할 수 있다.









    dawnsea
    2011/06/09 14:09 2011/06/09 14:09
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2597

    glibc build 정리 중..
    2011/05/06 17:23



    일단 받자.
    가급적 LFS의 가르침을 따르자..


    1. 리눅스 커널 헤더 준비..

    귀찮으면 걍 복사... 심볼릭 링크가 정답임..

    /usr/src/linux-headers-2.6.38-8 에서
    ./include/linux 를 /usr/include 로 복사
    ./include/asm-generic 을 /usr/include로 복사
    ./arch/x87/include/asm 을 /usr/include로 복사



    2. glibc 받자
    http://ftp.gnu.org/pub/pub/gnu/glibc/


    3. 빈 디렉토리 2개 생성 (make 할 곳, 설치할 곳)

    4. 빈 디렉토리에서 glibc 압축 푼 곳 지정하여 configure
    예)/root/home/glibc-2.13/configure

    5. 에러나면 gawk 설치 apt-get install gawk

    6. make

    7. 에러나면 패치 / http://www.linuxfromscratch.org/patches/lfs/development/glibc-2.13-gcc_fix-1.patch
    .. 패치 파일 안에 2.11 에 맞춰져 있음.. 손으로 수정하던가.. 패치 파일 고쳐서 패치. patch -p0 < .. patch 등.




    8. make


    9. make check 중에 에러남..


    10. make install 이거 무서움.. 버츄얼 박스 깔고 다시 해 볼 것..




    dawnsea
    2011/05/06 17:23 2011/05/06 17:23
    tag : 리눅스, 임베디드
    댓글.2 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2586
    1. dawnsea 2011/05/06 17:58  X  O

      패치를 했던가 안 했던가..
      http://sourceware.org/bugzilla/attachm ··· n%3Dview

    2. dawnsea 2011/05/15 21:38  X  O

      SPECS=`dirname $(gcc -print-libgcc-file-name)`/specs gcc -dumpspecs | sed \ -e 's@/lib\(64\)\?/ld@/glibc&@g' \ -e "/^\*cpp:$/{n;s,$, -isystem /glibc/include,}" > $SPECS echo "New specs file is: $SPECS"
      gcc -specs=/specs -o a a.c
      ldd a
      readelf -l a

      마무리 완료

    gcc 4.6 build 하기.
    2011/05/06 11:43


    옛날엔 어떻게 했는지 기억도 안 나고..



    해야 할 일이 있어서 해봤다.
    크로스 빌드가 아니라 걍 하면 되는듯.

    하는 법 : 매뉴얼 보고 하면 된다. 끗.




    .
    .
    .

    매뉴얼 보기 귀찮은 사람은..

    1. 매뉴얼 / http://gcc.gnu.org/install/

    2. 4.6 다운로드 / http://ftp.gnu.org/pub/pub/gnu/gcc/
    ; 참고 / svn 으로 다운로드 받으면 천년 걸림... -_-;

    3. ./configure 하면 에러난다.

    4. ftp://gcc.gnu.org/pub/gcc/infrastructure/ 방문한다.

    5. gmp, 4.3.2 다운로드
    ./configure
    make
    make check
    make install

    6. mpfr 2.4.2 다운로드
    ./configure
    make
    make check
    make install

    7. mpc-0.8.1 다운로드
    ./configure
    make
    make check
    make install

    8. 에러나면 ldconfig 한 번 때려본다. /etc/ld.so.conf 에 자료만 추가되고 ldconfig 명령이 실행이 안 된 것 같다.

    9. gcc 디렉토리로 들어가서 다시 ./configure, make make install 한다.

    끗.

    참고 / 크로스 빌드는 케겔운동 부터 시작하자 / http://www.kegel.com/crosstool/



    linux from scratch
    http://www.linuxfromscratch.org/lfs/vi ··· dex.html


    glibc 의 모든 것
    http://www.gnu.org/s/hello/manual/libc/index.html#Top

    LFS w-get 하기
    http://www.linuxfromscratch.org/lfs/view/development/w붙여쓰자get-list
    dawnsea
    2011/05/06 11:43 2011/05/06 11:43
    tag : 리눅스, 임베디드, 컴퓨팅팁, 프로그래밍
    댓글. 1 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2584
    1. dawnsea 2011/05/11 13:59  X  O

      m4 에러나면 apt-get install m4

      m4 못 찾으면 미러를 daum으로 변경한다.

    SVN Store password unencrypted (yes/no)?
    2011/03/30 16:51


    svn 처음 깔고...
    콘솔에서 커밋하다가...

    Store password unencrypted (yes/no)?

    라고 나오는데 yes, no 아무 것도 안 먹으면...
    "대운하 반대"를 4번 외친 후...



    ~/.subversion/servers 를 열어서,
    # store-passwords = no 의 주석을 해제하면 된다..






    svn commit -m 메시지 안 하고 svn commit 시,
    자꾸 지랄맞은 nano 에디터가 뜬다면 다음과 같이 수정한다.

    vim ~/.bashrc 열어서

    SVN_EDITOR=/usr/bin/vim
    export SVN_EDITOR



    * * *


    인증이 없으면 체크아웃도 없다!

    conf/svnserver.conf 를 열어서

    anon-access = none  ... none 으로 변경!


    dawnsea
    2011/03/30 16:51 2011/03/30 16:51
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2567

    우분투에서 tortoise 처럼 svn 쓰기, nautilus 확장
    2011/03/30 13:33


    ubuntu, svn, tortoise.

    윈도우에 거북이가 있다면,
    리눅스에는 토끼가 있구나;;;;

    요즘은 머큐리얼이 대세라는데...
    일단 svn + trac 조합을 쓰니깐.. 대충 써봅시다.


    http://www.rabbitvcs.org/


    환장하게 편리함. rabbit svn 등의 툴과는 다른 우클릭 툴이다.
    우클릭으로 tortoise에서 하던 대부분의 작업을 할 수 있다.

    근데 막상 깔아놓고 보면... 습관적으로 터미널로 작업을 하고 있는 나의 모습;;
    마우스는 어깨가 아프죠.


    그러니까...


    노틸러스에 터미널 오픈을 붙여보자.

    apt-get install nautilus-open-terminal

    이제 노틸러스로 터미널 오픈을 할 수 있다;;
    그러나 나도 모르게 터미널로 작업을 하고 있는... 자동반사..

    ctrl+alt+t 키를 눌러보자. 터미널이 무릎과 무릎사이 팍팍팍...



    노틸러스 기능 확장들은 반드시 그놈을 재시작해야 동작한다.



    nautilus-image-converter 를 설치하면 노틸러스에 그림 파일 리사이즈도 할 수 있다.



    dawnsea
    2011/03/30 13:33 2011/03/30 13:33
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2564

    우분투만 설치해서 grub 메뉴가 안 나올 때.
    2011/03/25 18:10


    1.
    /etc/default/grub 을 편집한다.


    2.
    GRUB_HIDDEN_TIMEOUT=0 를 주석처리한다.



    3.
    update-grub 을 때리고 재부팅.


    dawnsea
    2011/03/25 18:10 2011/03/25 18:10
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2562

    fork, wait, exit
    2011/03/24 14:18
    root@dawnsea-Lenovo-G460:/home/dawnsea# ./process_sync_dawnsea
    Create Child, pid = 4795, seq_no = 0 // 자식 프로세스 10개를 생성한다.
    Create Child, pid = 4796, seq_no = 1 // 식별을 용이하게 하기 위해서
    Create Child, pid = 4797, seq_no = 2 // 자식 프로세스는 sleep(1)초 후 동작한다.
    Create Child, pid = 4798, seq_no = 3
    Create Child, pid = 4799, seq_no = 4
    Create Child, pid = 4800, seq_no = 5
    Create Child, pid = 4801, seq_no = 6
    Create Child, pid = 4802, seq_no = 7
    Create Child, pid = 4803, seq_no = 8
    Create Child, pid = 4804, seq_no = 9      // 여기까지 10개의 자식 프로세스가 생성됐다.
    Child End! seq_no = 0, pid = 4795, my_buffer = 106   // 자식 프로세스가 끝나기 시작했다.
    Child End! seq_no = 2, pid = 4797, my_buffer = 102
    Child End! seq_no = 1, pid = 4796, my_buffer = 101
    Found! (my_buffer > 105), pid = 4795, Parent end // 105 보다 큰 값을 갖는 자식 프로세스의
    // 종료를 탐지한 것이다.
    // wait의 리턴이 늦었음을 알 수 있다.
    // 여기서 부모 프로세스는 종료했다.

    Child End! seq_no = 3, pid = 4798, my_buffer = 103
    Child End! seq_no = 4, pid = 4799, my_buffer = 101
    Child End! seq_no = 5, pid = 4800, my_buffer = 102
    Child End! seq_no = 6, pid = 4801, my_buffer = 106
    Child End! seq_no = 7, pid = 4802, my_buffer = 106
    Child End! seq_no = 8, pid = 4803, my_buffer = 103
    Child End! seq_no = 9, pid = 4804, my_buffer = 106   // 자식 프로세스들이 차례로 종료했다.

    #include <stdio.h>
    #include <stdlib.h>
    #include <linux/unistd.h>
    #include <sys/syscall.h>

    main()
    {
            int i; // 자식 프로세스 10개를 생성하기 위한 인덱스
            int my_buffer; // 시스템 콜에서 값을 리턴 받기 위한 버퍼
            int child_status; // 자식 프로세스가 exit로 넘긴 status 값을 저장하는 용도
            pid_t px, end_pid; // 현재 생성한 pid와 종료한 자식 프로세스의 pid

            for (i = 0; i < 10; i++) { // 10개의 자식 프로세스를 만들자
                    px = fork(); // 프로세스 생성
                    if (px < 0) { // 프로세스 생성에 실패했다면?
                            printf("fork fail!\n"); // 에러 메시지 출력후
                            exit(1); // 종료
                    }

                    if (px == 0) { // 자식 프로세스 진입
                            srand(i * 1000 + time(NULL)); // 랜덤 값 초기화
                            my_buffer = syscall(SYS_dawnsea); // 시스템 콜 호출 및 값 얻기
                            sleep(1); // 메시지를 쉽게 보도록 시간차를
    // 두고 실행하기 위한 sleep
                        do {
                                    my_buffer += (rand() % 10) + 1; // 1~10의 랜덤 값을 계속 더함

                            } while (my_buffer <= 100); // 100보다 커야 탈출
                        // my_buffer가 100보다 크면 탈출하여 종료 메시지를 찍는다
                           printf("Child End! seq_no = %d, pid = %d, my_buffer = %d\n", i, getpid(), my_buffer);

        // 105보다 크면 부모 프로세스를 즉시 종료시키기 위해 exit(0)을 호출한다.
                            if (my_buffer > 105) exit(0); // 부모 프로세스가 0을 받는다.
                            else exit(1); // 부모 프로세스는 0이 아닌 값을 받는다.


                    } else {
        // 부모 프로세스 실행 영역이다. 현재 생성한 자식 프로세스 정보를 출력.
                            printf("Create Child, pid = %d, seq_no = %d\n", px, i);
                    }
            }

            do { // 자식 프로세스를 대기한다.
                    end_pid = wait(&child_status); // 자식 프로세스가 종료할 때마다 리턴한다.
                    if (child_status == 0) { // 종료한 자식 프로세스가 0을 보냈으면
                        // my_buffer에 105보다 큰 값이 들어있는 것이므로 즉시 종료한다.
                            printf("Found! (my_buffer > 105), pid = %d, Parent end \n\n", end_pid);
                            exit(0);
                    }
            } while (child_status != 0); // 105이하 값이면 계속 대기로 들어간다.
            printf("Not Found(my_buffer > 105\n"); // 105 초과 값을 한 개도 못 찾은 경우다.
    }
    dawnsea
    2011/03/24 14:18 2011/03/24 14:18
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2560

    우분투 커널 컴파일, 설치 완전 쉽네;;
    2011/03/21 01:27


    ubuntu, kernel, compile, build, install

    옛날 생각하고 모듈 꼬이면 개망하는데 걱정을 했으나..
    요즘은 아주 좋다 ㅠ.ㅠ


    1.
    커널 소스 위치는 변하지 않았다.

    /usr/src

    일단 이동..




    2.
    깔 것을 깔자.
    apt-get install fakeroot linux
    apt-get source linux-image-$(uname -r)

    3.
    잘 안 되면 필요한 것 계속 깔자. 시냅틱에서 kernel build 쯤으로 검색해서 마구 인스톨.
    ln -s linux-2.6.35 linux


    4.
    fakeroot make-kpkg --initrd --append-to-version=dawnseahw1 kernel-image kernel-headers -j 4


    5.
    dpkg -i linux-image-2.6.35.11dawnsea_2.6.35.11dawnsea-10.00.Custom_i386.deb



    6.
    리부팅! uname -a 로 대충 확인해서 바뀌었나 보자!



    dawnsea
    2011/03/21 01:27 2011/03/21 01:27
    tag : 리눅스, 임베디드, 컴퓨팅팁
    댓글. 1 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2557
    1. dawnsea 2011/03/24 14:00  X  O

      참고 /

      Dong Hoon Han - sudo apt-get -y install auto-apt;
      sudo auto-apt update && sudo auto-apt updatedb && sudo auto-apt update-local;

      ./configure 대신 아래 명령어 실행
      auto-apt run ./configure

    svn mirroring
    2011/01/25 13:15


    다음 글을 참고.
    http://dalgarak.egloos.com/3886922



    1. 미러링 할 저장소 생성

    svnadmin create /home/svn/new_repo


    2. 저장소 안의 스크립트 변경

    echo '#!/bin/sh' > ./hooks/pre-revprop-change
    chmod 777 ./hooks/pre-revprop-change







    3. 저장소 안의 패스워드 설정 등..



    ./conf/passwd 파일 열어서 계정/패스워드 설정
    ./conf/svnserve.conf 파일 열어서 대충 설정

    [general]
    anon-access = none
    auth-access = write
    password-db = passwd
    realm = dawnsea'repo






    4. 미러링 초기화

    svnsync init --source-username=sjc --source-password=sjc --sync-username=dawnsea --sync-password=dawnsea svn://168.219.185.16/nxc1000 svn://168.219.185.16/sg_msp

    라든가..

    svnsync init --source-username=dawnsea --source-password=dawnsea --sync-username=dawnsea --sync-password=dawnsea svn://168.219.185.16/nxc1000 http://168.219.187.24/nxc_svn









    5. 미러링 개시

    svnsync sync --source-username=sjc --source-password=sjc --sync-username=dawnsea --sync-password=dawnsea svn://168.219.185.16/nxc1000







    6. UUID 통일

    ./db/uuid



    이후에 crontab 에 작업을 추가하면 될 것 같다.




    svn, linux


    dawnsea
    2011/01/25 13:15 2011/01/25 13:15
    tag : 리눅스, 임베디드, 컴퓨팅팁
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2396

    이 죽일 놈의 .svn 디렉토리
    2011/01/14 15:03









    1.

    .svn 만 지우기

    아래 내용을 aaa.reg 로 만들고 병합하면 우클릭 삭제가 가능하다. (윈도우)





    Windows Registry Editor Version 5.00

    [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
    @="Delete SVN Folders"

    [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
    @="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""

    http://weblogs.asp.net/jgalloway/archive/2007/02/24/shell-command-remove-svn-folders.aspx









    linux 에서 지우기 -> 이거 까딱 실수하면 조지니까 주의해서 사용 ㅡ.ㅡ

    find . -name .svn -print0 | xargs -0 rm -rf










    2.

    .SVN만 빼고 diff 때리기

    diff --exclude=.svn LEFT RIGHT










    3.

    아파치에서 .svn 만 감추기
    http://aproxacs.springnote.com/pages/698888










    4.

    아.. .svn 과 관련한 뭔가 좋은 툴이 있었던 것 같은데 기억이 안 나네요;;


    dawnsea
    2011/01/14 15:03 2011/01/14 15:03
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2394

    printk 수다 레벨 조정
    2011/01/13 14:12


    printk 얼마나 시끄럽게 할 것인가 조절.


    일단 까보자.

    car /proc/sys/kernel/printk

    결과 -->
    7     4    1     7

    이게 뭣꼬?

    셧업 시켜보자

    echo 1 > /proc/sys/kernel/printk



    수다맨으로

    echo 8 > /proc/sys/kernel/printk



    ldd 3판에 잘 돼있네
    http://www.makelinux.net/ldd3/chp-4-sect-2.shtml




    디바이스 드라이버의 수다를 잠재우려면,
    DBGPRINT 등으로 printk를 래핑한 매크로함수를 찾은 후,
    거기서 쓴 KERN_ERR를 매핑시킨 매크로 상수를 찾은 후,
    그에 맞춰서 echo 숫자 > /proc/sys/kernel/printk 를 때리면 되겠다.





    printk verbose level
    dawnsea
    2011/01/13 14:12 2011/01/13 14:12
    tag : 리눅스, 임베디드
    댓글. 1 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2393
    1. dawnsea 2011/10/20 14:30  X  O

      cat /proc/kmsg

    build 시간 구하기, 시스템 수행 시간 구하기 @ linux
    2011/01/12 15:53




    빌드 할 때 걸리는 시간을 구해보자.
    정말 쉽다 -_-;



    time make uImage


    -> 커널 빌드한 시간을 구한다.



    real    5m57.939s
    user    5m28.045s
    sys    0m17.837s

    전체 6분이 걸렸고,
    내가 5분 30초를 썼고
    커널이 컨텍스트 스위칭 등등 지 할일 하느라 6분중 17초를 썼다는 뜻이다.











    build time, 빌드 시간
    dawnsea
    2011/01/12 15:53 2011/01/12 15:53
    tag : 리눅스, 임베디드
    댓글. 1 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2392
    1. dawnsea 2011/01/13 12:25  X  O

      make -j 4 -> 쿼드코어 고속 빌드

    Embedded Linux Wi-Fi
    2011/01/03 17:40


    Embedded Linux
    Wi-Fi, wi-fi, wifi, WiFi
    Ralink
    USB

    임베디드 리눅스에서 USB 무선랜 쓰기.



    요즘엔 참 쉽다;;
    정말 쉽다;


    이번에 조진 칩은 ralink다.
    홈페이지 가서 소스를 다운받자.


    http://www.ralinktech.com/support.php?s=2

    나는 RT8070/RT3070/RT3370 USB를 사용했다.



    PC에서 쓰고 싶다면... 커널 소스를 다운받아야 한다.

    apt-get install linux-source


    현재 내 PC의 커널 버전을 알고 싶다면 다음 명령어를 친다.

    uname -r

    /usr/src/ 에서 내 커널 소스를 찾는다. 압축풀고 하니까 대충..나온다.



    다시 ralink 드라이버의 압축을 푼다.

    Makefile을 연 후 ..
    아래와 같이 커널 소스 위치를 잘 지정한다.
    PC용으로 쓰고 싶으면 apt-get으로 다운받은 커널 소스 위치를 지정한다.
    우리는 나름 임베디드 시스템 엔지니어니까 각자 포팅한다고 삽질한 커널 소스 위치를 지정한다.



    물론 커널은 커널 소스에서 make menuconfig는 1회 시행해야 한다.
    에러나면 ncurse 등을 깐다. 그래도 모르겠으면 푸샵 30회 실시후 구글 뒤지셈.

    그래도 빌드하다 에러나면 에라 모르겠다. 커널 빌드 1회 실시!


    디바이스드라이버 소스 트리에서..
    os/linux/config.mk 를 오픈하여 각 기능을 설정한다. WPA 정도는 켜주고..
    CROSS_COMPILE은 건들지 않는다. 상위에서 상속 받는다.

    나중에 insmod 성공하면 config.mk 파일에서 -DDBG를 검색 후 지운다.
    초기는 디버그 모드라 메세지 장난 아님.

    디바이스드라이버 소스 루트에서 make 치면 rt3370sta.ko 파일이 나온다.
    insmod로 잘 올라가면 성공!!


    옛날에 썼던 자료 참고 : "임베디드 리눅스에서 USB 무선랜 쓰기"


    이거 뭐.. 세월 참 좋네요 걍 대충 치면 빌드 다 되네;



    추가) 중요한 것을 빼먹었습니다.

    /etc/Wireless/RT2870STA/RT2870STA.dat  를 복사해 넣어야 합니다.
    안 그러면 ifconfig ra0 up 이 안 됩니다.

    DBG 모드로 빌드하면 발 에러를 확인 할 수 있음



    dawnsea
    2011/01/03 17:40 2011/01/03 17:40
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2375

    wpa supplicant 없이 wi-fi 간이 설정
    2011/01/03 17:20


    와이파이, wifi, wi-fi
    리눅스, linux, wpa_supplicant



    간단함.

    wireless_tools를 다운로드 받아서 빌드

    Makefile 안의 CROSS 환경변수 등을 수정하면..
    바로 크로스컴파일이 된다.


    essid, password를 적당히 써주면 된다.

    ifconfig ra0 up
    ifconfig lo up

    등을 적당히 해주고..

    ./iwconfig ra0 essid ARCHON key restricted C3233A0178

    ..를 때리면 된다.

    ./iwconfig 실행하면 ESSID가 정상적으로 보여야 한다.



    dawnsea
    2011/01/03 17:20 2011/01/03 17:20
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2374

    kernel jiffies read
    2010/12/29 08:43


    옛날에 그냥 전역변수 값 읽어다 쓰고 그랬는데..
    사실 문제가 있는 방법이었다.


    다음 함수를 쓰는 것이 정확한 방법인갑다.


    리눅스 시스템 호출을 활용한 커널 명령


    jiffies_to_usecs() // us로 읽는다.
    jiffies_to_msecs() // ms 로 읽는다.
    get_jiffies_64 () // 그냥 틱 값을 읽는다.

    반대로 msec_to_jiffies, usec_to_jiffies도 쓰는 듯.

    일반적이라면 HZ 상수가 100 이므로 1틱은 10m이지만,
    요즘은 뭔가 정밀 타이머도 제공하는 것 같고..

    잘 모르겠다;





    dawnsea
    2010/12/29 08:43 2010/12/29 08:43
    tag : 리눅스, 임베디드
    댓글. 1 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2372
    1. dawnsea 2010/12/29 09:28  X  O

      ...라고는 하지만 아키텍쳐에 따라 함수 원형 까보면 걍 jiffies 리턴 -_-;

    linux ramdisk image making
    2010/12/23 16:44


    인터넷에 수없이 많은 자료 동어반복임




    1. 공파일 만들기.


    dd if=/dev/zero of=test_ramdisk.image bs=1 count=16M





    2. 공파일을 ext2 로 만들기

    mkfs.ext2 test_ramdisk.image





    3. 공파일을 마운트하기

    mkdir test_ramdisk

    mount -o loop test_ramdisk.image ./test_ramdisk




    4. 미리 구성했던 파일 복사하기

    copy -rdf 플래그 사용할 것.



    5. 압축하기


    끝


    dawnsea
    2010/12/23 16:44 2010/12/23 16:44
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2371

    qt, qmake build environment
    2010/12/21 12:11





    qt를 빌드한 다음, 설치한 경로를 보자


    qt/bin/qmake  -> 실행파일





    qt 소스트리에서

    /qt/bin/qmake -project

    -> 존재하는 모든 소스를 뒤져서 .pro 파일을 생성해준다.






    여기서 다시,

    /qt/bin/qmake -makefile

    -> Makefile 을 생성해준다. 즉 make 할 수 있다.







    qt/mkspecs/qws/linux-armv6-g++/qmake.conf
    -> 빌드 환경 설정.

    qmake.conf를 보면 make 설정이 있다.
    따라서 Makefile에 반영하고 싶다면,

    qmake.conf 를 바꾼 후 해당 디렉토리 안에서,
    /qt/bin/qmake -makefile을 수행한다.


    /qt/mkspecs/common/linux.conf를 수정할 수도 있다.


    QMAKE_INCDIR +=  변수는 -I 옵션을 쓰지 않아도 된다.
    따라서 pkg-config 를 쓰기는 좀 그렇다. 물론 동작은 할 것이다. -I-I 도 동작한다.


    pkg-config를 설치한 후,

    PKG_CONFIG_PATH=크로스빌드 pkgconfig 위차 pkg-config --libs liblog4cxx --cflags liblog4css를 수행해본다.
    qmake.conf 에 `` 역싱글쿼테이션으로 넣을 수도 있다.







    dawnsea
    2010/12/21 12:11 2010/12/21 12:11
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2367

    arp arm cross build
    2010/12/20 18:23


    apache portable runtime

    arm-linux.cache 파일을 다음과 같이 생성한다.

    ac_cv_file__dev_zero="yes"
    ac_cv_func_setpgrp_void="yes"
    apr_cv_process_shared_works="yes"
    apr_cv_mutex_robust_shared="no"
    apr_cv_tcp_nodelay_with_cork="yes"
    ac_cv_sizeof_struct_iovec="8"
    apr_cv_mutex_recursive="yes"


    CC=arm-linux-config ./configure --prefix=/home/qtlibs/oss --host=arm-linux --cache=arm-linux.cache

    정도로 configure 한 후 make 하면 땡임



    dawnsea
    2010/12/20 18:23 2010/12/20 18:23
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2366

    Embedded Linux nfs client mounting 문제
    2010/12/17 15:54



    nolock 이 중요함.

    rpc 간 교통정리를 빼고 그냥 대충 쓰자는 옵션인 듯.


    lock을 걸지 않는다.. 라는 것은..
    nfs로 마운팅할 위치를 여러 곳에서 마운트 할 경우..
    문제가 생길 소지가 있지 않을까?





    아래처럼 마운트!!



    mount -t nfs 192.168.123.100:/home/qtlibs /qtlibs -o rw,rsize=4096,wsize=4096,nolock


    호스트 쪽은 portmap이 깔려 있어야 마운트가 빠르다고.
    물론 portmap은 거의 기본임..



    dawnsea
    2010/12/17 15:54 2010/12/17 15:54
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2362

    mdev의 문제점.
    2010/12/17 15:16


    mdev는 busybox 기능이다.
    미니 udev로 보면 된다.


    임베디드 시스템에서,

    mdev -s 명령어를 수행하면,
    /dev 가 자동으로 구성된다. 부팅 때 마다 tmpfs에 자동 구성시키는 방법도 유효하지만,
    /dev가 ro인 경우 곤란하다.

    또한 mdev -s 명령어 자체가 약 1초 이상을 소모한다.
    부팅속도가 중요한 디바이스에서는 문제가 된다.

    따라서 init.d/rcS 스크립트에서 mdev -s를 빼고,
    /dev를 미리 구성해놓는 편이 좋은 경우도 많다.


    짱구 잘 굴려서 계획을 세우자.



    dawnsea
    2010/12/17 15:16 2010/12/17 15:16
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2361

    tmpfs 를 쓰자.
    2010/12/17 15:00



    mount tmpfs -t tmpfs /var/tmp


    mount 명령어 사용법이 다르므로 주의.


    http://www.ibm.com/developerworks/kr/library/l-fs3.html


    tmpfs는 램디스크와 달리 시스템 메모리를 알아서 쓴다.
    너무 많이 쓰면 메모리를 잠식하므로 골아프다.

    어쨌든 임베디드 시스템에서 rfs 구성할 때 트릭으로 쓰긴 좋다.

    또한 ro 영역인 파일시스템을 테스팅할 때 중복마운팅으로 우회시키기도 좋다.
    중복마운팅은 다음글을 참고 http://keeptalk.cafe24.com/tc/2023



    dawnsea
    2010/12/17 15:00 2010/12/17 15:00
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2360

    Linux Kernel Porting @ 2.6.XX
    2010/12/14 14:08


    요즘 커널은 arch/arm/ 자리에도
    어지간히 레이어링이 잘 돼있다.

    mach_XXXX와
    plat_XXXX를 잘 디비면..


    상수값만 바꿔서 플랫폼 설정이 가능한 곳이 많아졌다.


    예를들어 ..
    platform_device,
    platform_data

    구조체 초기값 설정부를 잘보면.. 여러가지 설정이 된다.

    dawnsea
    2010/12/14 14:08 2010/12/14 14:08
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2358

    Linux Pipe, STDIN, STDOUT, STDERR
    2010/12/14 13:59



    오늘의 상식.


    stdin, stdout, stderr은
    fd 번호가 일반적으로(?=잘 몰갔다)
    0, 1, 2다.


    read, write 쓸때 fd에 0, 1, 2 넣으면 그냥 그대로 나감.


    디버그 메시지 찍을 때 printf 대신 그렇게 쓰면 유용..

    fprintf(stderr, "dflksdjlfsdjfjsklfdjlj...
    같은 형식을 추천..


    명령어 > /dev/null 2>&1 방식으로 실행하면..
    stderr이 stdout으로 같이 나가게 되므로
    완전한 콘솔 사일런트 실행이 가능.. 조용조용하다..

    에러를 표준 출력으로 보내고, 표준 출력은 null 로 보내니까 조용해짐..

    &는 걍 붙여야 됨.. 파일명이 아니니까.


    참고자료 / http://www.xaprb.com/blog/2006/06/06/w ··· -mean%2F





    dawnsea
    2010/12/14 13:59 2010/12/14 13:59
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2357

    DirectFB debug를 떠봅시다.
    2010/12/09 15:26
    PKG_CONFIG_PATH=/home/keeptalk/NXP2120/work/dfb_build/lib/pkgconfig CC=arm-linux-gcc CFLAGS='-I/home/keeptalk/NXP2120/work/dfb_build/include' LIBS='-lm' LDFLAGS='-L/home/keeptalk/NXP2120/work/dfb_build/lib' ./configure --disable-x11 --with-inputdrivers=tslib,linuxinput --with-gfxdrivers=none --prefix=/home/keeptalk/NXP2120/work/dfb_build --host=arm-linux --build=i686-pc-linux-gnu --target=arm-linux --with-tests --enable-zlib --enable-jpeg --with-smooth-scaling --with-dither=simple --with-dither-rgb16=simple --enable-debug


    요래 빌드하시고..
    즉, -enable-debug 를 추가하고




    arm-linux-dfbinfo --dfb:debug  와 같이 실행하면
    메시지가 줄줄줄..





    dawnsea
    2010/12/09 15:26 2010/12/09 15:26
    tag : 리눅스, 임베디드
    댓글.2 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2352
    1. 개발자 2011/01/04 20:01  X  O

      안녕하세요
      최근에도 계속 DirectFB에 대해서 하시고 계시는군요

      다름이 아니라 저는 mips 코어에서 개발을 해보고 있는데요
      DirectFB를 이용하여 화면에 한글을 출력하고자 하였을 경우에 한글은 표시가 되지만

      "[아" 라는 것을 출력을 시도하여 보면은 한글이 깨져버립니다.
      이는 한글은 2바이트이고 '[' 이거는 1바이트인데 2바이트씩 출력을 해서 그런거라고
      판단을 하고 있습니다. 여기에 대해서 어떻게 처리하셨는지

      혹시 메일을 알 수 있을까요? 가끔씩 물어보고 싶어서요~ 부탁드리겠습니다.

      • └ dawnsea 2011/01/04 22:21  X

        안녕하세요?

        잘 기억은 안 나지만 iconv도 깔아야하고 locale도 설정해야 하는 것으로 알고 있습니다.

    DirectFB 1.4.9 configure help capture
    2010/12/09 13:05








    매번 좁은 터미널에서 스크롤하면서 보는 것도 귀찮타.
    리눅스에서 듀얼모니터 사용 기념..











    configure는 대충 이래 하니까 에러 없다.


    PKG_CONFIG_PATH=/home/keeptalk/NXP2120/work/dfb_build/lib/pkgconfig CC=arm-linux-gcc CFLAGS='-I/home/keeptalk/NXP2120/work/dfb_build/include' LIBS='-lm' LDFLAGS='-L/home/keeptalk/NXP2120/work/dfb_build/lib' ./configure --disable-x11 --with-inputdrivers=tslib,linuxinput --with-gfxdrivers=none --prefix=/home/keeptalk/NXP2120/work/dfb_build --host=arm-linux --build=i686-pc-linux-gnu --target=arm-linux --with-tests --enable-zlib --enable-jpeg --with-smooth-scaling --with-dither=simple --with-dither-rgb16=simple



    결과는..






    dawnsea
    2010/12/09 13:05 2010/12/09 13:05
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2350

    glib arm cross build v2.26.1
    2010/12/08 18:24



    glib build 100번쯤 하면 당신도 빌드의 귀재




    먼저 PC 쪽에 libglib2.0-dev 를 깐다.
    glib-genmarshal 에러를 확인하고 깔아도 된다.

    zlib 등 부가 라이브러리는 이미 됐다고 가정.
    pkg-config도 깔려있고 PKG_CONFIG_PATH도 정상 설정 돼 있어야 함.

    PC 쪽에 gettext도 깐다.

    glib 디렉토리로 들어가서.
    다음 파일을 생성한다.

    arm-linux.cache 파일을 만들고.. 아래처럼 씀.

    glib_cv_long_long_format=ll
    glib_cv_stack_grows=no
    glib_cv_has__inline=yes
    glib_cv_has__inline__=yes
    glib_cv_uscore=no
    ac_cv_func_posix_getpwuid_r=yes
    ac_cv_func_posix_getgrgid_r=yes
    glib_cv_use_pid_surrogate=yes


    ./configure 실행

    PKG_CONFIG_PATH=/home/keeptalk/NXP2120/work/dfb_build/lib/pkgconfig CC=arm-linux-gcc CFLAGS='-I/home/keeptalk/NXP2120/work/dfb_build/include -L/home/keeptalk/NXP2120/work/dfb_build/lib' ./configure --prefix=/home/keeptalk/NXP2120/work/dfb_build --host=arm-linux --build=i686-pc-linux-gnu --target=arm-linux --with-libiconv=gnu --cache-file=arm-linux.cache



    make, make install 실행.



    dawnsea
    2010/12/08 18:24 2010/12/08 18:24
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2349

    커널 부팅, kernel booting, nfs, rfs, uboot
    2010/12/08 15:39



    요즘은 다 uImage 쓰는구나;;

    여튼..


    N**** 칩의 uboot 환경변수는 다음과 같다.
    칩이름은 일단 비공개..


    메모리맵이고 뭐고 모르니까 떠놓고..



    baudrate=115200
    ethaddr=12:24:45:4a:59:24:56
    bootfile="uImage"
    ethact=dm9000
    filesize=201C44
    fileaddr=81000000
    netmask=255.255.255.0
    bootcmd=nand read 81000000 400000 202000;nand read 82000000 800000 820000;bootm
    81000000
    bootdelay=3
    ipaddr=192.168.123.101
    gatewayip=192.168.123.100
    serverip=192.168.123.100
    stdin=serial
    stdout=serial
    stderr=serial

    Environment size: 349/16380 bytes




    nfs 부팅 시 다음과 같이 하고..


    CONFIG_CMDLINE="console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=192.168.123.100:/mnt/nfs
    ip=192.168.123.101:192.168.123.100:192.168.123.100:255.255.255.0::eth0:off cachepolicy=writeback"


    nfs 부팅 때는 이더넷이 먼저 활성화 되야 하니까 잊지 말것.


    dawnsea
    2010/12/08 15:39 2010/12/08 15:39
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2347

    리눅스 커널 모듈 컴파일.
    2010/12/07 22:57


    .c 하나 떨렁 만들고 언능 빌드하고 싶을때 ㅠ.ㅠ

    gcc -D__KERNEL__ -D_LINUX -DMODULE -c -O2 test.c




    조.. 좋은 추억이다..



    dawnsea
    2010/12/07 22:57 2010/12/07 22:57
    tag : 리눅스, 임베디드
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2345

    Introduction to GCC Inline Asm By Robin Miyagi
    2010/12/07 22:46









    옛 블로그 보관자료.


    원 출처 링크는 지오씨티라서...
    오래전에 개발살..





    추억 속의 지오씨티여..







    ------------------------------------------------------------------------
    		     Introduction to GCC Inline Asm
    
    			    By Robin Miyagi
    			    
    	    http://www.geocities.com/SiliconValley/Ridge/2544/ 
    	   
    			Wed Sep 13 19:18:50 UTC
    ------------------------------------------------------------------------
    
    * `as' and AT&T Syntax
    ------------------------------------------------------------------------
    
        The  GNU C  Compiler uses  the assembler  `as' as  a  backend.  This
        assembler uses AT&T syntax.  Here is a brief overview of the syntax.
        For  more   information  about  `as',   look  in  the   system  info
        documentation.
        
        - as uses the form;
        
            nemonic source, destination (opposite to intel syntax)
        
        - as  prefixes registers  with `%',  and prefixes  numeric constants
          with `$'.
        
        - Effective addresses use the following general syntax;
        
            SECTION:DISP(BASE, INDEX, SCALE)
        
          As in other assemblers, any one or more of these components may be
          ommited,  within constraints  of valid  intel  instruction syntax.
          The above syntax was shamelessly  copied from the info pages under
          the i386 dependant features of as.
        
        - As suffixes  the assembler nemonics  with a letter  indicating the
          operand sizes  ('b' for  byte, 'w' for  word, 'l' for  long word).
          Read  the info  pages for  more information  such as  suffixes for
          floating point registers etc.
        
        Example code (raw asm, not gcc inline)
        --------------------------------------------------------------------
        movl %eax, %ebx     /* intel: mov ebx, eax */                       
        movl $56, %esi      /* intel: mov esi, 56 */                        
        movl %ecx, $label(%edx,%ebx,$4) /* intel: mov [edx+ebx*4+4], ecx */ 
        movb %ah, (%ebx)    /* intel: mov [ebx], ah */                      
        --------------------------------------------------------------------
        
        Notice that  as uses  C comment  syntax.  As can  also use  `#' that
        works the same way as `;' in most other intel assemblers.
        
        Above code in inline asm
        --------------------------------------------------------------------
          __asm__ ("movl %eax, %ebx\n\t"
    	       "movl $56, %esi\n\t"
    	       "movl %ecx, $label(%edx,%ebx,$4)\n\t"
    	       "movb %ah, (%ebx)");
        --------------------------------------------------------------------
        
        Notice that in the above example, the __ prefixing and suffixing asm
        are not neccesary,  but may prevent name conflicts  in your program.
        You can read  more about this in [C  enxtensions|extended asm] under
        the info documentation  for gcc.
        
        Also notice the '\n\t' at the  end of each line except the last, and
        that each  line is  inclosed in quotes.   This is because  gcc sends
        each as instruction to as  as a string.  The newline/tab combination
        is required so that the lines are fed to as according to the correct
        format  (recall that  each line  in asssembler  is indented  one tab
        stop, generally 8 characters).
        
        You can also use labels from  your C code (variable names and such).
        In  Linux, underscores prefixing  C variables  are not  Necessary in
        your code; e.g.
        
           int main (void) {
        	   int Cvariable;	
        	   __asm__ ("movl Cvariable, %eax"); # Cvariable contents > eax
    	   __asm__ ("movl $Cvariable, %ebx"); # ebx ---> Cvariable
           }
        
         Notice that  in the documentation for  DJGPP, it will  say that the
         underscore is  necessary.  The difference is do  to the differences
         between  djgpp RDOFF  format  and  Linux's ELF  format.   I am  not
         certain, but I think that the old Linux a.out object files also use
         underscores (please contact me if you have comments on this).
    
    * Extended Asm
    ------------------------------------------------------------------------
    
        The code  in the  above example will  most probably  cause conflicts
        with the rest of your C code, especially with compiler optimizations
        (recall that gcc is an  optimizing compiler).  Any registers used in
        your code may be used to hold  C variable data from the rest of your
        program.  You  would not want  to inadvertently modify  the register
        without telling gcc to take  this into account when compiling.  This
        is where extended asm comes into play.
    
        Extended  asm   allows  you  to  specify   input  registers,  output
        registers, and clobbered registers  as interface information to your
        block of asm code.  You can even allow gcc to choose actual physical
        CPU   registers  automatically,   that  probably   fit   into  gcc's
        optimization  scheme better.  An  example will  demonstrate extended
        asm better.
    
        Example code
        --------------------------------------------------------------------
         #include < stdlib.h >
        
        int main (void) {
          int operand1, operand2, sum, accumulator;
        
          operand1 = rand (); operand2 = rand ();
          
          __asm__ ("movl %1, %0\n\t"
          	       "addl %2, %0"
    	       : "=r" (sum)			/* output operands */
    	       : "r" (operand1), "r" (operand2) /* input operands */
    	       : "0");				/* clobbered operands */
          
          accumulator = sum;
          
          __asm__ ("addl %1, %0\n\t"
    	       "addl %2, %0"
    	       : "=r" (accumulator)
    	       : "0" (accumulator), "g" (operand1), "r" (operand2)
    	       : "0");
          return accumulator;
        }
         --------------------------------------------------------------------
    
        The  first  the line  that  begins  with  ':' specifies  the  output
        operands,  the second  indicates the  input operands,  and  the last
        indicates  the  clobbered  operands.   the  "r", "g",  and  "0"  are
        examples of  constraints.  Output constraints must  be prefixed with
        an '=',  as in  "=r" (= is  a constraint modifier,  indicating write
        only).  Input  and output constraints  must have its  correspoding C
        argument included with it enclosed  in parenthisis (this must not be
        done with  the clobbered line, I  figured this out after  an hour of
        fustration).  "r"  means assign a general register  register for the
        argument,  "g" means  to assign  any register,  memory  or immediate
        integer for this.
    
        Notice the use of "0", "1",  "2" etc.  These are used to ensure that
        when the  same variable is indicated  in more than one  place in the
        extended asm, that is variable is only `mapped' to one register.  If
        you had merely used another "r" for example, the compiler may or may
        not assign  this variable to the  same register as  before.  You can
        surmise from this that "0"  refers to the first register assigned to
        a variable,  "1" the second etc.   When these registers  are used in
        the asm code, they are refered to as "%0", "%1" etc.
    
        Summary of  constraints. (copied from the  system info documentation
        for gcc)
        --------------------------------------------------------------------
        `m'
    
            A memory operand  is allowed, with any kind  of address that the
        	machine supports in general.
        
        `o'
    
            A  memory  operand  is  allowed,  but only  if  the  address  is
    	"offsettable".    This  means  that   adding  a   small  integer
    	(actually, the width  in bytes of the operand,  as determined by
    	its machine mode) may be added  to the address and the result is
    	also a valid memory address.
        
    	For example, an address which  is constant is offsettable; so is
    	an address that is the sum of a register and a constant (as long
    	as  a slightly  larger  constant  is also  within  the range  of
    	address-offsets supported by  the machine); but an autoincrement
    	or autodecrement  address is not  offsettable.  More complicated
    	indirect/indexed  addresses  may   or  may  not  be  offsettable
    	depending  on  the  other  addressing  modes  that  the  machine
    	supports.
        
    	Note that in  an output operand which can  be matched by another
    	operand,  the   constraint  letter   `o'  is  valid   only  when
    	accompanied by both `<'  (if the target machine has predecrement
    	addressing)  and `>'  (if  the target  machine has  preincrement
    	addressing).
        
        `V'
    
            A  memory operand  that  is not  offsettable.   In other  words,
    	anything  that would  fit the  `m'  constraint but  not the  `o'
    	constraint.
        
        `<'
    
            A   memory  operand   with   autodecrement  addressing   (either
    	predecrement or postdecrement) is allowed.
        
        `>'
    
            A   memory  operand   with   autoincrement  addressing   (either
    	preincrement or postincrement) is allowed.
        
        `r'
    
            A register operand  is allowed provided that it  is in a general
    	register.
        
        `d', `a', `f', ...
        
    	Other  letters can  be defined  in machine-dependent  fashion to
    	stand for particular classes of registers.  `d', `a' and `f' are
    	defined  on  the 68000/68020  to  stand  for  data, address  and
    	floating point registers.
        
        `i'
        
    	An  immediate  integer  operand  (one with  constant  value)  is
    	allowed.  This includes symbolic  constants whose values will be
    	known only at assembly time.
        
        `n'
        
    	An  immediate integer  operand  with a  known  numeric value  is
    	allowed.   Many systems  cannot support  assembly-time constants
    	for  operands less  than  a word  wide.   Constraints for  these
    	operands should use `n' rather than `i'.
        
        `I', `J', `K', ... `P'
        
    	Other letters in  the range `I' through `P' may  be defined in a
    	machine-dependent fashion  to permit immediate  integer operands
    	with explicit integer values  in specified ranges.  For example,
    	on the 68000, `I' is defined  to stand for the range of values 1
    	to 8.  This is the range permitted as a shift count in the shift
    	instructions.
        
        `E'
    
            An immediate  floating operand (expression  code `const_double')
    	is allowed, but only if  the target floating point format is the
    	same  as that  of the  host machine  (on which  the  compiler is
    	running).
        
        `F'
        
    	An immediate  floating operand (expression  code `const_double')
    	is allowed.
        
        `G', `H'
        
    	`G' and  `H' may  be defined in  a machine-dependent  fashion to
    	permit  immediate  floating  operands  in particular  ranges  of
    	values.
        
        `s'
        
    	An  immediate integer  operand whose  value is  not  an explicit
    	integer is allowed.
        	
    	This might appear strange; if  an insn allows a constant operand
    	with a value not known  at compile time, it certainly must allow
    	any known value.   So why use `s' instead  of `i'?  Sometimes it
    	allows better code to be generated.
        	
    	For  example, on  the  68000  in a  fullword  instruction it  is
    	possible to use an immediate operand; but if the immediate value
    	is between  -128 and 127,  better code results from  loading the
    	value into a  register and using the register.   This is because
    	the  load  into  the  register   can  be  done  with  a  `moveq'
    	instruction.   We arrange  for this  to happen  by  defining the
    	letter `K' to mean "any  integer outside the range -128 to 127",
    	and then specifying `Ks' in the operand constraints.
        
        `g'
        
    	Any register,  memory or  immediate integer operand  is allowed,
    	except for registers that are not general registers.
        	
        `X'
        
    	Any operand whatsoever  is allowed, even if it  does not satisfy
    	`general_operand'.  This is normally used in the constraint of a
    	`match_scratch'  when  certain  alternatives will  not  actually
    	require a scratch register.
        
        `0', `1', `2', ... `9'
        
    	An operand that matches the specified operand number is allowed.
    	If  a  digit is  used  together  with  letters within  the  same
    	alternative, the digit should come last.
        	
    	This is called a "matching  constraint" and what it really means
    	is that the  assembler has only a single  operand that fills two
    	roles considered separate in the  RTL insn.  For example, an add
    	insn has two  input operands and one output  operand in the RTL,
    	but on most CISC machines an add instruction really has only two
    	operands, one of them an input-output operand:
        	
    	     addl #35,r12
        	
    	Matching  constraints  are used  in  these circumstances.   More
    	precisely,  the  two  operands   that  match  must  include  one
    	input-only operand  and one output-only  operand.  Moreover, the
    	digit must  be a smaller number  than the number  of the operand
    	that uses it in the constraint.
        	
    	For operands  to match in  a particular case usually  means that
    	they  are  identical-looking  RTL  expressions.  But  in  a  few
    	special cases specific kinds  of dissimilarity are allowed.  For
    	example, `*x' as an input operand will match `*x++' as an output
    	operand.  For proper results  in such cases, the output template
    	should always use the  output-operand's number when printing the
    	operand.
        
        `p'
        
    	An operand that  is a valid memory address  is allowed.  This is
    	for "load address" and "push address" instructions.
        	
    	`p' in  the constraint must be  accompanied by `address_operand'
    	as  the  predicate   in  the  `match_operand'.   This  predicate
    	interprets the mode specified in the `match_operand' as the mode
    	of the memory reference for which the address would be valid.
        
        `Q', `R', `S', ... `U'
        
    	Letters  in  the range  `Q'  through `U'  may  be  defined in  a
    	machine-dependent fashion to  stand for arbitrary operand types.
    	The machine  description macro `EXTRA_CONSTRAINT'  is passed the
    	operand as its  first argument and the constraint  letter as its
    	second operand.
        	
    	A typical use for this  would be to distinguish certain types of
    	memory references that affect other insn operands.
        	
    	Do  not  define  these  constraint letters  to  accept  register
    	references  (`reg'); the reload  pass does  not expect  this and
    	would not handle it properly.
        
            In order to have valid assembler code, each operand must satisfy
    	its constraint.   But a  failure to do  so does not  prevent the
    	pattern  from applying  to  an insn.   Instead,  it directs  the
    	compiler  to modify  the code  so  that the  constraint will  be
    	satisfied.  Usually  this is done  by copying an operand  into a
    	register.
        
            Contrast, therefore, the two instruction patterns that follow:
        
    	 (define_insn ""
    	   [(set (match_operand:SI 0 "general_operand" "=r")
    		 (plus:SI (match_dup 0)
    			  (match_operand:SI 1 "general_operand" "r")))]
    	   ""
    	   "...")
        
    	which has two operands, one  of which must appear in two places,
    	and
        
    	 (define_insn ""
    	   [(set (match_operand:SI 0 "general_operand" "=r")
    		 (plus:SI (match_operand:SI 1 "general_operand" "0")
    			  (match_operand:SI 2 "general_operand" "r")))]
    	   ""
    	   "...")
        
    	which  has  three operands,  two  of  which  are required  by  a
    	constraint to  be identical.  If  we are considering an  insn of
    	the form
        
    	 (insn N PREV NEXT
    	   (set (reg:SI 3)
    		(plus:SI (reg:SI 6) (reg:SI 109)))
    	   ...)
        
    	the first pattern would not apply at all, because this insn does
    	not  contain two  identical subexpressions  in the  right place.
    	The  pattern  would  say,  "That  does  not  look  like  an  add
    	instruction; try other patterns."  The second pattern would say,
    	"Yes, that's  an add instruction,  but there is  something wrong
    	with it."   It would direct the  reload pass of  the compiler to
    	generate  additional insns  to  make the  constraint true.   The
    	results might look like this:
        
    	 (insn N2 PREV N
    	   (set (reg:SI 3) (reg:SI 6))
    	   ...)
    	 
    	 (insn N N2 NEXT
    	   (set (reg:SI 3)
    		(plus:SI (reg:SI 3) (reg:SI 109)))
    	   ...)
        
    	It is up to you to make sure that each operand, in each pattern,
    	has constraints that can handle any RTL expression that could be
    	present for  that operand.   (When multiple alternatives  are in
    	use, each pattern must, for each possible combination of operand
    	expressions, have at least one alternative which can handle that
    	combination of operands.)  The constraints don't need to *allow*
    	any  possible  operand--when  this  is  the case,  they  do  not
    	constrain--but they must at least point the way to reloading any
    	possible operand so that it will fit.
        
            * If  the  constraint accepts  whatever  operands the  predicate
    	  permits, there is no problem: reloading is never necessary for
    	  this operand.
        
    	  For  example, an operand  whose constraints  permit everything
    	  except  registers  is  safe  provided  its  predicate  rejects
    	  registers.
        
    	  An  operand whose  predicate accepts  only constant  values is
    	  safe provided its constraints  include the letter `i'.  If any
    	  possible constant  value is  accepted, then nothing  less than
    	  `i'  will do;  if the  predicate is  more selective,  then the
    	  constraints may also be more selective.
        
            * Any operand  expression can be  reloaded by copying it  into a
    	  register.  So  if an operand's constraints allow  some kind of
    	  register, it  is certain to be  safe.  It need  not permit all
    	  classes  of  registers;  the  compiler  knows how  to  copy  a
    	  register into another register of the proper class in order to
    	  make an instruction valid.
        
           	* A nonoffsettable  memory reference can be  reloaded by copying
     	  the address  into a register.   So if the constraint  uses the
     	  letter `o', all memory references are taken care of.
         
           	* A  constant operand  can be  reloaded by  allocating  space in
     	  memory  to hold it  as preinitialized  data.  Then  the memory
     	  reference can  be used  in place of  the constant.  So  if the
     	  constraint uses the letters  `o' or `m', constant operands are
     	  not a problem.
         
           	* If  the constraint permits  a constant  and a  pseudo register
     	  used in  an insn was not  allocated to a hard  register and is
     	  equivalent to  a constant, the register will  be replaced with
     	  the constant.  If the predicate does not permit a constant and
     	  the insn  is re-recognized for some reason,  the compiler will
     	  crash.  Thus  the predicate must always  recognize any objects
     	  allowed by the constraint.
        
    	If  the operand's  predicate  can recognize  registers, but  the
    	constraint does not permit them, it can make the compiler crash.
    	When this operand happens to be a register, the reload pass will
    	be  stymied, because it  does not  know how  to copy  a register
    	temporarily into memory.
        
    	If  the  predicate  accepts  a unary  operator,  the  constraint
    	applies to the operand.  For  example, the MIPS processor at ISA
    	level  3 supports  an instruction  which adds  two  registers in
    	`SImode' to produce a `DImode' result, but only if the registers
    	are  correctly  sign extended.   This  predicate  for the  input
    	operands accepts a `sign_extend' of an `SImode' register.  Write
    	the constraint to indicate the type of register that is required
    	for the operand of the `sign_extend'.
        ------------------------------------------------------------------------
    
        The '='  in the  "=r" is  a constraint modifier,  you can  find more
        information  about  constraint  modifiers,  in the  gcc  info  under
        Machine Descriptions : Constraints : Modifiers.
    
        I strongly recommend reading  more in the system info documentation.
        If  you haven't  had  much  experience with  the  info reader  (also
        accesable through  emacs), learn  it, it is  an excellent  source of
        information.
    
        The gcc info  documentation also explains how to  use a specific CPU
        register for  a constraint for various hardware  including the i386.
        You  can  find  this  information   under  [gcc  :  Machine  Desc  :
        Constraints : Machine Constraints] in the info documentation.
    
        You can specify specific registers in your constraints, e.g. "%eax".
    
    * __asm__ __volatile__
    ------------------------------------------------------------------------
    
        Because of  the compilers optimization mechanism, your  code may not
        appear at  exactly in the  location specified by the  programmer.  I
        may  even be interspersed  with the  rest of  the code.   To prevent
        this, you can  use __asm__ __volotile__ instead.  Like  the '__' for
        asm, these  are also not needed  for volatile, but  can prevent name
        conflicts.
    
    ========================================================================
    comments and suggestions 
    





     

    dawnsea
    2010/12/07 22:46 2010/12/07 22:46
    tag : 임베디드, 프로그래밍
    댓글 / 엮인글 / HanRSS 구독
    엮인글 주소 :: http://keeptalk.cafe24.com/tc/trackback/2343

    다음
    이전

    1 2 3 4 5 ... 7
    dawnsea’s Blog is powered by Textcube 1.8.5 : Accelerando / Designed by dawnsea / rss feed / A1503559.T407.Y764