OSDev

для всех
Текущее время: 28 мар 2024, 23:21

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Менеджер виртуальной памяти
СообщениеДобавлено: 12 июл 2019, 18:54 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Кто подскажет в чём может быть проблема. Написал простенький менеджер памяти. В загрузчике создаю каталог страниц по адресу 10000h, таблицу страниц описывающую первый мегабайт по адресу 11000h, таблицу описывающую физ. страницы ядра 12000h. Затем монтирую первый мегабайт и ядро и перехожу на ядро
Код:
KERNEL_DIR_PAGES_PADDR    = 10000h
ONE_MB_TABLE_PAGES_PADDR = 11000h
KERNEL_PAGES_TABLE_PADDR = 12000h
TEMP_KERNEL_PADDR        = 13000h  ; Временный физический адрес ядра
KERNEL_PADDR             = 100000h ; Физический адрес ядра


Код:
; Настраиваем и включаем страную адресацию
  ; Очищаем каталог страниц
  mov eax,0
  mov edi,KERNEL_DIR_PAGES_PADDR
  mov ecx,1024
  rep stosd
 
  ; Монтируем первый мегабайт
  mov [KERNEL_DIR_PAGES_PADDR], dword ONE_MB_TABLE_PAGES_PADDR+111b ; Вписываем таблицу в каталог
  ; Заполним первую таблицу страниц
  mov eax,11b
  mov ecx,0x100000 / 4096 ; 1MB / page_size = 256 стр.
  mov edi,ONE_MB_TABLE_PAGES_PADDR
  @@:
    stosd
    add eax,0x1000
    loop @b

  ; Монтируем физ. память начиная с KERNEL_PADDR (код ядра) по вирт. адресу KERNEL_ADDR
  mov [KERNEL_DIR_PAGES_PADDR+(KERNEL_ADDR shr 22)*4], dword KERNEL_PAGES_TABLE_PADDR+111b ; Вписываем таблицу в каталог
  ; Заполняем последнюю таблицу
  mov eax, KERNEL_PADDR+11b
  mov ecx, 0x400000/4096 ; 4MB / page_size
  mov edi, KERNEL_PAGES_TABLE_PADDR
  @@:
    stosd
    add eax, 0x1000
    loop @b
   
  ; Устанавливаем текущий каталог таблиц страниц
  mov eax, KERNEL_DIR_PAGES_PADDR
  mov cr3,eax
 
  ; Включаем страничную адресацию
  mov eax,cr0
  or eax,80000000h
  mov cr0,eax
 
  ; копируем ядро по вирт. адресу KERNEL_ADDR
  mov esi,TEMP_KERNEL_PADDR ; Источник
  mov edi,KERNEL_ADDR       ; Назначение
  mov ecx,KERNEL_SIZE       ; Размер
  rep movsb
 
  ; Устанавливаем новый стек
  mov esp, KERNEL_STECK_ADDR 
  ; Передаем управление ядру
  jmp KERNEL_ADDR           


В ядре при инициализации менеджера памяти отображаю каталог страниц по адресу 0xFFFFD000, всё работает до тех пор пока я не пытаюсь отмонтировать первый мегабайт.

Код:
KERNEL_ADDR             = 0xFFC00000      ; Адрес ядра
KERNEL_STECK_ADDR       = 0xFFFDAFFF      ; Адрес стека ядра
IDT_ADDR                = 0xFFFDB000
MEMORY_BMP_ADDR         = 0xFFFDC000      ; Адрес битовой карты памяти (Размер 131072B=32ст.)
VIDEO_BUFF_ADDR         = 0xFFFFC000      ; Адрес видеобуфера
KERNEL_DIR_PAGES_ADDR   = 0xFFFFD000      ; Адрес каталога страниц
;KERNEL_PAGES_TABLE_ADDR = 0xFFFFE000      ; Адрес таблицы со страницами ядра
TEMP_PAGE_ADDR          = 0xFFFFF000      ; Адрес временной страницы
KERNEL_SIZE             = 4096*2            ; Размер ядра в байтах
KERNEL_SEC_ID           = BOOT_CONT_SEC_ID+(BOOT_CONT_SIZE/512) ; LBA номер первого сектора ядра


