Protected Mode — Änderungen 4786 → 4835

Zeile 72: Zeile 72:
 
Hier wird festgelegt welcher Typ(Code,Daten,Stack,System) Segment vorliegt und wie Zugriffsrechte für dieses Segment aussehen.
 
Hier wird festgelegt welcher Typ(Code,Daten,Stack,System) Segment vorliegt und wie Zugriffsrechte für dieses Segment aussehen.
  
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
<center>
 +
{| {{prettytable}}
 
|+ Zugriff/Segmenttyp (BITs)
 
|+ Zugriff/Segmenttyp (BITs)
 
|-
 
|-
−
| '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''
+
! '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''
 
|-
 
|-
 
|P
 
|P
Zeile 83: Zeile 84:
 
|A
 
|A
 
|}
 
|}
 +
</center>
  
  
Zeile 105: Zeile 107:
 
Die Bits in diesem Feld geben ebenfalls Charakteristika für das Segment an.
 
Die Bits in diesem Feld geben ebenfalls Charakteristika für das Segment an.
  
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
<center>
 +
{| {{prettytable}}
 
|+  Zusatz (BITs)
 
|+  Zusatz (BITs)
 
|-
 
|-
−
| '''7''' || '''6''' || '''5''' || '''4'''
+
! '''7''' || '''6''' || '''5''' || '''4'''
 
|-
 
|-
 
|G
 
|G
Zeile 115: Zeile 118:
 
|AVL
 
|AVL
 
|}
 
|}
 +
</center>
  
 
====G = Granular Bit====
 
====G = Granular Bit====
Zeile 134: Zeile 138:
 
Hier eine Tabelle der normalen Segmenttypen. Systemsegmente werden später erläutert.
 
Hier eine Tabelle der normalen Segmenttypen. Systemsegmente werden später erläutert.
  
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
<center>
 +
{| {{prettytable}}
 
|-
 
|-
−
| '''TYPE-Feld (BITs)''' || '''Beschreibung'''
+
! '''TYPE-Feld (BITs)''' || '''Beschreibung'''
 
|-
 
|-
 
|000
 
|000
Zeile 163: Zeile 168:
 
|-
 
|-
 
|}
 
|}
 +
</center>
  
 
Sicherlich sind ein paar Erklärungen zu einzelnen Segmenttypen notwendig, weshalb ich das hier auch gleich mache:
 
Sicherlich sind ein paar Erklärungen zu einzelnen Segmenttypen notwendig, weshalb ich das hier auch gleich mache:
Zeile 191: Zeile 197:
 
Dies ist ebenfalls ein Speicherabschnitt der Daten beinhaltet um das Multitasking zu realisieren. Bei einem Task-Wechsel müssen alle Register des gerade laufenden Task gesichert werden, um diese später wiederherstellen zu können, damit der Task wieder gestartet werden kann. Das TSS beinhaltet alle Daten die für einen Task gespeichert werden. Daher ist es notwendig, das jeder Task ein eigenes TSS bekommt. Das TSS hat eine Größe von 104 Bytes. Sollte bei dem Deskriptor als Größe ein kleinerer Wert eingetragen werden, so wird beim Versuch den Deskriptor zu laden eine Exception ausgelöst.
 
Dies ist ebenfalls ein Speicherabschnitt der Daten beinhaltet um das Multitasking zu realisieren. Bei einem Task-Wechsel müssen alle Register des gerade laufenden Task gesichert werden, um diese später wiederherstellen zu können, damit der Task wieder gestartet werden kann. Das TSS beinhaltet alle Daten die für einen Task gespeichert werden. Daher ist es notwendig, das jeder Task ein eigenes TSS bekommt. Das TSS hat eine Größe von 104 Bytes. Sollte bei dem Deskriptor als Größe ein kleinerer Wert eingetragen werden, so wird beim Versuch den Deskriptor zu laden eine Exception ausgelöst.
  
−
 
+
<center>
−
{| border="1" align="center" cellpadding="5" cellspacing="0"
+
{| {{prettytable}}
 
! Offset || 31-16                || 0-15
 
! Offset || 31-16                || 0-15
 
|-
 
|-
Zeile 247: Zeile 253:
 
| 0x64  || I/O Map Base Address ||
 
| 0x64  || I/O Map Base Address ||
 
|}
 
|}
 +
</center>
  
−
 
+
<center>
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
{| {{prettytable}}
 
|+ Task State Segment Deskriptor (BITs) Teil 1
 
|+ Task State Segment Deskriptor (BITs) Teil 1
 
|-
 
|-
−
| ''' 31 - 24''' || '''23''' || '''21 - 22''' || '''20''' || '''19 - 16''' || '''15''' || '''13 - 14''' || '''12''' || ''' 11 - 8'''
+
! ''' 31 - 24''' || '''23''' || '''21 - 22''' || '''20''' || '''19 - 16''' || '''15''' || '''13 - 14''' || '''12''' || ''' 11 - 8''' || ''' 0 - 7 '''
−
|| ''' 0 - 7 '''
 
 
|-
 
|-
 
|Basisadresse 31-24
 
|Basisadresse 31-24
Zeile 266: Zeile 272:
 
|Basisadresse 16-23
 
|Basisadresse 16-23
 
|}
 
