Modo protegido

Anuncio
Primeros Pasos
Federico Raimondo
PSO
1er cuat 2011
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
1 / 44
Booteo
¿Qué?
Bootloader
wikipedia.org
Es un programa sencillo diseñado exclusivamente para preparar todo lo que
necesita el sistema operativo para funcionar.
Normalmente se utilizan los cargadores de arranque multietapas, en los
que varios programas pequeños se suman los unos a los otros, hasta que el
último de ellos carga el sistema operativo.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
2 / 44
Booteo
¿Por qué?
Bootloader ¿por qué?
Intel determinó que, por cuestiones de compatibilidad, todas las PCs
arrancan igual que un 8086. Este modo en el que arranca se lo llama modo
real.
En modo real, no tenemos para direccionar mas que 1114096 bytes en los
CPUs modernos (1.062 Mb aprox.). Este lı́mite hace que tengamos que
cambiar de modo e inicializar ciertas estructuras del CPU antes de cargar
el kernel (salvo que nuestro kernel ocupe menos de 1 Mb).
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
3 / 44
Booteo
¿Cómo?
Proceso de booteo
Cuando la computadora se prende, corre una serie de diagnósticos
llamados POST (Power On Self Test). Parte de esta secuencia es buscar
un dispositivo booteable.
Un dispositivo es booteable si tiene un sector de booteo cuyos bytes 511 y
512 son 0x55 y 0xAA respectivamente.
Cuando la BIOS lo detecta, lo carga en una dirección predeterminada:
0x0000:0x7C00 o 0x07C0:0x0000. (Son la misma dirección fı́sica, lo
veremos mas adelante)
Luego se procede a ejecutar el código cargado.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
4 / 44
Booteo
¿Cómo?
Memoria
¿Quién va a necesitar mas de 640 Kb?
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
5 / 44
Booteo
¿Cómo?
Resumiendo
Pasos a seguir en el booteo:
1
Determinar el disco y la partición a bootear.
2
Determinar dónde está la imagen del kernel en ese disco.
3
Cargar la imagen del kernel en memoria.
4
Pasar a modo protegido.
5
Preparar las estructuras para correr el kernel (Ej: preparar la pila).
¡Todo esto en 510 bytes!
Dirı́a un conocido personaje del rock:
“Esh imposhible, ¡esh imposhible!”
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
6 / 44
Booteo
¿Cómo?
Resumiendo
Pasos a seguir en el booteo:
1
Determinar el disco y la partición a bootear.
2
Determinar dónde está la imagen del kernel en ese disco.
3
Cargar la imagen del kernel en memoria.
4
Pasar a modo protegido.
5
Preparar las estructuras para correr el kernel (Ej: preparar la pila).
¡Todo esto en 510 bytes!
Dirı́a un conocido personaje del rock:
“Esh imposhible, ¡esh imposhible!”
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
6 / 44
Booteo
¿Cómo?
Opciones
wiki.osdev.org
Geek loading: Apretar todo eso en 510 bytes. Casi imposible.
One-stage loading: Hacer una rutina para preparar las estructuras y
linkearlo en el inicio de la imagen del kernel. El bootloader salta ahi,
esa rutina prepara todo y salta al kernel.
Two-stage loading: Hacer la rutina anterior, pero fuera del kernel.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
7 / 44
Booteo
¿Cómo?
El bootloader de PSO
Vamos a dar un bootloader para que hagan sus ejercicios.
El proceso que realiza es el siguiente:
Se copia el Bootloader en la posición 0x1000 de la memoria.
Se busca el archivo KERNEL.BIN en el diskette.
Se copia ese archivo en la posición 0x1200 de la memoria.
Se salta y se ejecuta la instrucción en la posición 0x1200 de la
memoria.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
8 / 44
Booteo
¿Cómo?
Memoria
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
9 / 44
Modo Real
Programación en Modo Real
¿Y la programación en modo real?
16 bits.
No hay protección de memoria, OJO.
No se pueden restringir las instrucciones.
AX, CX y DX no son de propósito general. No se pueden usar para
acceder a memoria.
Los compiladores modernos no generan código para modo real. No
queda otra que el assembler.
Podemos usar la BIOS tal cual esta (por ejemplo, para imprimir por
pantalla).
Menos modos de direccionamiento (a continuación).
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
10 / 44
Modo Real
Programación en Modo Real
Direccionamiento en modo real
Únicas opciones:
[BX + val]
[SI + val]
[DI + val]
[BP + val]
[BX + SI + val]
[BX + DI + val]
[BP + SI + val]
[BP + DI + val]
[val]
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
11 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
Cada dirección de memoria esta definida por un segmento y un offset (de
16 bits cada uno, por supuesto):
La forma de calcular a que dirección fisica que corresponde es:
(segmento << 4) + offset
En el ejemplo:
(0x07C0 << 4) + 0x0120 = 0x7C00 + 0x0120 = 0x7D20
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
12 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS: código
DS: datos
ES: datos
FS: datos
GS: datos
SS: pila
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS: código
DS: datos
ES: datos
FS: datos
GS: datos
SS: pila
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS:IP (Instruction Pointer)
DS: datos
ES: datos
FS: datos
GS: datos
SS: pila
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS:IP (Instruction Pointer)
MOV AX, [DS:SI]
ES: datos
FS: datos
GS: datos
SS: pila
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS:IP (Instruction Pointer)
MOV AX, [DS:SI]
MOV AX, [ES:SI]
FS: datos
GS: datos
SS: pila
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS:IP (Instruction Pointer)
MOV AX, [DS:SI]
MOV AX, [ES:SI]
MOV AX, [FS:SI]
GS: datos
SS: pila
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS:IP (Instruction Pointer)
MOV AX, [DS:SI]
MOV AX, [ES:SI]
MOV AX, [FS:SI]
MOV AX, [GS:SI]
SS: pila
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
Direccionamiento en Modo Real
¿Cómo especificamos los segmentos?
CS:IP (Instruction Pointer)
MOV AX, [DS:SI]
MOV AX, [ES:SI]
MOV AX, [FS:SI]
MOV AX, [GS:SI]
SS:SP (tope de pila)
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
13 / 44
Modo Real
Programación en Modo Real
A tener en cuenta
Estamos solos contra el mundo (no hay librerı́as, no hay printf, ¡no
hay nada!).
section .data .text .bss .rodata: Estan ligados a los formatos
de archivos de los sistemas operativos. Ahora solo tenemos un binario
plano, ¡Ojo con ejecutar los datos! ¡Ojo con modificar el código en
tiempo de ejecución!
No hay segmentation fault. Toda la memoria es “nuestra”. No
tenemos protección ni de nosotros mismos.
Podemos hacer lo que tenemos ganas, el CPU es nuestro.
Hasta que no pasemos a modo protegido, tenemos el mejor 8086 de
la historia.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
14 / 44
Modo protegido
Comparación
Modo Real vs Modo Protegido
Diferencias generales:
Real
Memoria disp. ∼ 1 mb (*)
Privilegios
Interrupciones
Todos hacen todo
Llamada a rutina
Instrucciones
Todas
Federico Raimondo (PSO)
Protegido
Toda (o 4GB por tarea
con paginación)
4 anillos (0-3)
Depende: interrupt, trap
o task gate. Con privilegios
Subconjunto, segun privilegio
Primeros Pasos
1er cuat 2011
15 / 44
Modo protegido
Definiciones
Algunas definiciones: A20
Es el bit 20 en la representación de las direcciones de memoria fı́sica.
Para poder direccionar mas de 220 direcciones, hay que habilitar el pin
20.
Este pin se lo llama A20 Gate o Line.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
16 / 44
Modo protegido
Definiciones
Algunas definiciones: Tablas de descriptores
wiki.osdev.org:
En la arquitectura Intel, precisamente en modo protegido, la mayorı́a de las tareas
de administración de memoria y manejo de interrupciones se controlan mediante
tablas de descriptores. Cada descriptor contiene información sobre un objeto
(rutina de interrupción, tarea, segmento de código, segmento de datos, etc) que
el CPU puede necesitar. Si se intenta, por ejemplo, cargar un nuevo valor dentro
de un registro de segmento, el CPU tiene que verificar los permisos para el area
de memoria que se intenta acceder.
Intel definió 3 tipos de tablas. La Tabla de Descriptores de Interrupciones (IDT),
la Tabla de Descriptores Globales (GDT) y la Tabla de Descriptores Locales
(LDT). Cada tabla se define como un par (tamaño, dirección) en los registros
LIDT, LGDT, LLDT.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
17 / 44
Modo protegido
Definiciones
Algunas definiciones: GDT
GDT: Global Descriptor Table
Cada entrada es de 8 bytes y puede tener alguno de los siguientes
descriptores:
Descriptor de segmento de memoria.
Descriptor de Task State Segment (TSS). Es el estado de la tarea,
para hacer cambio de tareas a nivel CPU.
Descriptor de LDT.
Descriptor de call gate. Se utilizaban para transferir control entre
niveles de privilegios. Actualmente no se usan en SO modernos.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
18 / 44
Modo protegido
Definiciones
Algunas definiciones: LDT
LDT: Local Descriptor Table.
Contiene lo mismo que la GDT.
Y entonces... ¿en que se diferencian?
La GDT tiene los descriptores globales y es una sola, mientras que los que
tiene la LDT son locales y pueden ser mas de uno. Con locales se refiere a
que son locales a una tarea. Cuando se cambia de tarea, se cambia de
LDT (hay uno por tarea). Desde que se usa paginación, esta tabla quedo
obsoleta.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
19 / 44
Modo protegido
Definiciones
Direccionamiento en modo protegido (memoria
segmentada)
Figura: Traducción de dirección lógica a fı́sica
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
20 / 44
Modo protegido
Definiciones
Direccionamiento en modo protegido (memoria
segmentada)
Figura: Selector de Segmento
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
21 / 44
Modo protegido
Definiciones
Algunas definiciones: Descriptores de Segmento
Figura: Descriptor de Segmento
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
22 / 44
Modo protegido
Definiciones
Algunas definiciones: Descriptores de Segmento
Figura: Tipos de Descriptores de Segmento
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
23 / 44
Modo protegido
1
Booteo
2
Modo Real
3
Modo protegido
Switch a Modo Protegido
Definiciones
Switch a Modo Protegido
4
Compilación/Linkeo
Consideraciones previas
Compilación
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
24 / 44
Modo protegido
Switch a Modo Protegido
Activar Modo Protegido vs Pasar a Modo Protegido
Activar el Modo protegido es poner en 1 el bit PE del registro CR0.
mov eax, cr0
or eax, 0x1
mov cr0, eax
El tema son las consecuencias catastróficas de hacer solamente esto.
Por eso hablamos de pasar a modo protegido.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
25 / 44
Modo protegido
Switch a Modo Protegido
Activar Modo Protegido vs Pasar a Modo Protegido
Activar el Modo protegido es poner en 1 el bit PE del registro CR0.
mov eax, cr0
or eax, 0x1
mov cr0, eax
El tema son las consecuencias catastróficas de hacer solamente esto.
Por eso hablamos de pasar a modo protegido.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
25 / 44
Modo protegido
Switch a Modo Protegido
Activar Modo Protegido vs Pasar a Modo Protegido
Activar el Modo protegido es poner en 1 el bit PE del registro CR0.
mov eax, cr0
or eax, 0x1
mov cr0, eax
El tema son las consecuencias catastróficas de hacer solamente esto.
Por eso hablamos de pasar a modo protegido.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
25 / 44
Modo protegido
Switch a Modo Protegido
Analizando la catástrofe
GDT
Nulo
Código
Datos
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Analizando la catástrofe
GDT
Nulo
Código
Datos
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Analizando la catástrofe
GDT
Nulo
Código
Datos
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
<¿Y ahora?>
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Analizando la catástrofe
GDT
Nulo
Código
Datos
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
¿Qué dice CS:EIP?
<¿Y ahora?>
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Analizando la catástrofe
GDT
Nulo
Código
Datos
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
¿Qué dice CS:EIP?
<¿Y ahora?>
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Analizando la catástrofe
GDT
Nulo
Código
Datos
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
¿Qué dice CS:EIP? BOOM
<¿Y ahora?>
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Solucionando la catástrofe
GDT
Nulo
Código
Datos
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
¿Qué dice CS:EIP? BOOM
¿Qué deberı́a decir CS? 0x0008
<¿Y ahora?>
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Solucionando la catástrofe
GDT
Nulo
Código
Datos
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
¿Qué dice CS:EIP? BOOM
¿Qué deberı́a decir CS? 0x0008
¿Y cómo cambiamos el registro CS?
<¿Y ahora?>
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Solucionando la catástrofe
GDT
Nulo
Código
Datos
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
CS
DS
ES
IP
AX
...
CPU
0x0000
0x0000
0xB800
0x03A6
0x024C
...
¿Qué dice CS:EIP? BOOM
¿Qué deberı́a decir CS? 0x0008
¿Y cómo cambiamos el registro CS? BOOM
mov cs, 0x0008
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
Solucionando la catástrofe
GDT
Nulo
Código
Datos
Código
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp 0x08:modoprotegido
modoprotegido:
...
Federico Raimondo (PSO)
CS
DS
ES
IP
AX
...
CPU
0x0008
0x0000
0xB800
0x03A6
0x024C
...
¿Qué dice CS:EIP? OK
¿Qué deberı́a decir CS? 0x0008
¿Y cómo cambiamos el registro CS? OK
Primeros Pasos
1er cuat 2011
26 / 44
Modo protegido
Switch a Modo Protegido
El switch, según intel (teorı́a)
1
Deshabilitamos las interrupciones. (CLI)
2
Cargamos el registro GDTR con la dirección base de la GDT. (LGDT)
3
Seteamos el bit PE del registro CR0. (MOV, OR, MOV)
4
Realizamos un FAR JUMP a la siguiente instrucción.
5
Si habilitamos la paginación, tenemos que tener en cuenta la ubicación de estos códigos
antes y después del jump.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
27 / 44
Modo protegido
Switch a Modo Protegido
El switch, segun intel (continuación de la teorı́a)
6
Si se va a usar la LDT, cargar el registro LDTR. (LLDT)
7
Cargar el registro de tareas con el selector de segmento inicial o una porción de memoria
donde se pueda guardar la información del TSS. (LTR)
8
Actualizar la información de los registros DS, ES, GS y FS. (actualmente tienen la
información de modo real)
9
Cargar el registro IDTR con el valor de la dirección base y el lı́mite de la IDT. (LIDT).
10
Habilitar las interrupciones. (STI)
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
28 / 44
Modo protegido
Switch a Modo Protegido
El switch, bien basico
1
Deshabilitamos las interrupciones. (CLI)
2
Cargamos el registro GDTR con la direccion base de la GDT. (LGDT)
3
Seteamos el bit PE del registro CR0. (MOV, OR, MOV)
4
Realizamos un FAR JUMP a la siguiente instruccion.
5
Actualizar la informacion de los registros DS, ES, GS, FS y SS. (actualmente tienen la
informacion de modo real)
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
29 / 44
Modo protegido
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Switch a Modo Protegido
BITS 16
extern kernel_start
extern GDT_DESC
global start
start :
call enable_A20
lgdt [ GDT_DESC ]
mov eax , cr0
or eax , 0 x1
mov cr0 , eax
jmp 0 x08 : modo_protegido
BITS 32
modo_ protegido :
mov
ax , 0 x10
mov
ds , ax
mov
es , ax
mov
fs , ax
mov
ss , ax
mov
esp , 0 xA0000
mov
ebp , 0 xA0000
xchg
call
jmp $
bx , bx
kernel_start
%include " a20 . asm "
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
30 / 44
Compilación/Linkeo
1
Booteo
2
Modo Real
3
Modo protegido
Consideraciones previas
Definiciones
Switch a Modo Protegido
4
Compilación/Linkeo
Consideraciones previas
Compilación
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
31 / 44
Compilación/Linkeo
Consideraciones previas
Origen del programa
Cuando compilamos bajo un sistema operativo, todos los compiladores asumen que la dirección
de inicio de nuestro programa es la 0x00000000 . Cada etiqueta se traduce a una dirección, y en
muchos casos se hacen saltos o llamadas a direcciónes absolutas.
¿Y si no estamos en un sistema operativo?
Por ejemplo, el archivo KERNEL.BIN se carga en la dirección 0x1200
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
32 / 44
Compilación/Linkeo
Consideraciones previas
Origen del programa
Cuando compilamos bajo un sistema operativo, todos los compiladores asumen que la dirección
de inicio de nuestro programa es la 0x00000000 . Cada etiqueta se traduce a una dirección, y en
muchos casos se hacen saltos o llamadas a direcciónes absolutas.
¿Y si no estamos en un sistema operativo?
Por ejemplo, el archivo KERNEL.BIN se carga en la dirección 0x1200
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
32 / 44
Compilación/Linkeo
Consideraciones previas
Ejemplo
Sin direccion de origen
0x0630
ciclo:
nop
...
call ciclo
Con direccion de origen en 0x1200
0x1830
ciclo:
nop
...
call ciclo
Si la version de la izquierda se carga en la posición 0x1200 , el call se sigue haciendo a la
posición 0x0630 , o sea, a cualquier lado.
El efecto de la direccion de origen es cambiar la forma en que se traducen las etiquetas en
direcciones al momento de compilar.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
33 / 44
Compilación/Linkeo
Consideraciones previas
Origen del programa
Hay 2 formas de hacerlo, segun como se compile:
Si compilamos de assembler a binario, usamos la directiva ORG al inicio del archivo.asm
para indicar la direccion de origen. Ej: ORG 0x1200 .
Si compilamos de assembler a elf, usamos el parámetro -Ttext en el linker. Ej: -Ttext
0x1200 .
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
34 / 44
Compilación/Linkeo
Compilación
Compilación de assembly en formato bin
roquenio@woody$ nasm -fbin archivo.asm -o archivo.bin
Consideraciones:
Todo el código ejecutable tiene que estar incluido (No hay librerı́as).
Se ejecuta tal cual se escribió, no hay entry point.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
35 / 44
Compilación/Linkeo
Compilación
Compilación de assembly en formato elf32 y linkeo
Compilación:
roquenio@woody$ nasm -felf32 archivo.asm -o archivo.o
Linkeo:
roquenio@woody$ ld -static -m elf i386 --oformat binary -b elf32-i386 -e start
-Ttext 0x1200 archivo.o -o archivo.bin
Consideraciones:
Se pueden usar librerı́as.
No se respeta el entry point.
El parámetro Ttext da el orı́gen de la sección .text. Por ejemplo, esto se usa para hacer
saltos a posiciones absolutas de memoria. Si usan el Bootloader de Orga 2, deben usar
0x1200 como origen de la sección .text.
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
36 / 44
Compilación/Linkeo
Compilación
Compilación de C en formato elf32 y linkeo
Ojo, solo sirve cuando ya estamos en modo protegido.
Compilación:
roquenio@woody$ gcc -m32 -g -ggdb -fno-zero-initialized-in-bss
-fno-stack-protector -ffreestanding -c -o archivo.elf archivo.c
Linkeo:
roquenio@woody$ ld -static -m elf i386 -nostdlib -N -b elf32-i386 -e start
-Ttext 0x1200 -o archivo.elf archivo.o
Lo convertimos en binario:
roquenio@woody$ objcopy -S -O binary archivo.elf archivo.bin
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
37 / 44
Compilación/Linkeo
Compilación
Compilacion de un bootloader y creacion de diskette
Creamos un diskette vacio:
roquenio@woody$ dd bs=512 count=2880 if=/dev/zero of=diskette.img
Formateamos la imagen en FAT12:
roquenio@woody$ sudo mkfs.msdos -F 12 diskette.img -n ETIQUETA
Escribimos en el sector de booteo:
roquenio@woody$ dd if=bootloader.bin of=diskette.img count=1 seek=0 conv=notrunc
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
38 / 44
Compilación/Linkeo
Compilación
Copiado del KERNEL.BIN adentro del diskette
roquenio@woody$ mcopy -i diskette.img kernel.bin ::/
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
39 / 44
Compilación/Linkeo
Compilación
Fin
¡GANÉ!
Figura: Un groso
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
40 / 44
Compilación/Linkeo
Compilación
Ejercicio
1
Crear el archivo klib.c en el directorio kernel/ y su correspondiente klib.h en el
directorio include/ que contendrán las funciones de biblioteca para usar dentro del kernel.
Realizar todas las modificaciones necesarias para que sea incluido en la compilación.
2
Programar las funciones necesarias para poder escribir en pantalla un texto arbitrario en
una posición y de color arbitrarios, similar.
3
Extienda la funcionalidad para poder escribir números en decimal o hexadecimal en
pantalla.
4
Modificar el archivo kernel.c para que cuando empiece muestre el estado de todos los
registros del procesador en la pantalla:
De segmento: cs, ds, es, fs, gs, ss
De control: cr0, cr2, cr3, cr4
Internos: gdtr, ldtr, idtr, tr
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
41 / 44
Compilación/Linkeo
Compilación
Código C, con una pisca de Assembler
Desde C se puede ejecutar un poquito de assembler fácilmente como funciones.
#define LS_INLINE static __inline __attribute__((
always_inline))
/* Prototipos */
LS_INLINE void lcr0(uint_32 val);
LS_INLINE uint_32 rcr0(void);
/* Funciones */
LS_INLINE void lcr0(uint_32 val) {
__asm __volatile("movl %0, % %cr0" : : "r" (val));
}
LS_INLINE uint_32 rcr0(void) {
uint_32 val;
__asm __volatile("movl % %cr0, %0" : "=r" (val));
return val;
}
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
42 / 44
Compilación/Linkeo
Compilación
La memoria de video
La memoria de video comienza en la dirección 0xB8000.
La matriz de video tiene 80 columnas y 25 filas.
Cada elemento es de 2 bytes. El primero es el modo y el segundo es el caracter ASCII.
Cada bit del color del modo de video indica las componentes RGB (8 colores).
Figura: Byte de modo de video
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
43 / 44
Compilación/Linkeo
Compilación
Caracteres ASCII
Figura: tabla de caracteres ascii
Federico Raimondo (PSO)
Primeros Pasos
1er cuat 2011
44 / 44
Descargar