Код:
; Маска 20 старших установленных бит
MASK_HEIGHT_BITS_20 = 0FFFFF000h
; Маска 10 младших установленных бит
MASK_LOW_BITS_10 = 3FFh
; Извлекаем из адреса номер PDE дескриптора
TEMP_PAGE_PDE_ID = (TEMP_PAGE_ADDR shr 22)         
; Извлекаем из адреса номер PTE дескриптора
TEMP_PAGE_PTE_ID = (TEMP_PAGE_ADDR shr 12) and MASK_LOW_BITS_10

kernel_dir_pages dd KERNEL_DIR_PAGES_PADDR

macro vmm.init
{
  pmm.init
  ; Спроецировать физ. адрес каталога страниц по адресу KERNEL_DIR_PAGE_ADDR
  vmm.map_page KERNEL_DIR_PAGES_PADDR, KERNEL_DIR_PAGES_ADDR
  mov [kernel_dir_pages],KERNEL_DIR_PAGES_ADDR
  ; Отмонтировать первый МБ
  ; vmm.unmount_one_mb ; После этого всё ломается и ребутится
}

; Отображение физ. страницы во временную вирт. страницу
; page_paddr - физ. адрес страницы
macro vmm.map_temp_page page_paddr
{
  push eax
  mov eax,page_paddr
  call vmm_map_temp_page
  pop eax
}

; Отображение физ. страниц на вирт. адреса
; page_paddr - физ. адрес страницы
; page_addr  - вирт. адрес страницы
macro vmm.map_page page_paddr, page_addr
{
  push ecx esi
  mov ecx,page_paddr
  mov esi,page_addr
  call vmm_map_page
  pop esi ecx
}

macro vmm.unmount_one_mb
{
  push eax esi edi
  vmm.map_temp_page ONE_MB_TABLE_PAGES_PADDR
  mov eax,0
  mov esi,0
  mov edi,TEMP_PAGE_ADDR
  mov ecx,100000h/PMM_PAGE_SIZE
  @@:
    mov [edi],dword 0
    add edi,4
    invlpg [esi]
    add esi,1000h
    loop @b
  ; Устанавливаем текущий каталог таблиц страниц
  pop edi esi eax
}

; Отображение физ. страницы во временную вирт. страницу
; EAX - физ. адрес страницы
vmm_map_temp_page:
  push eax ebx esi
  mov ebx,[kernel_dir_pages]       ; EAX = адрес директории страниц
  add ebx,TEMP_PAGE_PDE_ID*4       ; Прибавляем к адресу дир. смещение PDE дескриптора
  mov esi,[ebx]                    ; Читаем содержимое дескриптора в ESI
  and esi,MASK_HEIGHT_BITS_20      ; Преобразуем содержимое дескриптора в адрес таблицы страниц
  add eax,11b                      ; Добовляем атрибуты к физ. адресу, получаем дескриптор
  mov [esi+TEMP_PAGE_PTE_ID*4],eax ; Прибавляем к адресу таблицы смещение PTE дескриптора, вписываем дескриптор
  invlpg [TEMP_PAGE_ADDR]
  pop esi ebx eax
  ret

