El GDT

From Movaxes

(Difference between revisions)
('''gdt.asm''')
 
Line 1: Line 1:
-
=EL GDT (Global Table Descriptor)=
+
Esta página fue movida a [http://wiki.todoprogra.com/index.php?title=El_GDT El GDT] gracias!
-
==GDT==
+
-
 
+
-
El GDT es una estructura de datos para definir los privilegios de diferentes áreas de la memoria.
+
-
 
+
-
La tabla de descriptores es un array de entradas de 8 bytes que contienen descriptores, puede contener cualquier cantidad de descritores hasta un máximo de 8192 descriptores. La primera entrada del GDT no es usada por el procesador (descriptor nulo).
+
-
 
+
-
==GDTR==
+
-
 
+
-
El GDT es apuntado por un registro especial de 48 bits llamado '''GDTR'''. El puntero al GDT debe contener esta información:
+
-
+
-
*'''LIMIT''': Los primeros 16 bits indican el tamaño del segmento del GDT.
+
-
*'''BASE''': Los siguientes 32 bits indican en dónde se encuentra el GDT en el espacio lineal de 4Gb de la memoria. Se puede calcular de esta forma (ASM):
+
-
<pre>
+
-
puntero_gdt:
+
-
 
+
-
dw final_gdt-inicio_gdt-1 ;LIMIT
+
-
dd inicio_gdt ;BASE
+
-
</pre>
+
-
 
+
-
==Segmentos==
+
-
 
+
-
El GDT contiene un número de entradas llamadas '''Segment Descriptors''', ''estos descriptores de segmento'' indican en que parte de la memoria empieza, termina y los privilegios asociados con esta entrada. Cada descriptor del GDT indica si el área de la memoria es para uso del sistema (ring 0) o para el uso de las aplicaciones (ring 3). Los anillos (rings) indican al procesador si está permitido ejecutar instrucciones especiales (por ejemplo: ''cli'').
+
-
 
+
-
La estructura de una entrada del descriptor es:
+
-
*Limite (segment limit) 2 bytes.
+
-
*Base (base adress) 2 bytes: La dirección lineal en donde empieza el segmento.
+
-
*Base (base) 1 byte:
+
-
*Acceso (access) 1 byte: contiene los siguiente bits:
+
-
**Presencia (1 bit) = debe estar puesto a 1 si el segmento es válido
+
-
**Privilegio (2 bit) = contiene el nivel de privilegios (ring 0 = kernel, ring 3 = aplicaciones).
+
-
**Ejecutable (1 bit) = 1 si es segmento de codigo, 0 si es segmento de datos.
+
-
**Dirección (1 bit) =
+
-
***Segmento de Código: relacionado con los privilegios
+
-
***Segmento de Datos: 1 indica que el segmento crece hacia abajo, 0 que crece hacia arriba.
+
-
**Lectura y Escritura (1 bit) =
+
-
***Segmento de Código: Si está permitida la lectura de este segmento. (en un segmento de datos nunca puede escribirse)
+
-
***Segmento de Datos: Si está permitida la escritura de este segmento. (en un segmento de datos siempre se puede leer)
+
-
**Accedido (1 bit) = el procesador lo pone a 1 cuando accede a el.
+
-
*Banderas 2 =
+
-
**Granularidad (1 bit) = 0 si el límite está bloques de 1 byte (granulación de bytes), 1 si el límite está en bloques de 4Kib (granulación de páginas).
+
-
**Tamaño (1 bit) = 0 si el segmento define un modo protegido de 16 bits, 1 si es modo protegido de 32 bits.
+
-
 
+
-
<pre>
+
-
;--------------------------------------------------------------------------------------------------------;
+
-
; Limite Bajo (2b) ; Base Baja (2b) ; Base Media (1b) ; Acceso (1b) ; Granularidad (1b) ; Base Alta (1b) ;
+
-
;--------------------------------------------------------------------------------------------------------;
+
-
</pre>
+
-
 
+
-
''todo: información más detallada?''
+
-
 
+
-
==Implementación==
+
-
 
+
-
Esta es la implementación de NULL-OS con el GDT:
+
-
 
+
-
==='''boot.asm'''===
+
-
<pre>
+
-
;--------------------------;
+
-
; NULL OS (boot.asm)      ;
+
-
; version: 0.0.1          ;
+
-
; autor: movaxes          ;
+
-
; fecha: 6/2/07            ;
+
-
;--------------------------;
+
-
[BITS 32]
+
-
 
+
-
%include "gdt.asm"
+
-
 
+
-
global boot ;donde inicia nuestro kernel
+
-
extern _main ;esta funcion se encuentra en main.c
+
-
 
+
-
;Multiboot Header
+
-
 
+
-
MULTIBOOT_PAGE_ALIGN equ 1<<0
+
-
MULTIBOOT_MEMORY_MAP equ 1<<1
+
-
   
+
-
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
+
-
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_MAP
+
-
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+
-
 
+
-
SECTION .text
+
-
ALIGN 4
+
-
multiboot_header:
+
-
 
+
-
dd MULTIBOOT_HEADER_MAGIC
+
-
dd MULTIBOOT_HEADER_FLAGS
+
-
dd MULTIBOOT_CHECKSUM
+
-
 
+
-
;nuestro stack (pila) de 16kb:
+
-
 
+
-
KERNEL_STACK equ 0x4000
+
-
 
+
-
boot:
+
-
 
+
-
mov esp,stack+KERNEL_STACK ;apuntamos a nuestra pila
+
-
+
-
push eax ;ponemos en la pila MULTIBOOT_HEADER_MAGIC
+
-
push ebx ;ponemos en la pila MULTIBOOT_MEMORY_MAP
+
-
+
-
call gdt_set ;ponemos el GDT
+
-
call _main ;llamamos a main en main.c
+
-
cli
+
-
hlt ;detiene el CPU
+
-
jmp $ ;loop infinito
+
-
+
-
SECTION .bss
+
-
ALIGN 32
+
-
stack:
+
-
 
+
-
resb KERNEL_STACK
+
-
</pre>
+
-
 
+
-
==='''gdt.asm'''===
+
-
<pre>
+
-
;--------------------------;
+
-
; NULL OS (gdt.asm)        ;
+
-
; version: 0.0.2          ;
+
-
; autor: movaxes          ;
+
-
; fecha: 13/2/07          ;
+
-
;--------------------------;
+
-
[BITS 32]
+
-
;----------------;
+
-
;gdt_set        ;
+
-
;----------------;
+
-
 
+
-
gdt_set:
+
-
 
+
-
lgdt [puntero_gdt]  ;carga el GDTR
+
-
mov ax, 0x10 ;
+
-
mov ds, ax ;Apuntamos el segmento de datos a 0x10
+
-
mov es, ax ;...
+
-
mov fs, ax
+
-
mov gs, ax
+
-
mov ss, ax
+
-
 
+
-
jmp 0x08:gdt_set_end ;cargamos el CS
+
-
   
+
-
gdt_set_end:
+
-
 
+
-
ret ;fin de gdt_set
+
-
 
+
-
;----------------;
+
-
 
+
-
puntero_gdt: ;nuestro puntero al GDT
+
-
 
+
-
dw GDT_END-GDT_INIT-1 ;limite (fin del gdt - inicio del gdt - 1)
+
-
dd GDT_INIT ;base
+
-
+
-
;----------------;
+
-
;GDT            ;
+
-
;----------------;
+
-
GDT_INIT:
+
-
;----------------;
+
-
NULL_SEG    equ    $-GDT_INIT ;Descriptor nulo (NULL = 0x0):
+
-
 
+
-
    dw 0 ;Limite del Segmento
+
-
    dw 0 ;00..15 de la dirección base
+
-
    db 0 ;16..23 de la dirección base
+
-
    db 0 ;Permisos de acceso al segmento:
+
-
;(presencia,privilegio,ejecutable,direccion,r/w,accedido)
+
-
    db 0 ;Granularidad, Tamaño del los optcodes (16 o 32), limite de 16..19
+
-
    db 0 ;24..31 de la dirección base
+
-
;----------------;
+
-
K_CODE_SEG    equ    $-GDT_INIT ;segmento de Codigo del kernel:
+
-
 
+
-
    dw 0xFFFF
+
-
    dw 0
+
-
    db 0
+
-
    db 10011010b
+
-
    db 11001111b
+
-
    db 0
+
-
;----------------;
+
-
K_DATA_SEG    equ    $-GDT_INIT ;segmento de Datos del Kernel:
+
-
 
+
-
    dw 0FFFFh
+
-
    dw 0
+
-
    db 0
+
-
    db 10010010b
+
-
    db 11001111b
+
-
    db 0
+
-
;----------------;
+
-
U_CODE_SEG    equ    $-GDT_INIT ;segmento de Codigo de usuario:
+
-
 
+
-
    dw 0FFFFh
+
-
    dw 0
+
-
    db 0
+
-
    db 11111010b
+
-
    db 11001111b
+
-
    db 0
+
-
;----------------;
+
-
U_DATA_SEG    equ    $-GDT_INIT ;segmento de Datos de usuario:
+
-
 
+
-
    dw 0xFFFF
+
-
    dw 0
+
-
    db 0
+
-
    db 11110010b
+
-
    db 11001111b
+
-
    db 0
+
-
;----------------;   
+
-
GDT_END: ;fin del GDT
+
-
;----------------;
+
-
</pre>
+
-
 
+
-
==='''main.c'''===
+
-
<pre>
+
-
/*--------------------------;
+
-
; NULL OS (main.c)          ;
+
-
; version: 0.0.1            ;
+
-
 
+
-
; autor: movaxes            ;
+
-
; fecha: 6/2/07            ;
+
-
;--------------------------*/
+
-
 
+
-
//esta es nuestra funcion _main llamada desde boot.asm
+
-
//los argumentos que pasamos son:
+
-
//MULTIBOOT_HEADER_MAGIC
+
-
//MULTIBOOT_MEMORY_INFO
+
-
//los cuales estan en la pila (stack)
+
-
void _main(void* mm, unsigned int magic)
+
-
{
+
-
//todo:...
+
-
}
+
-
</pre>
+
-
 
+
-
==='''link.ld'''===
+
-
<pre>
+
-
ENTRY (boot)
+
-
SECTIONS{
+
-
    . = 0x00100000;
+
-
 
+
-
    .text :{
+
-
        *(.text)
+
-
    }
+
-
 
+
-
    .rodata ALIGN (0x1000) : {
+
-
        *(.rodata)
+
-
    }
+
-
 
+
-
    .data ALIGN (0x1000) : {
+
-
        *(.data)
+
-
    }
+
-
 
+
-
    .bss : {
+
-
        _sbss = .;
+
-
        *(COMMON)
+
-
        *(.bss)
+
-
        _ebss = .;
+
-
    }
+
-
}
+
-
</pre>
+
-
 
+
-
==='''build.sh:'''===
+
-
<pre>
+
-
#!/bin/bash
+
-
echo --- compilando *.asm
+
-
nasm -f elf boot.asm -o boot.o
+
-
nasm -f elf gdt.asm -o gdt.o
+
-
echo --- compilando *.c
+
-
#gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c
+
-
gcc -o main.o -c main.c -Wall -Werror -nostdlib -nostartfiles -nodefaultlibs
+
-
echo --- linking *.o
+
-
ld -T link.ld -o kernel.bin boot.o  main.o gdt.o
+
-
echo --- borrando *.o
+
-
rm *.o
+
-
echo --- EXITO!!
+
-
</pre>
+
-
 
+
-
===Compilar y Probar el Kernel===
+
-
Para compilar solo escribe en un terminal:
+
-
<pre>
+
-
$sh build.sh
+
-
</pre>
+
-
 
+
-
Para poder probar tu nuevo kernel puedes usar GRUB (mira: [http://www.editthis.info/movaxes/Usando_GRUB Usando GRUB] para saber cómo puedes hacerlo)
+
-
 
+
-
<br>
+
-
<br>
+

Current revision as of 18:32, 6 April 2007

Esta página fue movida a El GDT gracias!

Personal tools