diff --git a/06-subroutines-interruptions/fuck-system.c b/06-subroutines-interruptions/fuck-system.c index 1e7248b..cbdcef0 100644 --- a/06-subroutines-interruptions/fuck-system.c +++ b/06-subroutines-interruptions/fuck-system.c @@ -3,8 +3,18 @@ #include #include +// Смотрим у производителя процессора номер прерывания +// деления на ноль (я сижу на x86-64, а этот номер зависит от архитектуры процессора) +#define ZERODIV_NR 0x00 + extern void store_idt(struct desc_ptr *storage); +static void example_handler(void) +{ + pr_warn("entered the handler"); + return; +} + static int __init fuck_system(void) { pr_info("start to fuck system"); @@ -12,12 +22,28 @@ static int __init fuck_system(void) struct desc_ptr newidtreg; struct desc_ptr oldidtreg; gate_desc *oldidt, *newidt; + // Выделяем память под 256 прерываний + unsigned long new_page = __get_free_page(GFP_KERNEL); + if (!new_page) + { + return -ENOMEM; + } store_idt(&oldidtreg); - newidtreg.address = oldidtreg.address; + newidtreg.address = new_page; newidtreg.size = oldidtreg.size; - newidt = (gate_desc *)newidtreg.adress; + newidt = (gate_desc *)newidtreg.address; memcpy(newidt, oldidt, newidtreg.size); + pack_gate( + (newidt + ZERODIV_NR), + GATE_INTERRUPT, + (unsigned long) example_handler, + 0, + 0, + __KERNEL_CS + ); + + load_idt(&newidtreg); pr_info("idt register stored"); return 0; }