Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Languages
 С
 GNU С Library 
 Qt 
 STL 
 Threads 
 C++ 
 Samples 
 stanford.edu 
 ANSI C
 Libs
 LD
 Socket
 Pusher
 Pipes
 Encryption
 Plugin
 Inter-Process
 Errors
 Deep C Secrets
 C + UNIX
 Linked Lists / Trees
 Asm
 Perl
 Python
 Shell
 Erlang
 Go
 Rust
 Алгоритмы
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Linux Kernel 2.6...5164 
 Trees...935 
 Максвелл 3...861 
 Go Web ...815 
 William Gropp...796 
 Ethreal 3...779 
 Ethreal 4...766 
 Gary V.Vaughan-> Libtool...765 
 Rodriguez 6...756 
 Steve Pate 1...749 
 Ext4 FS...748 
 Clickhouse...748 
 Ethreal 1...736 
 Secure Programming for Li...721 
 C++ Patterns 3...712 
 Ulrich Drepper...693 
 Assembler...687 
 DevFS...655 
 Стивенс 9...644 
 MySQL & PosgreSQL...622 
 
  01.01.2024 : 3621733 посещений 

iakovlev.org

Gdt

В интеловской архитектуре для защищенного режима контроль за памятью осуществляется с помощью специальных дескрипторных таблиц . Дескриптор может хранить информацию о каком-то обьекте - задаче , программе и т.д. Перед тем как вы каждый раз делаете запись в сегментный регистр , процессор должен проверить корректность такой записи .

Intel определяет 3 типа таблиц : таблица прерываний - IDT, глобальная таблица дескрипторов - GDT , и локальная таблица дескрипторов - LDT. Таблицы инициализируются с помощью инчструкций lidt, lgdt, lldt. Положение этих таблиц фиксируется еще на этапе загрузки и последующий доступ к ним осуществляется с помощью указателей .

Glossary

Segment
область памяти с заданными свойствами
Segment Register
регистр , ссылающийся на такой сегмент ( ss, cs, ds ...)
Selector
ссылка на дескриптор , загружаемый в сегментный регистр .
Descriptor
структура (строка в таблице)

Что можно сохранить в GDT ?

  • null descriptor
  • code segment descriptor (type=0x9A)
  • data segment descriptor (type=0x92)
  • TSS segment descriptor

GDT имеет следующую структуру :

  • null descriptor
  • dpl 0 code segment descriptor
  • dpl 0 data segment descriptor
  • dpl 3 code segment
  • dpl 3 data segment
  • остальной произвольный набор дескрипторов

dpl 0 code segment загружается в MSR. Остальные вычисляются на его базе . (See the intel instruction reference for SYSENTER and SYSEXIT for more information.)

Flat Setup

Если вам нужны 4GB памяти :

GDT[0]={.base=0, .limit=0, .type=0};              // selector 0 cannot be used
 GDT[1]={.base=0, .limit=0xffffffff, .type=0x9A};  // selector 8 will be our code
 GDT[2]={.base=0, .limit=0xffffffff, .type=0x92};  // selector 0x10 will be our data
 GDT[3]={.base=&myTss, .limit=sizeof(myTss), .type=0x89}; // you can use LTR(0x18)

В данной модели код не очень-то и защищен , потому-что он перекрывается с сегментом данных.

Small Kernel Setup

Если сегменты кода и данных нужно разделить и каждому выделить допустим по 4 метра:

GDT[0]={.base=0, .limit=0, .type=0};              // selector 0 cannot be used
 GDT[1]={.base=0x04000000, .limit=0x03ffffff, .type=0x9A};  // selector 8 will be our code
 GDT[2]={.base=0x08000000, .limit=0x03ffffff, .type=0x92};  // selector 0x10 will be our data
 GDT[3]={.base=&myTss, .limit=sizeof(myTss), .type=0x89}; // you can use LTR(0x18)

Начало кодового сегмента будет начинаться с отметки 4 метров иметь адрес совпадающий с cs:0 , сегмент данных будет начинаться с 8 метров и совпадать с адресом ds:0.

0. Отключение прерываний

Прерывания нужно отключать дабы не было проблем.

1. Заполнение таблиц

Базовый адрес в таблице GDT[] состоит из 3-х частей плюс флаг для установки свойств.

encodeGdtEntry(unsigned char target[8], struct MTGDT source)
 {
    if ((source.limit>64K) && (source.limit&0xfff)!=0xfff))
      kerror("you can't do that!");
    if (source.limit>64K) {
      // adjust granularity if required
      source.limit=source.limit/4096;
      target[6]=0xC0;
    } else target[6]=0x40;
 
    target[0]=source.limit&0xff;
    target[1]=(source.limit>>8)&0xff;
    target[6]|=(source.limit>>16)&0xf;
 
    target[2]=source.base&0xff;
    target[3]=(source.base>>8)&0xff;
    target[4]=(source.base>>16)&0xff;
    target[7]=(source.base>>24)&0xff;
 
    target[5]=source.type;
 }

