임베디드 응용 프로그램 개발을 위해 Raspberry Pi를 순수한 임베디드 CPU 단위로 사용하고 싶습니다. 라즈베리 파이는 메모리가 많은 강력한 CPU를 가지고 있기 때문에 훌륭한 임베디드 보드를 만듭니다.
Linux OS없이 Raspberry Pi를 사용할 수 있습니까? 어떻게해야합니까?
임베디드 응용 프로그램 개발을 위해 Raspberry Pi를 순수한 임베디드 CPU 단위로 사용하고 싶습니다. 라즈베리 파이는 메모리가 많은 강력한 CPU를 가지고 있기 때문에 훌륭한 임베디드 보드를 만듭니다.
Linux OS없이 Raspberry Pi를 사용할 수 있습니까? 어떻게해야합니까?
답변:
Raspberry Pi에서 베어 메탈 프로그래밍을 살펴본 결과 원하는 작업처럼 들립니다. 코드를 작동시키기 위해 많은 노력을 기울인 일부 사람들과 베어 메탈 프로그래밍에 대한 몇 가지 좋은 포럼 주제가 있습니다. 시작하려면 다음을 확인하십시오.
또는 일반적으로 Raspberry Pi의 Bare Metal Forum으로 이동하여 둘러 볼 수 있습니다.
내 이해는 Broadcom 칩에 내장 된 부팅 순서로 인해 SD 카드에서 부팅해야한다는 것입니다. 부팅 순서에 대한 링크를 찾으려고하는데 Google fu가 작동하지 않습니다. 나중에 찾으면 편집하겠습니다.
부팅하는 유일한 방법은 fat32 형식의 sdcard에서 시작하고 poweron에서 gpu 펌웨어로드로 이동하여 kernel이라는 이름의 arm 이진 파일을 실행합니다 .img 따라서 원하는대로하는 사용자 정의 커널을 만들고 싶다면 이 지점에서
완전 자동화 된 최소 베어 메탈 깜박임 예
Ubuntu 16.04 호스트 인 Raspberry Pi 2에서 테스트되었습니다.
호스트에 SD 카드 삽입
이미지를 만드십시오 :
./make.sh /dev/mmblck0 p1
어디에:
/dev/mmblck0
SD 카드의 장치입니다p1
장치의 첫 번째 파티션입니다 ( /dev/mmblck0p1
)PI의 삽입 된 SD 카드
전원을 껐다 켜십시오
GitHub 업스트림 : https://github.com/cirosantilli/raspberry-pi-bare-metal-blinker/tree/d20f0337189641824b3ad5e4a688aa91e13fd764
시작
.global _start
_start:
mov sp, #0x8000
bl main
hang:
b hang
main.c
#include <stdint.h>
/* This is bad. Anything remotely serious should use timers
* provided by the board. But this makes the code simpler. */
#define BUSY_WAIT __asm__ __volatile__("")
#define BUSY_WAIT_N 0x100000
int main( void ) {
uint32_t i;
/* At the low level, everything is done by writing to magic memory addresses. */
volatile uint32_t * const GPFSEL4 = (uint32_t *)0x3F200010;
volatile uint32_t * const GPFSEL3 = (uint32_t *)0x3F20000C;
volatile uint32_t * const GPSET1 = (uint32_t *)0x3F200020;
volatile uint32_t * const GPCLR1 = (uint32_t *)0x3F20002C;
*GPFSEL4 = (*GPFSEL4 & ~(7 << 21)) | (1 << 21);
*GPFSEL3 = (*GPFSEL3 & ~(7 << 15)) | (1 << 15);
while (1) {
*GPSET1 = 1 << (47 - 32);
*GPCLR1 = 1 << (35 - 32);
for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; }
*GPCLR1 = 1 << (47 - 32);
*GPSET1 = 1 << (35 - 32);
for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; }
}
}
ldscript
MEMORY
{
ram : ORIGIN = 0x8000, LENGTH = 0x10000
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.bss*) } > ram
}
make.sh
#!/usr/bin/env bash
set -e
dev="${1:-/dev/mmcblk0}"
part="${2:-p1}"
part_dev="${dev}${part}"
mnt='/mnt/rpi'
sudo apt-get install binutils-arm-none-eabi gcc-arm-none-eabi
# Generate kernel7.img
arm-none-eabi-as start.S -o start.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c main.c -o main.o
arm-none-eabi-ld start.o main.o -T ldscript -o main.elf
# Get the raw assembly out of the generated elf file.
arm-none-eabi-objcopy main.elf -O binary kernel7.img
# Get the firmware. Those are just magic blobs, likely compiled
# from some Broadcom proprietary C code which we cannot access.
wget -O bootcode.bin https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/bootcode.bin?raw=true
wget -O start.elf https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/start.elf?raw=true
# Prepare the filesystem.
sudo umount "$part_dev"
echo 'start=2048, type=c' | sudo sfdisk "$dev"
sudo mkfs.vfat "$part_dev"
sudo mkdir -p "$mnt"
sudo mount "${part_dev}" "$mnt"
sudo cp kernel7.img bootcode.bin start.elf "$mnt"
# Cleanup.
sync
sudo umount "$mnt"