|}
 +
</center>
  
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
<center>
 +
{| {{prettytable}}
 
|+ Task State Segment Deskriptor (BITs) Teil 2
 
|+ Task State Segment Deskriptor (BITs) Teil 2
 
|-
 
|-
−
| '''31 - 24''' || '''16 - 0'''
+
! '''31 - 24''' || '''16 - 0'''
 
|-
 
|-
 
|Basisadresse 15 - 0
 
|Basisadresse 15 - 0
 
|Größe 15 - 0
 
|Größe 15 - 0
 
|}
 
|}
 +
</center>
  
 
====Type = Deskriptor Typ====
 
====Type = Deskriptor Typ====
Zeile 285: Zeile 294:
 
In der Regel ist es so, das lediglich das Betriebssystem das mit der Privilegstfue 0 arbeitet zugang zu der Hardware und dem gesamten Speicher hat. Ein Benutzerprogramm, das für gewöhnlich mit der Privilegstufe 3 arbeitet, ist daher sehr eingeschränkt und darf von Haus aus lediglich Standardbefehle ausführen und auch nur Daten im eigenen Adressraum verändern und benutzen. Folglich wäre das Benutzerprogramm sehr unattraktiv und hätte kaum einen nützlichen Verwendungszweck. Daher gibt es die Call Gates. Das sind Deskriptoren in der GDT, die auf ein Codesegment zeigen das eine höhere Privilegstufe besitzt als das Benutzerprogramm. Das Benutzerprogramm kann nun einen Call zu diesem Call Gate machen, was zur Folge hat das es dem Benutzerprogramm gestattet wird, Code in einer höheren Privilegstufe auszuführen. Dieser Code stammt jedoch nicht vom Benutzerprogramm selbst, sondern vom Betriebssystem oder einem Treiber. Außerdem definiert ein Call Gate nicht nur das Code Segment in dem sich der ausführbare, höher privilegierte Code, befindet, sondern auch die genaue Adresse. Sprich das Offset des Codes innerhalb des Segmentes. Somit ist es möglich einem Benutzerprogramm auf eine kontrollierte Art und Weise Zugang zu Systemfunktionen zu gewähren. Hier gibt es noch eine kleine Besonderheit die zu beachten ist. Bei einem Wechsel der Privilegstufe, der für gewöhnlich die Folge eines Call Gate Aufrufs ist, wird ein anderer Stack benutzt. Für jeden Task gibt es für jede Privilegstufe einen eigenen Stack. Damit nun Parameter die VOR dem Call Gate Aufruf auf den alten Stack gepusht wurden, auch in dem neuen Segment benutzt werden können, werden diese beim Aufruf des Call Gates vom alten Stack in den neuen Stack kopiert. Der Deskriptor des Call Gates beinhaltet ein Feld das angibt, wie viele Parameter zwischen den Stacks kopiert werden sollen. Wenn die Routine in dem neuen Segment abgearbeitet wurde und mittels des RET Befehls wieder zurückgesprungen wird, wird wieder der Stack gewechselt und das Programm erhält wieder seine ursprüngliche Privilegstufe.
 
