Пишу модуль ядра с целью отслеживания повреждений памяти. Для этого периодически вычисляю контрольные суммы сегментов кода для каждой задачи и сравниваю с предыдущими значениями. Все было бы хорошо, если бы в результате не получалось, что области, которые я пытаюсь контролировать, оказались изменяющимися. Такое явление можно было бы объяснить например свопингом, но у меня ядро работает без поддержки свопинга. Значит остается вариант, что я неверно нахожу адреса:
прохожусь по всем задачам и по всем областям для каждой из задач,
для сегментов кода вызываю функцию вычисления контрольной суммы
for_each_task(ts)
{
struct vm_area_struct *mmap = ts->mm->mmap;
while (mmap)
{
if (Code_Segment(mmap)) Check_Summ(mmap);
mmap = mmap->next;
}
}
а вот здесь как раз вопрос: почему возвращаются адреса (start_code), которые в действительности не соответствуют сегментам кода?... поэтому и контрольные суммы у меня не сходятся... (как я понимаю)
void Check_Summ(struct vm_area_struct *mmap)
{
unsigned long start = mmap->vm_start,
end = mmap->vm_end,
size = end - start;
pgd_t *pgd = pgd_offset(mmap->vm_mm, start);//перевожу виртуальный адрес пространства задачи в физ.
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);
void *start_code = __va(phys_addr); //перевожу физический адрес в виртуальный пространства ядра
unsigned int csum = Crc32(start_code, size);
printk("sum=%10u\n",csum);
}
контроль целостности сегментов кода
Модератор: Модераторы разделов
-
- Сообщения: 7
Re: контроль целостности сегментов кода
интересен даже такой факт:
преобразую виртуальный адрес пространства задачи в физический известным методом через таблицы страниц
pgd_t *pgd = pgd_offset(mm, start);
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);
и получаю физический адрес, который больше максимально доступной памяти!))
господа!, объясните новичку. мое знание не согласуется с происходящим
преобразую виртуальный адрес пространства задачи в физический известным методом через таблицы страниц
pgd_t *pgd = pgd_offset(mm, start);
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);
и получаю физический адрес, который больше максимально доступной памяти!))
господа!, объясните новичку. мое знание не согласуется с происходящим
-
- Сообщения: 20
- ОС: Linux
Re: контроль целостности сегментов кода
Zulkidal писал(а): ↑29.01.2010 15:16интересен даже такой факт:
преобразую виртуальный адрес пространства задачи в физический известным методом через таблицы страниц
pgd_t *pgd = pgd_offset(mm, start);
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);
и получаю физический адрес, который больше максимально доступной памяти!))
господа!, объясните новичку. мое знание не согласуется с происходящим
1) значением pte entry является не физический адрес, там еще флаги есть (Intel Software Developers Manual в помощь)
2) ядро содержит отображение 1:1 только для примерно гига памяти (на самом деле меньше), так
что если физический адрес будет выше этой границы, __va() работать не будет.
-
- Сообщения: 7
Re: контроль целостности сегментов кода
int_0dh писал(а): ↑29.01.2010 16:511) значением pte entry является не физический адрес, там еще флаги есть (Intel Software Developers Manual в помощь)
2) ядро содержит отображение 1:1 только для примерно гига памяти (на самом деле меньше), так
что если физический адрес будет выше этой границы, __va() работать не будет.
при чем здесь pte entry? тут в коде такого вообще нет.
и при чем здесь флаги?
>intel developers manual
я-то как раз прочитал этот мануал.
про __va() я знаю. у меня 512 метров оперативки - далеко еще до ХайМем (896 м.). так что вопрос про преобразование адресов открыт.
-
- Сообщения: 20
- ОС: Linux
Re: контроль целостности сегментов кода
>>1) значением pte entry является не физический адрес, там еще флаги есть (Intel Software Developers Manual в помощь)>>>
>>2) ядро содержит отображение 1:1 только для примерно гига памяти (на самом деле меньше), так
>>что если физический адрес будет выше этой границы, __va() работать не будет.
>при чем здесь pte entry? тут в коде такого вообще нет.
>и при чем здесь флаги?
да ну?
вот строчка из кода что вы привели:
unsigned long phys_addr = pte_val(*pte);
теперь тут находится отнюдь на физический адрес а просто значение PTE entry.
чтобы получить физический адрес надо сделать phys_addr &= ~PTE_FLAG_MASK;
>>intel developers manual
>я-то как раз прочитал этот мануал.
ок, еще раз прочесть всегда полезно
>>2) ядро содержит отображение 1:1 только для примерно гига памяти (на самом деле меньше), так
>>что если физический адрес будет выше этой границы, __va() работать не будет.
>при чем здесь pte entry? тут в коде такого вообще нет.
>и при чем здесь флаги?
да ну?
вот строчка из кода что вы привели:
unsigned long phys_addr = pte_val(*pte);
теперь тут находится отнюдь на физический адрес а просто значение PTE entry.
чтобы получить физический адрес надо сделать phys_addr &= ~PTE_FLAG_MASK;
>>intel developers manual
>я-то как раз прочитал этот мануал.
ок, еще раз прочесть всегда полезно
-
- Сообщения: 7
Re: контроль целостности сегментов кода
спасибо. именно такую конкретику и хотел услышать
могли бы вы объяснить преобразование phys_addr &= ~PTE_FLAG_MASK ?
и главное: в ядре 2.4.32 нигде не определено это зничение маски
вот есть в <asm-i386/page.h> такое
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PTE_MASK PAGE_MASK
-
- Сообщения: 20
- ОС: Linux
Re: контроль целостности сегментов кода
надо просто отрезать младшие 12 бит (0-11).
перед этим неплохо проверить что страница действительно присутствует в памяти.
и учесть что в вашем коде возможны гонки, так что время от времени вы можете
получать неверные значения чексумм.
перед этим неплохо проверить что страница действительно присутствует в памяти.
и учесть что в вашем коде возможны гонки, так что время от времени вы можете
получать неверные значения чексумм.
-
- Сообщения: 7
-
- Сообщения: 20
- ОС: Linux
Re: контроль целостности сегментов кода
ну, я не телепат и не знаю из какого контекста
вызывается ваша хрень. если вы не хватаете
соответсвующие блокировки/семафоры то ,например, вполне возможны
модификации системой/другими потоками процесса
списка vma/pde/pte во время ваших по ним прогулок.
-
- Сообщения: 7
Re: контроль целостности сегментов кода
что-то я не понимаю:
после действий
pgd_t *pgd = pgd_offset(mm, start);
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);
я получаю виртуальный адрес Page Table Entry. затем вы мне предлогаете маскировать первые 12 бит (для получения физического адреса), которые являются в адресе смещением относительно начала страницы - получаем совсем не физический адрес!)) получили всего-навсего адрес Page Table Directory в которой лежит наш PTE.
как же тогда получить физический адрес?
прочитав intel developers manual я как раз все понял. как говорится, и ежу ясно. но множество функций и определений в ядре вместе еще и со средним каталогом, не несущим никакой смыловой нагрузки, сбивают меня с толку
как я себе представляю это дело:
в результате получив pte, я беру старшие 20 бит из этой структуры, соответствующие адресу дескриптора страничного кадра, смещаю на 12 и получаю адрес struct page. по адресу дескрипотра и началу массива дескрипоторов страничных кадров вычисляю номер в последнем. номер смещаю на 12 и получаю физический адрес.
хм, осталось дело за малым))
-
- Сообщения: 7
Re: контроль целостности сегментов кода
Хм, я загнул. Да и думал неверно: работал с адресом, когда надо работать с содержимым по этому адресу))
структура PTE не может указывать на такой маленький объект, как struct page. Она непосредственно содержит физический адрес страницы.
структура PTE не может указывать на такой маленький объект, как struct page. Она непосредственно содержит физический адрес страницы.