2015-10-28 18:36:31 +01:00
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
|
|
BEGIN
|
|
|
|
|
CLEAR
|
|
|
|
|
STAGE2
|
|
|
|
|
PROTECTED_MODE
|
2015-11-10 16:52:46 +01:00
|
|
|
IDT_SETUP_ENTRY $14, $interrupt_handler
|
2015-10-28 18:36:31 +01:00
|
|
|
lidt idt_descriptor
|
|
|
|
|
SETUP_PAGING_4M
|
|
|
|
|
|
|
|
|
|
/* Make page 0 not present, so that any access to it will segfault. */
|
2015-11-18 10:20:14 +01:00
|
|
|
andb $0xFE, page_table
|
2015-10-28 18:36:31 +01:00
|
|
|
|
|
|
|
|
PAGING_ON
|
|
|
|
|
/* Access page 0, generating a segfault. */
|
2015-11-18 10:20:14 +01:00
|
|
|
movb $0, 0
|
2015-10-28 18:36:31 +01:00
|
|
|
PAGING_OFF
|
|
|
|
|
|
|
|
|
|
jmp .
|
|
|
|
|
|
|
|
|
|
IDT_START
|
|
|
|
|
IDT_SKIP 14
|
|
|
|
|
IDT_ENTRY
|
|
|
|
|
IDT_END
|
2015-11-10 16:52:46 +01:00
|
|
|
interrupt_handler:
|
2015-10-28 18:36:31 +01:00
|
|
|
VGA_PRINT_STRING $message
|
2018-07-17 09:46:13 +01:00
|
|
|
/* Mandatory because page faults push the error code to the stack.
|
|
|
|
|
*
|
|
|
|
|
* If we don't do this, then the stack will be wrong for iret,
|
|
|
|
|
* likely leading to a general fault exception:
|
|
|
|
|
* http://stackoverflow.com/questions/10581224/why-does-iret-from-a-page-fault-handler-generate-interrupt-13-general-protectio/33398064#33398064
|
|
|
|
|
*/
|
2015-10-28 18:36:31 +01:00
|
|
|
pop %eax
|
|
|
|
|
VGA_PRINT_HEX_4 <%eax>
|
2018-07-17 09:46:13 +01:00
|
|
|
/* Make the page present. because iret will return to before the mov,
|
|
|
|
|
* and we'd get and infinite loop.
|
|
|
|
|
*/
|
2015-11-18 10:20:14 +01:00
|
|
|
orb $1, page_table
|
2015-10-28 18:36:31 +01:00
|
|
|
iret
|
|
|
|
|
message:
|
|
|
|
|
.asciz "Page fault handled. Error code:"
|