Перехват 3-его прерывания в модуле ядра под FreeBSD.
Но он этого не делает. При запуске выводится сообщение что тип сегмента то 0xe то ещё что нибудь. При этом ничего не падает, но и проги отлаживаются нормально. Код частично взят из исходников FreeBSD. Подскажите, где у меня ошибка.
Заранее благодарен.
t.gd_looffset = (int)func;
Я бы на сиху не надеялся, а сделал бы ((unsigned)func & 0xffff)
Аналогично тут:
t.gd_hioffset = ((unsigned)func)>>16;
Во-вторых лучше сделать не так
unsigned gd_type:5 ;
а так:
unsigned gd_type:4 ;
unsigned gd_xx2:1; // значение по умолчанию 0, хотя может быть любым
по аналогичным причинам.
Попробывал, не помогло...
А результат работы printf-ов можете привести?
idt: 0xc091b280
looffset:b9bc selector8 :stkpy:0 xx:0 type:e dpl:0 p:1 hioffset:c07b
looffset:8418 selector8 :stkpy:0 xx:0 type:f dpl:0 p:1 hioffset:0
выгрузил и загрузил:
idt: 0xc091b280
looffset:b9bc selector8 :stkpy:0 xx:0 type:e dpl:0 p:1 hioffset:c07b
looffset:8418 selector8 :stkpy:0 xx:0 type:f dpl:0 p:1 hioffset:0
выгрузил и загрузил:
idt: 0xc091b280
looffset:b9bc selector8 :stkpy:0 xx:0 type:e dpl:0 p:1 hioffset:c07b
looffset:8418 selector8 :stkpy:0 xx:0 type:f dpl:0 p:1 hioffset:0
что интересно, значение всех полей остаётся неизменным после записи, но адрес idt постоянен.
looffset:b9bc selector8 :stkpy:0 xx:0 type:e dpl:0 p:1 hioffset:c07b
looffset:8418 selector8 :stkpy:0 xx:0 type:f dpl:0 p:1 hioffset:0
Итого ваш обработчик дожен находиться по адресу
0x00008418
А старый обработчик находится по адресу
0xc07bb9bc
У вас указан относительный адрес к обработчику (тот что прописан в самом модуле), а вам надо указать адрес с учетом GOT
Сдесь возможно несколько причин:
1. модуль компилируется без учета динамического позиционирования кода (это опция в компиляторе)
2. модуль линкуется без создания GOT
Меня беспокоит другое: параметры обработчика не мняются после загрузки и выгрузки модуля
Хотелось бы увидеть новый вариант исходника модуля если это можно.
Мне честно говоря и не нужно, что бы idt возвращалась в прежнее состояние. Модуль я доделал и теперь он действительно перехватывает прерывание.Но есть проблема: при вызове int 3 с уровня пользователь ядро падает в GP.
Что бы ядро не падало в GP надо в бинарнике менять ret на iret (0xc3 на 0xcf), но при этом вызов int3 с уровня пользователя заканчивается SEGMENTATION FAULT с адресом возврата 0. Как бы это исправить?