我试图了解 mtdoops.c 文件的功能。
MTD 设备分区被视为用于存储内核 oops 消息的循环缓冲区。
在编写任何新的内核 oops 消息之前,我们正在使用以下函数检查 mtd 分区中的空闲页面。
下面是 find_next_position 函数的函数代码。
static void find_next_position(struct mtdoops_context *cxt)
{
struct mtd_info *mtd = cxt->mtd;
int ret, page, maxpos = 0;
u32 count[2], maxcount = 0xffffffff;
size_t retlen;
for (page = 0; page < cxt->oops_pages; page++) {
if (mtd_block_isbad(mtd, page * record_size))
continue;
/* Assume the page is used */
mark_page_used(cxt, page);
ret = mtd_read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
&retlen, (u_char *)&count[0]);
if (retlen != MTDOOPS_HEADER_SIZE ||
(ret < 0 && !mtd_is_bitflip(ret))) {
printk(KERN_ERR "mtdoops: read failure at %ld (%td of %d read), err %d\n",
page * record_size, retlen,
MTDOOPS_HEADER_SIZE, ret);
continue;
}
if (count[0] == 0xffffffff && count[1] == 0xffffffff)
mark_page_unused(cxt, page);
if (count[0] == 0xffffffff || count[1] != MTDOOPS_KERNMSG_MAGIC)
continue;
if (maxcount == 0xffffffff) {
maxcount = count[0];
maxpos = page;
} else if (count[0] < 0x40000000 && maxcount > 0xc0000000) {
maxcount = count[0];
maxpos = page;
} else if (count[0] > maxcount && count[0] < 0xc0000000) {
maxcount = count[0];
maxpos = page;
} else if (count[0] > maxcount && count[0] > 0xc0000000
&& maxcount > 0x80000000) {
maxcount = count[0];
maxpos = page;
}
}
if (maxcount == 0xffffffff) {
cxt->nextpage = cxt->oops_pages - 1;
cxt->nextcount = 0;
}
else {
cxt->nextpage = maxpos;
cxt->nextcount = maxcount;
}
mtdoops_inc_counter(cxt);
}
在这里,我们循环遍历 mtd 分区中的所有可用页面。
cxt->oops_pages = (mtd 设备分区大小) / 记录大小,其中记录大小为 4096。
从代码中我们可以了解到,MTD 头信息和魔术指针信息存储在每页的前 16 位中。
请帮助了解此功能的功能。
1) 无法理解 0xffffffff、0x40000000、0xc0000000 等硬编码。
2)所有 if/else 条件都分配了相同的值。为什么只检查那些值?
3) 无法获得有关 MTD_HEADER 格式的足够信息。
mtdoops.c 的完整源代码可以在下面找到。
http://lxr.free-electrons.com/source/drivers/mtd/mtdoops.c
如果任何与 mtdoops 相关的文档链接可以提供很大帮助。提前致谢。