2015-10-31 4 views
1

Я пытаюсь понять функциональность файла mtdoops.c.find_next_position() function in mtdoops.c

Устройство MTD Разделение рассматривается как циклический буфер для хранения сообщений 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 = (МПД размер раздела устройства)/размер записи , где размер запись 4096.

Из кода мы можем понять, что, информация заголовка МПД и волшебной информации указателя в настоящее время хранится в первых 16 битах каждой страницы.

Пожалуйста, помогите понять функциональность этой функции.

1) Не удалось разобрать жесткие коды, такие как 0xffffffff, 0x40000000, 0xc0000000.

2) Все условия if/else присваивают одинаковые значения. Почему проверяются только эти значения?

3) не удалось получить достаточную информацию о формате MTD_HEADER.

Полный исходный код mtdoops.c можно найти ниже.

http://lxr.free-electrons.com/source/drivers/mtd/mtdoops.c

Если какая-либо связь документации, связанной с mtdoops может оказать большую помощь. Заранее спасибо.

ответ

1

Функция выполняет поиск последней записи, сделанной счетчиком счетчиков [0], которая интерпретируется как вид порядкового номера. Поскольку этот счетчик может обертываться, когда он достигает 0xffffffff, maxcount должен следовать за count [0] постепенно, а не быть максимальным из всех порядковых номеров. Вот почему, если счетчик счетчик [0] = 2, выполняется после того, как MAXCOUNT уже достигают, скажем (0xffffffff - 2), MAXCOUNT должен стать 2 (второй "еще-если")

} else if (count[0] < 0x40000000 && maxcount > 0xc0000000) { 

Все эти IFDEF-s для обработки обертки счетчика. Я согласен, что этот код не очень хорошо написан. Два последних «если еще-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 

еще итерация по страницам вместо пропуска всего плохого блока.