; Отображение физ. страницы на виртуальную
; ECX - Адрес физ. страницы
; ESI - Адрес вирт. страницы
vmm_map_page:
  push eax ecx esi edi
  invlpg [esi]
  mov edi,esi
  shr esi,22                   ; Извлекаем из адреса номер PDE дескриптора
  shl esi,2                    ; Умножаем его на 4 и получаем смещение в директории страниц
  shl edi,10                   ; Извлекаем из адреса номер PTE дескриптора
  shr edi,22 
  shl edi,2                    ; Умножаем его на 4 и получаем смещение в таблице страниц
  add esi,[kernel_dir_pages]   ; Прибавляем к адресу дир. смещение PDE дескриптора
  mov eax,[esi]                ; Прочитаем PDE дескриптор в EAX
  ; Проверяем присутствие таблицы страниц в каталоге
  cmp eax,0                    ; Если дескриптор пуст то таблица отсутствует, нужно создать ее,
  jnz @f                       ; иначе переходим к изменению существующей таблицы
  ; Создание таблицы
  pmm.alloc_page               ; Выделяем физ. страницу под таблицу
  add eax,111b                 ; Добавляем атрибуты и
  mov [esi],eax                ; заносим ее в каталог
  @@:
  and eax,MASK_HEIGHT_BITS_20  ; Преобразуем содержимое дескриптора в адрес таблицы страниц
  call vmm_map_temp_page       ; Отображаем таблицу во временную страницу
  add ecx,11b                  ; Добовляем атрибуты к физ. адресу, получаем дескриптор
  mov [TEMP_PAGE_ADDR+edi],ecx ; Прибавляем к адресу таблицы смещение PTE дескриптора, вписываем дескриптор
  pop edi esi ecx eax
  ret


Если я от монтирую первый мегабайт то при мапировании физ. страниц в виртуальные, при обращении к ним система перезагружаеться. Также система перезагружается при включении прерываний, хотя если первый мегабайт не трогать всё нормально работает.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 13 июл 2019, 00:44 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
FreeProger писал(а):
Код:
KERNEL_ADDR             = 0xFFC00000      ; Адрес ядра
KERNEL_STECK_ADDR       = 0xFFFDAFFF      ; Адрес стека ядра
IDT_ADDR                = 0xFFFDB000
MEMORY_BMP_ADDR         = 0xFFFDC000      ; Адрес битовой карты памяти (Размер 131072B=32ст.)
VIDEO_BUFF_ADDR         = 0xFFFFC000      ; Адрес видеобуфера
KERNEL_DIR_PAGES_ADDR   = 0xFFFFD000      ; Адрес каталога страниц
;KERNEL_PAGES_TABLE_ADDR = 0xFFFFE000      ; Адрес таблицы со страницами ядра
TEMP_PAGE_ADDR          = 0xFFFFF000      ; Адрес временной страницы
KERNEL_SIZE             = 4096*2            ; Размер ядра в байтах
KERNEL_SEC_ID           = BOOT_CONT_SEC_ID+(BOOT_CONT_SIZE/512) ; LBA номер первого сектора ядра


Суть действа и алгоритм сам по себе мало понятен. В комментариях желательно уточнять Адрес - Физ. адрес - Вирт. адрес...
Нету особого смысла временно отображать структуры ядра. Можно делать все данные в постоянной доступности. Первый мегабайт уж точно не обязательно выключать, там наверняка лежат части твоей системы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 13 июл 2019, 06:55 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Цитата:
В комментариях желательно уточнять Адрес - Физ. адрес - Вирт. адрес...

