cmarrin
Posts: 23
Joined: Sat Sep 15, 2018 7:19 pm

Limit on the size of a bare metal program?

Sat Sep 15, 2018 7:42 pm

I've been bare metal programming on a Raspberry Pi Zero W for a couple of weeks. It's my own code, but with many ideas from other work, especially that of David Welch. It's been working great. I've added interrupt driven serial input, I'm using the ARM timer to blink the activity LED on an interrupt, and I have a really simple serial console.

Here's the thing. My code is currently at 19228 bytes (the size of the .bin file). When I load it onto the SD card everything works great. If I add something to get the size to 19232 it still works. But if it gets up to 19236, it fails to run. I'm loading the code at 0x8000 and there doesn't seem to be anything magic that I can find about those numbers. I'm mostly using dwelch's loadmap which is pretty much just:

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

Is there some magic I'm missing about default ram limits or something? I'm not setting up the MMU or anything.

cmarrin
Posts: 23
Joined: Sat Sep 15, 2018 7:19 pm

Re: Limit on the size of a bare metal program?

Sun Sep 16, 2018 5:54 am

A little more info. I'm convinced now that it's not an absolute limit I'm going over. Seems more like it's a positioning of code or something. Maybe I'm overrunning a buffer, which is sometimes is benign and other times is fatal. For a bit, I was thinking that code optimization might be failing. I would try -Os, -Og, -Ofast. Occasionally one of these would get it working. But I think it was just moving the code around to a more or less dangerous arrangement.

So my next question is about debugging tools. I have the ability to print to the serial console and sometimes this works. But other times I have some Heisenberg action going on. Adding the prints causes a failure where there was none before. Does anyone have any clever debugging tricks I can use on a bare metal system? Otherwise, I'll just continue commenting out blocks of code to get more clues about what's happening.

cmarrin
Posts: 23
Joined: Sat Sep 15, 2018 7:19 pm

Re: Limit on the size of a bare metal program?

Sun Sep 16, 2018 6:18 am

One more post. I think I've found the culprit.I have 2 interrupt sources, the ARM Timer and the mini UART. When setting up each I disable the interrupt line specific to that device in the interrupt peripheral registers (the ones at 0x2000B200). Then I setup all the control registers and then re-enable the interrupt lines. Then I enable interrupts in the CPSR register. I do this with an enableIRQ() function which is some assembly to read, set and write the CPSR register.

This is basically following dwelch's patterns for the timer and uart demos. But he never enabled both at the same time. So I added an enableIRQ() on both devices and it looks like that sometimes causing a problem. Not sure if it's because touching the CPSR register when interrupts are enabled is a bad thing or if this is just a red herring. But I tried adding a disableIRQ() function. When I start setting up the device I disableIRQ(), do the setup and then do enableIRQ(). Seems like the right thing to do and it solves the problem for now. But there still might be something lurking out there waiting to stab me in the back again.

Does anyone have any "best practices" for managing the interrupt system?

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: Limit on the size of a bare metal program?

Sun Sep 16, 2018 8:32 pm

That was an arbitrary limit. I tend to use minimalish sizes on my examples so that I dont have to keep changing the linker script every time.

Historically and probably still you could (can) adjust the split length to determine how much if the ram goes to the arm and how much to the GPU so even for a specific board with a specific amount of memory I didnt want a big limit.

My code is meant to be an example, a starting point, borrow from or not and adjust as desired to your application.

There are ways to determine the amount of memory at boot, the information is passed to the linux kernel so you can pick it up using that mechanism. still need to have a reasonable limit on the .text limit and then depending on your application can use whatever else is available based on detection. But thats getting ahead of things. There was no magic limit there, I probably started with a small number like 0x1000 or 0x8000 then made it larger as needed for an example program. I guess we could go back to the early commits of the repo.

Good Luck,
Enjoy,

David

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: Limit on the size of a bare metal program?

Sun Sep 16, 2018 8:52 pm

Yeah I dont use interrupts unless I have to, or unless I want to do a simple demonstration as they are a bigger trap than just booting a processor. One little mistake and pain. Uart interrupts are generally tricky, depends on the uart (talking general not necessarily pi) Usually you get an interrupt when a buffer becomes free on the TX side or hits a low water limit or not empty or a high water limit. timers and system call interrupts and such are easier to demonstrate the mechanism of telling the peripheral to interrupt, then enabling the various layers between the interrupt and processor, place the vector/handler clean up and return. I use the uart for debugging primarily and/or it is the forground task, so I rarely if ever use the interrupt for it.

My belief is the first steps are where we lose a lot of baremetal programmers no matter what platform. mastering the tools enough to build a binary that works, enough of a bootstrap to get running, and then some peripheral management to see that it really did boot. I have personal curiosities like aarch64 and how to "split the cores" and actually the added pain to get an interrupt/system call through on the 64 bit arm. So I went down those paths. With help from the other folks here. Pay it forward.

Certainly if you have multiple interrupts then it gets into interrupt priorities if that is part of the design. single or multiple there is the how do you clean up, what if one happened while I was blind, from the time it asserted and the logic took over to when I could possibly safely switch modes or re-arm the interrupt, etc. Do I want to do it that way or check at the end of the handler to see if another came in, so I can control when the handler gets interrupted. Then timer plus uart, plus other, what if anything overlaps what if anything is completely separate. All part of the fun.

Enjoy, you have found a great resource here, I have not seen a forum this useful in a long while.
David

cmarrin
Posts: 23
Joined: Sat Sep 15, 2018 7:19 pm

Re: Limit on the size of a bare metal program?

Tue Sep 18, 2018 8:26 pm

Agreed about the usefulness of this forum, and of course your work deserves the most credit for getting me this far.

Thanks!

Return to “Bare metal, Assembly language”