在mtdoops.c中查找下一个函数

在mtdoops.c中查找下一个函数,c,linux,kernel,panic,C,Linux,Kernel,Panic,我试图理解mtdoops.c文件的功能 MTD设备分区被视为用于存储内核oops消息的循环缓冲区 在编写任何新的内核oops消息之前,我们使用下面的函数检查mtd分区中的空闲页面 static void find_next_position(struct mtdoops_context *cxt) { struct mtd_info *mtd = cxt->mtd; int ret, page, maxpos = 0; u32 count[2], maxcount

我试图理解mtdoops.c文件的功能

MTD设备分区被视为用于存储内核oops消息的循环缓冲区

在编写任何新的内核oops消息之前,我们使用下面的函数检查mtd分区中的空闲页面

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);
下面是查找下一个位置功能的功能代码

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);
静态无效查找下一个位置(结构mtdoops\u上下文*cxt)
{
结构mtd_info*mtd=cxt->mtd;
int ret,第页,maxpos=0;
u32计数[2],最大计数=0xffffffff;
尺寸调整;
对于(第0页;第oops\u页;第++){
if(mtd_块_坏(mtd,页面*记录_大小))
继续;
/*假设页面已被使用*/
标记所使用的页面(cxt,第页);
ret=mtd\U读取(mtd,页面*记录大小,MTDOOPS\U页眉大小,
&retlen,(u_char*)和count[0];
如果(retlen!=MTDOOPS\u标题\u大小||
(ret<0&!mtd_是位翻转(ret))){
printk(KERN_ERR“mtdoops:read failure at%ld(%td of%d read)),ERR%d\n“,
页面*记录大小,重新调整,
MTDOOPS_收割台_尺寸,ret);
继续;
}
如果(计数[0]==0xFFFFFF&&count[1]==0xFFFFFF)
标记未使用的页面(cxt,第页);
如果(计数[0]==0xffffffff | |计数[1]!=MTDOOPS\u KERNMSG\u MAGIC)
继续;
如果(maxcount==0xFFFFFF){
maxcount=计数[0];
maxpos=页面;
}否则如果(计数[0]<0x40000000&&maxcount>0xc0000000){
maxcount=计数[0];
maxpos=页面;
}否则如果(计数[0]>maxcount&&count[0]<0xc0000000){
maxcount=计数[0];
maxpos=页面;
}否则如果(计数[0]>maxcount&&count[0]>0xc0000000
&&最大计数>0x8000000){
maxcount=计数[0];
maxpos=页面;
}
}
如果(maxcount==0xFFFFFF){
cxt->nextpage=cxt->oops\u页面-1;
cxt->nextcount=0;
}
否则{
cxt->nextpage=maxpos;
cxt->nextcount=MAXTCOUNT;
}
mtdoops公司计数器(cxt);
}

在这里,我们将遍历mtd分区中所有可用的页面

cxt->oops\U页=(mtd设备分区大小)/记录大小 其中记录大小为4096

从代码中我们可以理解,MTD头信息和魔术指针信息存储在每个页面的前16位

请帮助理解此功能的功能

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);
1) 无法理解硬编码,如0xFFFFFF、0x40000000、0xc0000000

2) 所有的if/else条件都指定了相同的值。 为什么只检查这些值

3) 无法获取有关MTD_标头格式的足够信息

下面是mtdoops.c的完整源代码


如果有任何与mtdoops相关的文档链接可以提供很大帮助。提前感谢。

该函数搜索计数器计数[0]生成的最后一条记录,该记录被解释为序列号类型。由于此计数器可以在到达0xFFFFFF时环绕,因此maxcount应逐步跟随计数[0],而不是所有序列号的最大值。这就是为什么如果在maxcount已经达到(0xffffffff-2)之后计数器计数[0]=2,maxcount应该变成2(第二个“else if”)

我无法想象情况会怎样

else if (count[0] > maxcount && count[0] > 0xc0000000
    && maxcount < 0x80000000) {
仍然迭代页面,而不是跳过整个坏块

if (mtd_block_isbad(mtd, page * record_size))
    continue