在mtdoops.c中查找下一个函数
我试图理解mtdoops.c文件的功能 MTD设备分区被视为用于存储内核oops消息的循环缓冲区 在编写任何新的内核oops消息之前,我们使用下面的函数检查mtd分区中的空闲页面在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
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