2. Инициализация таблиц

Это можно сделать с помощью команд lgdt и lidt

real mode

линейный адрес может быть вычислен кака segment*16+offset.

gdtr dw 0 ; for limit storage
      dd 0 ; for base storage
 
 setGdt:
    xor eax,eax
    mov ax, ds
    shl eax, 4
    add eax, GDT
    mov [gdtr+2],eax
    mov eax, GDT_end
    sub eax, GDT
    mov [gdtr],ax
    lgdt [gdtr]
    ret

flat protected mode

gdtr dw 0   ; for limit storage
      dd 0   ; for base storage
 
 setGdt:
    mov eax,[esp+4]
    mov [gdtr+2],eax
    mov ax,[esp+8]
    mov [gdtr],ax
    ldgt [gdtr]
    ret

3. Reload segment registers

Для работы с GDT нужно использовать сегментные регистры

reloadSegments:
    jmp 0x08:here
 .here:
    mov ax,0x10
    mov ds,ax
    mov es,ax
    mov fs,ax
    mov gs,ax
    mov ss,ax
    ret

LDT

Аналогично GDT (global descriptor table), LDT (local descriptor table) состоит из дескрипторов . Каждый процесс имеет свою собственную LDT .

               GDTR (base+limit)
               +-- GDT -----------+
               |                  |
 SELECTOR ---> [LDT descriptor    ]----> LDTR (base+limit)
               |                  |     +---LDT-------------+
               |                  |     |                   |
               ..                 ..    ..                  ..
               +------------------+     +-------------------+

Сегменты

Real mode

В RealMode адрес имеет форму A:B :

Physical address = (A * 0x10) + B

Регистры в real-mode при адресации ограничены 16 битами. 16 бит - это число в диапазоне от 0 до 64k. Эти 64К и называются сегментом.

A = A 64k сегмент
B = смещение внутри сегмента

Базовые адреса сегментов - это чила типа (A * 0x10) .

Т.е. сегмент 0x1000 имеет базовый адрес 0x10000. Этот сегмент простирается в диапазоне 0x10000 -> 0x1FFFF, соответственно сегмент 0x1010 имеет базовый адрес 0x10100 и занимает диапазон физических алресов 0x10100 -> 0x200FF

Имеются 6 сегментных регистров : (CS, DS, ES, FS, GS, SS).

CS = Code Segment DS = Data Segment SS = Stack Segment ES = Extra Segment FS/GS = General Purpose Segments

DS,ES,FS,GS,SS можно смело использовать для работы с памятью .

MOV [SI], AX - базовым сегментным регистром по умолчанию является DS

MOV ES:[DI], AX - здесь базовым сегментным регистром является es

Операции с сегментными регистрами

Кроме CS, сегментные регистры можно загружать из AX (mov ds, ax) или из стека (pop ds).

CS нельзя изменить командой. Его можно изменить при переключении на другой сегментный регистр.

Far Jump
Например JMP 0x10:0x100 грузит CS сегментом 0x10 и IP = 0x100. CS:IP - это логический адрес для инструкции.
INT
Новое значение CS/IP читается из таблицы Interrupt Vector Table .

Protected Mode

Здесь логический адрес используется в форме A:B. Регистры в этом режиме ограничены 32 битами , что дает доступ к 4 гигам памяти.

Отличие защищенного режима от реального в том , что А - это не абсолютное значение , это - selector, который есть смещение в таблице Global Descriptor Table(GDT). GDT состоит из набора таких дескрипторов .

Каждый дескриптор включает в себя следующую информацию :

  • Базовый адрес сегмента
  • Тип сегмента (16-bit/32-bit)
  • Привилегия (Ring 0 -> Ring 3)
  • Байтовое ограничение (Segment limit is in byte/4kb units)
  • Сегментное ограничение (The maximum legal offset within the segment)
  • Тип дескриптора (0 = system; 1 = code/data)
  • Еще один тип(Code/Data/Read/Write/Accessed/Conforming/Non-Conforming/Expand-Up/Expand-Down)

Диапазон физических адресов в сегменте:

Segment Base -> Segment Base + Segment Limit
Physical address = Segment Base (Found from the descriptor GDT[A]) + B
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье
Ольга
  Всё в этой статье вроде и не плохо,но я,задав в поисковой строке idt,не обнаружила того,что меня интересует. 
2006-03-30 11:40:27
Яковлев Се�
  Если набрать в поисковой строке "idt", то будет выведен список из 30 страниц.
В том числе и эта страница.
.

2006-03-30 19:33:19