In der Regel ist es so, das lediglich das Betriebssystem das mit der Privilegstfue 0 arbeitet zugang zu der Hardware und dem gesamten Speicher hat. Ein Benutzerprogramm, das für gewöhnlich mit der Privilegstufe 3 arbeitet, ist daher sehr eingeschränkt und darf von Haus aus lediglich Standardbefehle ausführen und auch nur Daten im eigenen Adressraum verändern und benutzen. Folglich wäre das Benutzerprogramm sehr unattraktiv und hätte kaum einen nützlichen Verwendungszweck. Daher gibt es die Call Gates. Das sind Deskriptoren in der GDT, die auf ein Codesegment zeigen das eine höhere Privilegstufe besitzt als das Benutzerprogramm. Das Benutzerprogramm kann nun einen Call zu diesem Call Gate machen, was zur Folge hat das es dem Benutzerprogramm gestattet wird, Code in einer höheren Privilegstufe auszuführen. Dieser Code stammt jedoch nicht vom Benutzerprogramm selbst, sondern vom Betriebssystem oder einem Treiber. Außerdem definiert ein Call Gate nicht nur das Code Segment in dem sich der ausführbare, höher privilegierte Code, befindet, sondern auch die genaue Adresse. Sprich das Offset des Codes innerhalb des Segmentes. Somit ist es möglich einem Benutzerprogramm auf eine kontrollierte Art und Weise Zugang zu Systemfunktionen zu gewähren. Hier gibt es noch eine kleine Besonderheit die zu beachten ist. Bei einem Wechsel der Privilegstufe, der für gewöhnlich die Folge eines Call Gate Aufrufs ist, wird ein anderer Stack benutzt. Für jeden Task gibt es für jede Privilegstufe einen eigenen Stack. Damit nun Parameter die VOR dem Call Gate Aufruf auf den alten Stack gepusht wurden, auch in dem neuen Segment benutzt werden können, werden diese beim Aufruf des Call Gates vom alten Stack in den neuen Stack kopiert. Der Deskriptor des Call Gates beinhaltet ein Feld das angibt, wie viele Parameter zwischen den Stacks kopiert werden sollen. Wenn die Routine in dem neuen Segment abgearbeitet wurde und mittels des RET Befehls wieder zurückgesprungen wird, wird wieder der Stack gewechselt und das Programm erhält wieder seine ursprüngliche Privilegstufe.
  
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
<center>
 +
{| {{prettytable}}
 
|+ Call Gate (BITs) Teil 1
 
|+ Call Gate (BITs) Teil 1
 
|-
 
|-
−
| ''' 31 - 16''' || '''15''' || '''14 - 13''' || '''12''' || '''11 - 8''' || '''7 - 5''' || '''4 - 0'''
+
! ''' 31 - 16''' || '''15''' || '''14 - 13''' || '''12''' || '''11 - 8''' || '''7 - 5''' || '''4 - 0'''
 
|-
 
|-
 
|Offset 31 - 16
 
|Offset 31 - 16
Zeile 298: Zeile 308:
 
|Param
 
|Param
 
|}
 
|}
 +
</center>
  
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
<center>
 +
{| {{prettytable}}
 
|+ Call Gate (BITs) Teil 2
 
|+ Call Gate (BITs) Teil 2
 
|-
 
|-
−
| '''31 - 24''' || '''16 - 0'''
+
! '''31 - 24''' || '''16 - 0'''
 
|-
 
|-
 
|Selektor
 
|Selektor
 
|Offset 15 - 0
 
|Offset 15 - 0
 
|}
 
|}
 +
</center>
  
  
Zeile 340: Zeile 353:
 
Diese haben in etwa den selben Sinn und Zweck eines Call Gates. Jedoch werden diese in der IDT abgelegt und ein Sprung zu einem Interrupt-Handler erfolgt mittels des Int Befehls. Zudem sind die Interrupt Gates hauptsächlich dazu gedacht Systemfunktionen bereitzustellen, mit der auf das Auftreten eines Hardware-Interrupts reagiert wird. Deshalb wird beim Aufurf eines Interrupt Gates auftomatisch das IF Flag im EFLAGS Register geändert, damit während der Abarbeitung des Interrupt Handlers kein weiterer Interrupt ausgelöst werden kann.
 
Diese haben in etwa den selben Sinn und Zweck eines Call Gates. Jedoch werden diese in der IDT abgelegt und ein Sprung zu einem Interrupt-Handler erfolgt mittels des Int Befehls. Zudem sind die Interrupt Gates hauptsächlich dazu gedacht Systemfunktionen bereitzustellen, mit der auf das Auftreten eines Hardware-Interrupts reagiert wird. Deshalb wird beim Aufurf eines Interrupt Gates auftomatisch das IF Flag im EFLAGS Register geändert, damit während der Abarbeitung des Interrupt Handlers kein weiterer Interrupt ausgelöst werden kann.
  
−
 
+
<center>
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
{| {{prettytable}}
 
|+ Interrupt Gate (BITs) Teil 1
 
|+ Interrupt Gate (BITs) Teil 1
 
|-
 
|-
−
| ''' 31 - 16''' || '''15''' || '''14 - 13''' || '''12''' || ''' 11 ''' || '''10 - 8''' || '''7 - 0'''
+
! ''' 31 - 16''' || '''15''' || '''14 - 13''' || '''12''' || ''' 11 ''' || '''10 - 8''' || '''7 - 0'''
 
|-
 
|-
 
|Offset 31 - 16
 
|Offset 31 - 16
Zeile 354: Zeile 367:
 
|0
 
|0
 
|}
 
|}
 +
</center>
  
−
{|border="1" align="center" cellpadding="5" cellspacing="0"
+
<center>
 +
{| {{prettytable}}
 
|+ Interrupt Gate (BITs) Teil 2
 
|+ Interrupt Gate (BITs) Teil 2
 
|-
 
|-
−
| '''31 - 24''' || '''16 - 0'''
+
! '''31 - 24''' || '''16 - 0'''
 
|-
 
|-
 
|Selektor
 
|Selektor
 
|Offset 15 - 0
 
|Offset 15 - 0
 
|}
 
|}
−
 
+
</center>