Я попытался включить это в само название канстант и переменных, если заканчивается на PADDR то это физ. Адрес, если просто ADDR то виртуальный. Суть действа в том что бы освободить адресное пространство от нуля. Я если честно пока что сам не уверен что это нужно. Просто считал что с нуля будет адресное пространство процессов. В первом МБ по идеи не должно остаться необходимых структур. В нем находятся таблицы с самим первым МБ, с каталогом страниц и с таблицей страниц ядра. При инициализации менеджера памяти пока ещё первый МБ доступен я отображаю каталог в пространство ядра, потом я отмонтирую мегабайт и могу обращаться к каталогу через отображенный адрес, вроде мне не чего из первого МБ больше не нужно. Но после от монтирования ядро работает а вот мапирование страниц перестаёт работать, не мапируются новые адреса, видимо из за этого не мапируются таблица прерываний.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 13 июл 2019, 13:31 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Опытным путём выяснил что проблема возникает лишь тогда когда я отмонтирую страницу с каталогом страниц или
страницу с таблицей страниц первого мегабайта.
Код:
KERNEL_DIR_PAGES_PADDR   = 11000h  ; Физ. адрес каталога таблиц страниц
ONE_MB_TABLE_PAGES_PADDR = 12000h  ; Физ. адрес таблицы страниц первого мегабайта

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 13 июл 2019, 22:20 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Небольшая заметка про
KERNEL_STECK_ADDR = 0xFFFDAFFF ; Адрес стека ядра
Стек по-английски пишется через A
и должен быть выровнен хотя бы на 4, а при использовании сопроцессора так вообще на 8 или 16 байт в зависимости от размера чисел.
KERNEL_STACK_ADDR = 0xFFFDB000


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 14 июл 2019, 12:40 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Да я понакосячил с распределением вирт. адресов. Переделал, но проблема не ушла.
Код:
KERNEL_ADDR             = 0xFFC00000 ; Вирт. адрес ядра
KERNEL_STACK_ADDR       = 0xFFFDB000 ; Вирт. адрес стека ядра
IDT_ADDR                = 0xFFFDC000 ; Вирт. адрес таблицы прерывани
VIDEO_BUFF_ADDR         = 0xFFFDD000 ; Вирт. адрес видеобуфера
KERNEL_DIR_PAGES_ADDR   = 0xFFFDE000 ; Вирт. адрес каталога страниц
MEMORY_BMP_ADDR         = 0xFFFDF000 ; Вирт. адрес битовой карты памяти (Размер 131072B=32ст.)
TEMP_PAGE_ADDR          = 0xFFFFF000 ; Вирт. адрес временной страницы
KERNEL_SIZE             = 8192       ; Размер ядра в байтах
KERNEL_SEC_ID           = BOOT_CONT_SEC_ID+(BOOT_CONT_SIZE/512) ; LBA номер первого сектора ядра


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 15 июл 2019, 16:12 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Вроде разобрался с менеджером памяти, все правильно работает. После от монтирования первого мегабайта менеджер работает исправно. Но когда я активирую обработчики прерываний, система ребутится. Причём если его не отмонтировать все исправно работает. Либо если отмонтировать а потом примонтировать обратно лишь первую страницу, первые 4К то все норм. Кто может подсказать, для чего прерываниям может понадобиться первые 4К? И ещё вопрос нужно ли вообще отмонтировать первый мегабайт если я хочу что бы адресное пространство процессов начиналось от нуля?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 15 июл 2019, 18:50 

Зарегистрирован: 16 апр 2019, 17:15
Сообщения: 11
Цитата:
для чего прерываниям может понадобиться первые 4К?

А где у Вас лежит таблица (или вектор) прерываний?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 15 июл 2019, 19:22 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
FreeProger писал(а):
И ещё вопрос нужно ли вообще отмонтировать первый мегабайт если я хочу что бы адресное пространство процессов начиналось от нуля?
Вопрос звучит не совсем корректно. Дело в том, что при создании пользовательского процесса надо создавать новый каталог страниц, и новые таблицы страниц, и на этапе создания указываешь для нулевой виртуальной страницы любой свободный физический адрес за пределами первого мегабайта. Отмонтировать ни чего не приходится. Впрочем, нулевую страницу вообще ни куда не монтируют, а оставляют пустой, для отлова ошибок обращения по нулевому (пустому) адресу с помощью исключения Page fault.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Менеджер виртуальной памяти
СообщениеДобавлено: 15 июл 2019, 20:03 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Цитата:
А где у Вас лежит таблица (или вектор) прерываний?



