Raspberry Pi 3에서 BareMetal 해봤다 ~ 개발 환경 구축과 아무것도하지 않는 무한 루프 프로그램 작성 ~

12838 단어 Raspberrypi3Baremetal

소개



Raspberry Pi 3에서 BareMetal 해 보았으므로 정보를 정리해 둔다.
우선 개발 환경 구축과 최소한의 아무것도 하지 않는 무한 루프 프로그램 작성까지.

자신의 PC 환경은 다음과 같습니다.
  • 우분투 18.04.1 LTS

  • 준비하는 것


  • bootcode.bin (부트 로더)
  • start.elf (펌웨어)
  • config.txt (구성 파일)
  • kernel8.img (프로그램 본체)

  • "bootcode.bin"과 "start.elf"는 아래에서 다운로드합니다.
    raspberrypi/firmware/boot

    다음 두 파일의 페이지로 들어가서



    「Download」버튼을 누르면 파일 단독으로 다운로드할 수 있습니다.



    이러한 파일을 FAT32 포맷 SD 카드에 넣고 Raspberry Pi 3에 전원을 켜면 프로그램이 실행됩니다.

    설정 파일



    ARM 코어를 64bit 모드로 기동시키는 설정을 써 둡니다.

    config.txt
    # ARMコアをAArch64で起動させる
    arm_control=0x200
    

    프로그램 본체는 디폴트에서는 「kernel8.img」가 실행됩니다만, 이것을 바꾸고 싶은 경우는 이하와 같이 합니다.

    config.txt
    # 動作させたいプログラム本体の名前を指定
    kernel=Foo.img
    
    # ARMコアをAArch64で起動させる
    arm_control=0x200
    

    컴파일러



    다음 명령으로 도구 체인을 설치합니다.
    sudo apt install g++-aarch64-linux-gnu
    

    설치되었는지 확인
    aarch64-linux-gnu-gcc -v
    

    자신의 환경에서는 다음과 같은 결과가 되었습니다.
    gcc version 7.3.0 (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04)
    

    프로그램 작성



    다음 파일을 작성합니다.
  • Makefile
  • linker.ld
  • boot.S
  • main.c

  • Makefile



    적당히 다음과 같은 느낌으로 Makefile을 작성해 둡니다.

    make를 설치하지 않은 경우 다음 명령으로 설치하십시오.
    sudo apt install make
    

    Makefile
    TARGET     = kernel8
    TARGET_ELF = kernel8.elf
    TARGET_IMG = kernel8.img
    
    PREFIX  = aarch64-linux-gnu-
    GCC     = $(PREFIX)gcc
    LD      = $(PREFIX)ld
    OBJCOPY = $(PREFIX)objcopy
    
    SRCS = $(wildcard *.c)
    OBJS = $(SRCS:.c=.o)
    CFLAGS  = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
    LDFLAGS = -nostdlib -nostartfiles
    
    %.o: %.S
        $(GCC) $(CFLAGS) -c $< -o $@
    
    %.o: %.c
        $(GCC) $(CFLAGS) -c $< -o $@
    
    $(TARGET_IMG): boot.o $(OBJS)
        $(LD) $(LDFLAGS) boot.o $(OBJS) -T linker.ld -o $(TARGET_ELF)
        $(OBJCOPY) -O binary $(TARGET_ELF) $(TARGET_IMG)
    
    clean:
        rm $(TARGET_ELF) $(TARGET_IMG) *.o
    

    링커 스크립트



    링커 스크립트는 데이터를 실행 파일에 배치하고 생성하는 방법을 정의하는 파일입니다.
    자세한 것은 이하등을 참조.
  • 첫 C 언어 - 제9회 링커 스크립트
  • 0부터 만드는 OS 개발 커널 시작

  • linker.ld
    SECTIONS
    {
        . = 0x80000;
    
        /* .text : プログラムコードが入る領域 */
        .text : {
            KEEP(*(.text.boot))
            *(.text .text.* .gnu.linkonce.t*)
        }
    
        /* .rodata : 変更されない文字列とか定数などが入る領域 */
        .rodata : {
            *(.rodata .rodata.* .gnu.linkonce.r*)
        }
    
        PROVIDE(_data = .);
    
        /* .data : 初期値を持った変数などを置く領域 */
        .data : {
            *(.data .data.* .gnu.linkonce.d*)
        }
    
        /* .bss : 初期値を持たない変数などを置く領域 */
        .bss (NOLOAD) : {
            . = ALIGN(16);
            __bss_start = .;
            *(.bss .bss.*)
            *(COMMON)
            __bss_end = .;
        }
    
        _end = .;
    
        /* 入力セクション破棄 */
        /DISCARD/ : {
            *(.comment)
            *(.gnu*)
            *(.note*)
            *(.eh_frame*)
        }
    }
    
    /* .bssのサイズ */
    __bss_size = (__bss_end - __bss_start) >> 3;
    

    부팅 처리



    C 언어의 메인 함수에 갈 때까지의 처리를 어셈블리 언어로 써 갑니다.

    boot.S
        .section ".text.boot"
    
        .global _start
    
    _start:
        // CPU IDの読み取り、スレーブコアの停止
        mrs x1, mpidr_el1
        and x1, x1, #3
        cbz x1, 2f
    1:
        // CPU ID > 0, STOP
        wfe
        b   1b
    2:
        // CPU ID == 0
    
        // コードの前にスタックを設定する
        ldr x1, =_start
        mov sp, x1
    
        // Clear bss
        ldr x1, =__bss_start
        ldr w2, =__bss_size
    3:
        cbz w2, 4f
        str xzr, [x1], #8
        sub w2, w2, #1
        cbnz w2, 3b
    4:
        // C言語プログラムのメイン関数にジャンプ
        bl  main
        // フェイルセーフの場合は、このコアも停止
        b   1b
    

    프로그램 본체



    여기까지 오면 후에는 C언어로 짹짹 쓰는 것뿐입니다.
    우선, 아무것도 하지 않는 무한 루프 프로그램을 써 둔다.

    main.c
    void main(){
        while(1){
        }
    }
    

    마지막으로



    어렵지만 매우 재미 있습니다.
    Raspberry Pi 3의 BareMetal은 VideoCore와 CPU 간의 통신을 실시하는 「Mailbox」라고 하는 구조를 사용할 수 있게 되고 나서가 프로덕션이므로 현재는 이것을 잘 다룰 수 있도록 공부중입니다.
    어느 정도 이해할 수 있으면 기사로 정리하고 싶습니다 ...

    이 기사의 소스 코드는 Github에 넣어 있기 때문에, 좋으면 부디 ~
    RaspberryPiBareMetal

    좋은 웹페이지 즐겨찾기