Raspberry Pi 4 kernel load address
tdh8316 opened this issue · 2 comments
Hi! first of all, thank you for writing this guide.
I followed everything in part 2-building and wrote my own kernel.c due to I have no UART connector.
// kernel.c
#define BCM2711_PERI_BASE_ADDR 0xFE000000
#define GPIO_BASE_ADDR BCM2711_PERI_BASE_ADDR + 0x200000
#define OUT_PIN 21
volatile unsigned *m_pGPIO;
void setGPIOModeInput(int pin)
{
const int reg = pin / 10;
const int shift = (pin % 10) * 3;
*(m_pGPIO + reg) = ((*(m_pGPIO + reg) & ~(7 << shift)) | (0 << shift));
}
void setGPIOModeOutput(int pin)
{
setGPIOModeInput(pin);
const int reg = pin / 10;
const int shift = (pin % 10) * 3;
*(m_pGPIO + reg) = ((*(m_pGPIO + reg) & ~(7 << shift)) | (1 << shift));
}
inline __attribute__((always_inline)) void setGPIO(int pin)
{
*(m_pGPIO + 7) = 1 << pin;
}
inline __attribute__((always_inline)) void clrGPIO(int pin)
{
*(m_pGPIO + 10) = 1 << pin;
}
int main(void)
{
m_pGPIO = (volatile unsigned *)GPIO_BASE_ADDR;
setGPIOModeOutput(OUT_PIN);
while (1)
{
setGPIO(OUT_PIN);
clrGPIO(OUT_PIN);
}
}
And I made the latest Raspbian-Lite (64bit) micro SD card using raspberry pi imager. Then replaced the kernel8.img
.
I expected GPIO21 (40 for hardware) to generate spikes, but it didn't.
I'm not even sure whether the boot sequence is done; I found this post on the forum. They say the kernel load address is changed to 0x200000.
Is this guide affected by that post? If not, I'll assume that the kernel.c
contains problems.
Hi,
Thanks for your message. The kernel load address should still be 0x80000
.
I suspect you have an issue with your kernel.c.
All the best,
Adam
You intrigued me, so I had a play tonight!
I couldn't get your code to work, but I put this together... It does exactly what you expect yours to do and I've tested it (with a LED and a resistor).
It doesn't help me work out what's wrong with your code, but at least it proves it should work (and all this at load address 0x80000
).
All the best and happy bug hunting!
Adam
#define PERIPHERAL_BASE 0xFE000000
#define GPFSEL0 PERIPHERAL_BASE + 0x200000
#define GPSET0 PERIPHERAL_BASE + 0x20001C
#define GPCLR0 PERIPHERAL_BASE + 0x200028
#define GPIO_FUNCTION_OUT 1
#define GPIO_MAX_PIN 53
void mmio_write(long reg, unsigned int val) { *(volatile unsigned int *)reg = val; }
unsigned int mmio_read(long reg) { return *(volatile unsigned int *)reg; }
unsigned int gpio_call(unsigned int pin_number, unsigned int value, unsigned int base, unsigned int field_size, unsigned int field_max) {
unsigned int field_mask = (1 << field_size) - 1;
if (pin_number > field_max) return 0;
if (value > field_mask) return 0;
unsigned int num_fields = 32 / field_size;
unsigned int reg = base + ((pin_number / num_fields) * 4);
unsigned int shift = (pin_number % num_fields) * field_size;
unsigned int curval = mmio_read(reg);
curval &= ~(field_mask << shift);
curval |= value << shift;
mmio_write(reg, curval);
return 1;
}
unsigned int gpio_set(unsigned int pin_number, unsigned int value) { return gpio_call(pin_number, value, GPSET0, 1, GPIO_MAX_PIN); }
unsigned int gpio_clear(unsigned int pin_number, unsigned int value) { return gpio_call(pin_number, value, GPCLR0, 1, GPIO_MAX_PIN); }
unsigned int gpio_function(unsigned int pin_number, unsigned int value) { return gpio_call(pin_number, value, GPFSEL0, 3, GPIO_MAX_PIN); }
int main(void)
{
gpio_function(21, GPIO_FUNCTION_OUT);
while (1)
{
gpio_set(21, 1);
gpio_clear(21, 1);
}
}