Место под таблицу выделяется менеджером памяти, он выделяет первую попавшуюся свободную страницу. Проверял, выделяет правильно. Выше первого МБ и не занятые ядром. В данный момент вывел этот адрес 102000h, по адресу 100000h до 102000h у меня лежит ядро.
Код:
macro int.init
{
  push eax
  mm.alloc_page ; EAX <- Free page paddr
  mm.map_page eax, IDT_ADDR, PAGE_PRESENT or PAGE_WRITE
 
  ci_8259A.init ; Инициализация контроллера прерываний 8259A
 
  ; Обработчики исключений (нарушений, ловушек и аварий)
  int.set_handler 0,  exc_0, GATE_P+GATE_TRAP        ; #DE Нарушение. Ошибка деления, код ошибки-нет. Вызвано: div, idiv
  int.set_handler 1,  exc_1, GATE_P+GATE_TRAP        ; #DB Нарушение/Ловешка. Исключение отладки. Код ошибки-нет.
  int.set_handler 2,  exc_2, GATE_P+GATE_INT         ; Немаскируемые прерывания поступающие на порт NMI. (Аппаратный сбой)
  int.set_handler 3,  exc_3, GATE_P+GATE_TRAP        ; #BP Ловушка. Программное прерывание служащее для отладки. Вызвано: int 3
  int.set_handler 4,  exc_4, GATE_P+GATE_TRAP        ; #OF Ловушка. Фиксирует арефметическое переполнение(overflow). Код ошибки-нет. Вызвано: into
  int.set_handler 5,  exc_5, GATE_P+GATE_TRAP        ; #BR Нарушение. Нарушение границ массива. Код ошибки-нет. Вызвано: bound
  int.set_handler 6,  exc_6, GATE_P+GATE_TRAP        ; #UD Нарушение. Недопустимый код команды. Код ошибки-нет.
  int.set_handler 7,  exc_7, GATE_P+GATE_TRAP        ; #NM Нарушение. Сопроцессор не доступен. Код ошибки-нет. Вызвано: esc, wait
  int.set_handler 8,  exc_8, GATE_P+GATE_TRAP        ; #DF Авария. Двойное нарушение. Код ошибки-да
  int.set_handler 9,  0, 0                           ; Авария. Выход сопроцессора из сегмента. Код ошибки-нет
  int.set_handler 10, exc_10, GATE_P+GATE_TRAP       ; #TS Нарушение. Недопуст. сегмент состояния задачи TSS. Ошибка-да. Выз. jmp, call, iret, прерывание
  int.set_handler 11, exc_11, GATE_P+GATE_TRAP       ; #NP Нарушение. Отсутствие сегмента. Ошибка-да. Выз. команда загрузки сегмент. регистра
  int.set_handler 12, exc_12, GATE_P+GATE_TRAP       ; #SS Нарушение. Ошибка обращения к стеку. Код ошибки-да. Вызвано: командой обращения к стеку
  int.set_handler 13, exc_13, GATE_P+GATE_TRAP       ; #GP Нарушение. Общая защита. Код ошибки-да. Вызвано: команда обращения к памяти
  int.set_handler 14, exc_14, GATE_P+GATE_TRAP       ; #PF Нарушение. Страничное нарушение. Код ошибки-да. Вызвано: команда обращения к памяти
  int.set_handler 15, 0, 0                           ; Не используется
  int.set_handler 16, exc_16, GATE_P+GATE_TRAP       ; #MF Нарушение. Сопроцессор не доступен. Код ошибки-нет. Вызвано: esc, wait
  int.set_handler 17, exc_17, GATE_P+GATE_TRAP       ; #AC Нарушение. Ошибка выравнивания. Код ошибки-да. Вызвано: команда обращения к памяти
  ; 18-31 Зарезервировано
  ; Аппаратные прерывания (Hardware interrupts) от ведущего контроллера 8259A
  int.set_handler 32, int8_handler, GATE_P+GATE_INT  ; IRQ0 — программируемый интервальный таймер или высокоточный таймер событий №0
  int.set_handler 33, int9_handler, GATE_P+GATE_INT  ; IRQ1 — клавиатура PS/2
  int.set_handler 34, int_EOI, GATE_P+GATE_INT       ; IRQ2 — запрос прерывания от ведомого контроллера прерываний (8259A - Slave)
  int.set_handler 35, int_EOI, GATE_P+GATE_INT       ; IRQ3 — произвольное устройство (в IBM PC/AT — последовательный порт COM2 и COM4)
  int.set_handler 36, int_EOI, GATE_P+GATE_INT       ; IRQ4 — произвольное устройство (в IBM PC/AT — последовательный порт COM1 и COM3)
  int.set_handler 37, int_EOI, GATE_P+GATE_INT       ; IRQ5 — произвольное устройство (в IBM PC/AT — параллельный порт LPT2)
  int.set_handler 38, int_EOI, GATE_P+GATE_INT       ; IRQ6 — произвольное устройство (в IBM PC/AT — контроллер гибких дисков)
  int.set_handler 39, int_EOI, GATE_P+GATE_INT       ; IRQ7 — произвольное устройство (в IBM PC/AT — параллельный порт LPT1)
  ; Аппаратные прерывания (Hardware interrupts) от ведомого контроллера 8259A (линии шины ISA)
  int.set_handler 40, int_EOI, GATE_P+GATE_INT       ; IRQ8 — часы реального времени или высокоточный таймер событий №1
  int.set_handler 41, int_EOI, GATE_P+GATE_INT       ; IRQ9 — произвольное устройство
  int.set_handler 42, int_EOI, GATE_P+GATE_INT       ; IRQ10 — произвольное устройство
  int.set_handler 43, int_EOI, GATE_P+GATE_INT       ; IRQ11 — произвольное устройство или высокоточный таймер событий №2
  int.set_handler 44, int_EOI, GATE_P+GATE_INT       ; IRQ12 — произвольное устройство, обычно мышь PS/2, либо высокоточный таймер событий №3
  int.set_handler 45, int_EOI, GATE_P+GATE_INT       ; IRQ13 — ошибка арифметического сопроцессора
  int.set_handler 46, int_EOI, GATE_P+GATE_INT       ; IRQ14 — произвольное устройство, обычно первый контроллер ATA (или контроллер Serial ATA в режиме совместимости
  int.set_handler 47, int_EOI, GATE_P+GATE_INT       ; IRQ15 — произвольное устройство, обычно второй контроллер ATA (или контроллер Serial ATA в режиме совместимости)                                             
  ; Программные прерывания (Software interrupts)
  int.set_handler 48,  syscall_handler, GATE_P+GATE_DPL3+GATE_TRAP ; Ловушка. Печать строки
  ;---------------------------------------------------------------------------------------------------------------
 
  lidt  [IDTR] ; загружаем регистр IDTR.
 
  ; разрещаем аппаратные прерывания и NMI
  in  al,70h
  and al,7Fh
  out 70h,al ; разрешить NMI прерывания
  sti        ; Разрешить аппаратные прерывания
 
  pop eax
}

IDTR:
    .size dw (256*8)-1 ; Размер IDT таблицы
    .addr dd IDT_ADDR  ; Адрес IDT таблицы

; Добавить шлюз прерывания в IDT
; int_id  - Номер прерывания (1 байт)
; handler - Адресс обработчика прерывания (Смещение в сегменте) (4 байта)
; attr    - Атрибуты. Бит присутствия, уровень привилегий, storageSegment, тип шлюза
macro int.set_handler int_id, handler, attr
{
  push eax ebx ecx
  mov eax,int_id
  mov ebx,handler
  mov ecx,attr
  call int_set_handler
  pop ecx ebx eax
}

; Добавить шлюз прерывания в IDT
; eax - Номер прерывания (1 байт)
; ebx - Адресс обработчика прерывания (Смещение в сегменте) (4 байта)
; ecx - Атрибуты. Бит присутствия, уровень привилегий, storageSegment, тип шлюза
int_set_handler:
  push ebx
  mov word [IDT_ADDR + (eax*8)],bx          ; Записываем младшую часть адреса
  shr ebx, 16                               ; Сдвигаем старшую часть адреса в BX
  mov word [IDT_ADDR + (eax*8) + 6],bx      ; Записываем старшую часть адреса
  mov word [IDT_ADDR + (eax*8) + 2],SL_CODE ; Записываем селектор сегмента
  mov byte [IDT_ADDR + (eax*8) + 4],0       ; Пустой. Если это шлюз вызова то младшие 5 бит это количество параметров, старшие 3 бита = 0
  mov byte [IDT_ADDR + (eax*8) + 5],cl      ; Установка параметров шлюза прерывания
  pop ebx
  ret




Последний раз редактировалось FreeProger 15 июл 2019, 20:47, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB