我正在尝试了解 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 device partition size) / record size where record size is 4096.
从代码中我们可以了解到,MTD头信息和魔法指针信息存储在每个页面的前16位。
Please help to understand the functionality of this function.
1) Could not understand the hardcodings like 0xffffffff, 0x40000000 , 0xc0000000.
2) All the if/else condition is assigning same values . why only those values are being checked ?
3) could not get sufficient information about MTD_HEADER format.
完整的 mtdoops.c 源代码如下。
http://lxr.free-electrons.com/source/drivers/mtd/mtdoops.c
如果有任何与 mtdoops 相关的文档链接可以提供很大帮助。提前致谢。
最佳答案
该函数搜索计数器 count[0] 生成的最后一条记录,它被解释为一种序列号。由于此计数器在达到 0xffffffff 时可以回绕,因此 maxcount 应该逐步跟随 count[0],而不是成为所有序列号的最大值。这就是为什么如果 counter count[0] = 2,在 maxcount 已经达到之后满足,比如说 (0xffffffff - 2),maxcount 应该变成 2(第二个“else-if”)
} else if (count[0] < 0x40000000 && maxcount > 0xc0000000) {
所有这些 ifdef-s 都用于处理计数器的环绕。 我同意这段代码写得不是很好。最后两个“if else-s”,恕我直言,可以一次完成
} else if (count[0] > maxcount) {
我无法想象什么时候的情况
else if (count[0] > maxcount && count[0] > 0xc0000000
&& maxcount < 0x80000000) {
可以满足。
值 0xffffffff、0x40000000、0xc0000000 只是方便使用的值。同样成功,可以使用 0xc0000020 代替 0xc0000000。
我可以在这个函数中看到另一个奇怪的东西,比如
if (mtd_block_isbad(mtd, page * record_size))
continue
仍然遍历页面而不是跳过整个坏 block 。
关于c - mtdoops.c 中的 find_next_position() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33450420/