C语言 在引导自定义RaspberryPi内核时,标记是无意义的

hs1rzwqc  于 2023-04-19  发布在  其他
关注(0)|答案(1)|浏览(84)

我正在为RaspberryPi 1B+开发内核,我在ATAGS上遇到了一些问题。我的实现方向是这个页面。
解析的实现看起来像这样:

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)

现在,据我所知,atag是通过r2传递给内核的,即。

void kernel(uint32_t r0, uint32_t r1, uint32_t r2)

现在r2应该是ATAG列表的起始地址。我想得到RAM大小,所以我写了一个小函数

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

但这只会返回零(用get_mem_size((atag_t *)r2)调用它)。所以,我假设我做错了什么...结果,r2总是0x6E750000,而这是没有atag,所以当然tag_next永远不会到达内存段。
我真的不明白我做错了什么。我是不是误解了这些标签?

k5ifujac

k5ifujac1#

经过一些尝试,我得到了它的工作,但我仍然不完全理解原来的问题是什么。
我将自定义内核放到Pi上的方式是这样的:
1.使用RaspberryPi成像工具将Raspian闪存到SD卡上。
1.用自定义内核替换kernel.img
现在SD卡上的大部分文件在你写自定义内核时实际上是不必要的,事实上,你只需要bootcode.bin, start.elf, fixup.dat和你的内核镜像。一旦我删除了所有的ATAG地址从0x6E750000切换到0。经过一些挖掘,我发现这个github仓库在kernel_main的开头有以下内容

// Hack for newer firmware - assume if atags not specified then they are at 0x100
// We also check the zero address in case this is true - see later
if(atags == 0x0)
    atags = 0x100;

在将此添加到我的kernel_main后,代码开始工作。所以似乎我的标签没有指定...不知道为什么会发生这种情况,或者我需要在哪里设置它,但这是现在的诀窍。如果有人知道这里发生了什么,请随时添加到这里/做出自己的答案。

相关问题