如何将 ARM 源文件制作成 Raspberry Pi 3 B 将 运行 的内核?

How do I make an ARM source file into a kernel that the Raspberry Pi 3 B will run?

我受到 this Starfox fan game to create a game using ARM assembly on the Raspberry Pi. I have also looked at this tutorial series 的启发,以更好地了解邮箱和帧缓冲系统。无论我使用哪个 Make/CMake,在启动时我都无法从这两个地方获得任何东西到 运行,因为它们应该在原始 Raspberry Pi 上 运行。我已经查看了 Valver 的裸机编程教程、raspberrypi.org 裸机论坛和无数来自我自己的 C 代码的输出源文件,只是为了了解如何在屏幕上打印图形,但一无所获。我在我的 C 代码中使用了 X11 库,结果发现输出的 ARM 源文件只是按原样调用 C 函数(例如 bl XOpenDisplay)。如果我尝试执行第二个 link 处给出的代码(确保将基本外设地址更改为 0x3F000000 并将视频核心访问权限更改为 0xC0000000),而 Raspbian 是运行ning,我遇到分段错误。

我想要一个汇编源文件(例如,main.s)并将其转换为二进制文件(例如,kernel7.img 或类似文件),它将 运行 一打开 Raspberry Pi 3 B.

是的,我知道用高级语言制作 GUI 更容易,但我决心让游戏在 ARM 汇编中运行。以下是一些对我的个人项目最有帮助的答案:

  1. 将前两个 link 的代码移植到我的 Pi 3 上 运行 启动时成功,请记住它们为我的模型生成了错误的二进制文件。
  2. 用于构建自定义 OS 的工具,可以根据需要注入汇编代码,但我不确定这是否合理。
  3. 了解如何在 ARM 程序集中制作 GUI 的资源,这些 GUI 可以 运行 在最新的 Raspbian 上而不会产生分段错误或类似错误。

谢谢!

裸机可能是去这里的正确方法。烘焙 pi 系列很好,很多人都从那里开始,它有一些问题可能会妨碍您。 raspberrypi.org 的 baremetal 论坛非常非常好,有一个包含大量 baremetal 信息和示例的固定线程。

vectors.s

.globl _start
_start:
    mov sp,#0x8000
    bl notmain
hang: b hang

.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

.globl dummy
dummy:
    bx lr

notmain.c

extern void PUT32 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern void dummy ( unsigned int );

#define SYSTIMERCLO 0x20003004
#define GPFSEL3 0x2020000C
#define GPFSEL4 0x20200010
#define GPSET1  0x20200020
#define GPCLR1  0x2020002C

//0x01000000 17 seconds
//0x00400000 4 seconds
//#define TIMER_BIT 0x01000000
#define TIMER_BIT 0x00400000

int notmain ( void )
{
    unsigned int ra;

    ra=GET32(GPFSEL4);
    ra&=~(7<<21);
    ra|=1<<21;
    PUT32(GPFSEL4,ra);

    while(1)
    {
        PUT32(GPSET1,1<<(47-32));
        while(1)
        {
            ra=GET32(SYSTIMERCLO);
            if((ra&=TIMER_BIT)==TIMER_BIT) break;
        }
        PUT32(GPCLR1,1<<(47-32));
        while(1)
        {
            ra=GET32(SYSTIMERCLO);
            if((ra&=TIMER_BIT)==0) break;
        }
    }
    return(0);
}

内存映射

MEMORY
{
    ram : ORIGIN = 0x8000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > ram
    .bss : { *(.bss*) } > ram
}

建设

arm-none-eabi-as --warn --fatal-warnings vectors.s -o vectors.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c notmain.c -o notmain.o
arm-none-eabi-ld vectors.o notmain.o -T memmap -o notmain.elf
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy notmain.elf -O binary kernel.img

在 pi-zero 上删除任何 config.txt,保存或重命名任何 kernel.img 并复制此 kernel.img,LED 将闪烁。

删除 C 代码并分支到您的主程序中,将其添加到项目中,然后就可以了...

视频的帧缓冲区非常简单,一次邮箱握手,你就有了一个基地址来将像素推入...

从 pi-0 开始...对于 pi3,您需要处于 aarch32 模式,您可能需要 config.txt 才能做到。如果你没有做任何中断,它在大多数情况下工作相同,如果你有很多裸机示例来向你展示修改...