Тройная ошибка в домашнем ядре - PullRequest
9 голосов
/ 02 ноября 2010

Я пытаюсь написать ядро, в основном для развлекательных целей, и сталкиваюсь с проблемой, если считаю, что это тройная ошибка.Все работало до того, как я попытался включить пейджинг.Код, который нарушает, таков:

void switch_page_directory(page_directory_t *dir){

 current_directory = dir;
 asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));

 u32int cr0;
 asm volatile("mov %%cr0, %0": "=r"(cr0));

 cr0 |= 0x80000000;//enable paging
 asm volatile("mov %0, %%cr0":: "r"(cr0)); //this line breaks


}//switch page directory

Я следовал различным учебным пособиям / документам для этого, но, таким образом, я использую для подкачки страниц http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html.Я не уверен, какой другой код будет полезен для выяснения этого, но если мне нужно будет предоставить еще кое-что, я буду очень рад это сделать.

Edit =====

Я считаю, что CS, DS и SS выбирают правильные записи. Вот код, используемый для их установки

global gdt_flush     
extern gp            
gdt_flush:

    lgdt [gp]        ; Load the GDT with our 'gp' which is a special pointer
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment

    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!

flush2:
    ret               ; Returns back to the C code!

, а вот сама структура gdt

struct gdt_entry{
    unsigned short limit_low;
    unsigned short base_low;
    unsigned char base_middle;
    unsigned char access;
    unsigned char granularity;
    unsigned char base_high;
} __attribute__((packed));

struct gdt_ptr{
    unsigned short limit;
    unsigned int base;
} __attribute__((packed));

struct gdt_entry gdt[5];
struct gdt_ptr gp;

IDT очень похожа на эту.

Ответы [ 3 ]

6 голосов
/ 03 ноября 2010

GDT: вы не говорите, что такое содержимое записей GDT, но материал, который вы показали, выглядит довольно похоже на более раннюю часть учебника, с которой вы связались и если вы настроили записи таким же образом, то все должно быть хорошо (то есть отображение плоского сегмента с сегментом кода кольца 0 для CS, сегмент данных кольца 0 для всего остального, как с базой 0, так и сограничение в 4 ГБ).

IDT: вероятно, в любом случае не имеет значения, если прерывания отключены и вы (пока) не ожидаете возникновения ошибок страницы.

Таблицы страниц: неверные таблицы страниц делаюткажется наиболее вероятным подозреваемым.Убедитесь, что ваше отображение идентификаторов охватывает все кода, данных и стековой памяти, которые вы используете (по крайней мере).

Исходный код, связанный с нижней частью http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html определенно создает что-то, что работает правильно работает как с QEMU, так и с Bochs, так что, надеюсь, вы сможете сравнить, что вы делаете с тем, что делаете, и выяснить, что не так.

QEMU в целом хорош, но я бы порекомендовал Bochs для разработки действительно низкоуровневых программ - он включает (или может быть настроен для включения) очень удобный внутренний отладчик .например, установите reset_on_triple_fault=0 в строке cpu: файла конфигурации, установите точку останова в коде switch_page_directory(), запустите точку останова, затем пошаговые инструкции и посмотрите, что произойдет ...

2 голосов
/ 05 ноября 2011

Вы можете связать qemu с сеансом отладчика GDB с помощью инструментов удаленного отладчика в GDB.Это можно сделать, введя следующие команды:

qemu -s [optional arguments]

Затем в сеансе GDB откройте исполняемый файл ядра и после установки точки останова в функции switch_page_directory() введите следующую команду вприглашение gdb:

target remote localhost:1234

Затем вы можете пошагово пройти через ваше ядро ​​в точке останова и посмотреть, где происходит ваша тройная ошибка.

Еще один шаг, который необходимо рассмотреть, - это на самом делеустановите некоторые обработчики исключений по умолчанию в вашей IDT ... причина, по которой вы совершаете тройной сбой, заключается в том, что CPU выдает исключение, но нет подходящего обработчика исключений для его обработки.Таким образом, с некоторыми установленными обработчиками по умолчанию, особенно с обработчиком двойного сбоя, вы можете эффективно остановить ядро, не переходя в тройной сбой, который автоматически сбрасывает ПК.

Наконец, убедитесь, что вы перепрограммировали PICперед переходом в защищенный режим ... в противном случае аппаратные прерывания по умолчанию, запрограммированные для запуска из BIOS в реальном режиме, теперь будут вызывать прерывания исключений в защищенном режиме.

1 голос
/ 17 июля 2014

Я также столкнулся с той же проблемой в руководстве по подкачке страниц. Но после некоторого поиска я нашел решение, которое происходило, потому что , как только пейджинг включен, все адреса становятся виртуальными , и для их решения мы должны сопоставитьвиртуальные адреса к одним и тем же физическим адресам, поэтому они относятся к одной и той же вещи, и это называется сопоставление идентификаторов.

вы можете перейти по этой ссылке для получения дополнительной помощи в реализацииIdentity Maping.

и еще одна вещь, которую вы установили в mem, - это недавно выделенное пространство на ноль, потому что оно может содержать значения мусора, а memset не было сделано в учебнике, это будет работать на bochs, потому что оно установило пространство на ноль для вас, нодругой эмулятор (qemu) и реальное оборудование очень добры.

...