简体   繁体   中英

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

I was inspired by this Starfox fan game to create a game using ARM assembly on the Raspberry Pi. I have also looked at this tutorial series to get a better understanding of the mailbox and frame buffer systems. No matter which Make/CMake I use, I cannot get anything from either of those places to run on startup because they were expected to run on the original Raspberry Pi. I have looked at Valver's bare metal programming tutorial, the raspberrypi.org bare metal forums, and countless output source files from my own C code just to understand how to print graphics on the screen and have gotten nowhere. I have used the X11 library in my C code only to find that the output ARM source file simply calls the C functions as is (eg bl XOpenDisplay ). If I try to execute the code given at the second link (making sure to change the base peripheral address to 0x3F000000 and the video core access to 0xC0000000 ) while Raspbian is running, I get segmentation faults.

I want to have an assembly source file (say, main.s ) and make it into a binary (say, kernel7.img or similar) that will run as soon as I turn on my Raspberry Pi 3 B.

Yes, I know making GUIs in high level languages is easier, but I am determined to make the game operate in ARM assembly. Here are some answers that would be most helpful in my personal project:

  1. Porting the code from the first two links to successfully run on my Pi 3 upon startup, bearing in mind that they produce the wrong binaries for my model.
  2. Tools for building a custom OS that can inject assembly code as needed, though I'm not sure how plausible that is.
  3. Resources to learn how to make GUIs in ARM assembly that can run on the latest Raspbian without creating segmentation faults or similar errors.

Thank you!

baremetal is probably the right way to go here. the baking pi series is fine lots of folks have started there, it has issues that will probably get in your way. The baremetal forum at raspberrypi.org is very very good, there is a pinned thread with lots of baremetal information and examples.

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);
}

memmap

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

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

build

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

on pi-zero remove any config.txt, save or rename any kernel.img and copy this kernel.img and the leds will blink.

remove the c code and branch into your main add that to the project and there you go...

the framebuffer for video is super easy, one mailbox handshake and you have a base address to shove pixels into...

start with a pi-zero...for a pi3 you will want to be in aarch32 mode which you may need a config.txt to do. it for the most part works the same if you are not doing any interrupts, if you are then there are plenty of baremetal examples to show you the modifications...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM