I'm working on a kernel for a RaspberryPi 1B+ and I'm having some trouble with the ATAGS. My orientation for the implementation was this page.
The implementation for parsing looks something like this:
typedef struct atag_header
{
uint32_t size;
uint32_t tag_type;
} atag_header;
typedef struct atag_core
{
uint32_t flags;
uint32_t pagesize;
uint32_t rootdevice;
} atag_core;
typedef struct atag_mem
{
uint32_t size;
uint32_t address;
} atag_mem;
/* etc... */
typedef struct atag_t {
atag_header header;
union {
atag_core core;
atag_mem mem;
atag_ramdisk ramdisk;
atag_initrd2 initrd2;
atag_serial serial;
atag_revision revision;
atag_videolfb videolfb;
atag_cmdline cmdline;
};
} atag_t;
#define tag_next(t) ((atag_t *)((uint32_t *)(t) + (t)->header.size))
#define tag_size(type) ((sizeof(atag_header) + sizeof(type)) >> 2)
Now as far as I understand the atag's are passed to the kernel over r2, i.e.
void kernel(uint32_t r0, uint32_t r1, uint32_t r2)
Now r2 is supposed to be the address at which the list of ATAG's starts. I would like to get the RAM size, so I wrote a little function
uint32_t get_mem_size(atag_t * atags) {
while (atags->header.tag_type != ATAG_NONE) {
if (atags->header.tag_type == ATAG_MEM) {
return atags->mem.size;
}
atags = tag_next(atags);
}
return 0;
}
but this just returns zero (calling it with get_mem_size((atag_t *)r2)). So, I assumed that I was doing something wrong... Turns out, r2 is always 0x6E750000 and well this is no atag so of course tag_next will never reach the memory segment..
I don't really understand what I'm doing wrong. Did I misunderstand something about these atags?
After some trying out I got it to work, but I still don't fully understand what the original problem was.
The way how I got my custom kernel onto the Pi worked something like this:
kernel.imgwith custom kernel.Now most of the files on the SD card are actually not necessary when you are writing your custom kernel, in fact, you only need
bootcode.bin, start.elf, fixup.datand your kernel image. Once I had removed everything the ATAG address switched from0x6E750000to0. After some digging I found this github repo with the following at the beginning of thekernel_mainAfter adding this to my
kernel_main, the code started working. So it seems my atags are not specified... Not sure why this happens or where exactly I would need to set this up, but this does the trick for now. If anyone knows what is going on here, please feel free to add to this/make your own answer.