´Indice general - 148.206.53.231

136

Transcript of ´Indice general - 148.206.53.231

Page 1: ´Indice general - 148.206.53.231
Page 2: ´Indice general - 148.206.53.231

Indice general

1. Introduccion 5

2. Arquitectura y organizacion de la computadora 72.1. CPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.1.1. Unidad aritmetica-logica (ALU, Arithmetic Logic Unit) 92.1.2. Registros internos de microprocesadores Intel . . . . . 102.1.3. Direccionamiento en modo real . . . . . . . . . . . . . 162.1.4. Direccionamiento de la memoria en modo protegido . 182.1.5. Unidad de control . . . . . . . . . . . . . . . . . . . . . 192.1.6. Conjunto de instrucciones . . . . . . . . . . . . . . . . 21

2.2. Memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.3. Entrada/Salida . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.3.1. Interfaces de entrada-salida . . . . . . . . . . . . . . . 24

3. El BIOS 273.1. Interrupciones . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.2. Controlador de interrupciones 8259 . . . . . . . . . . . . . . . 303.3. Temporizador 8254 (U8254) . . . . . . . . . . . . . . . . . . . 313.4. Temporizador 0, 1 y 2 . . . . . . . . . . . . . . . . . . . . . . 33

3.4.1. Modos de Operacion . . . . . . . . . . . . . . . . . . . 343.4.2. Programacion del temporizador . . . . . . . . . . . . . 36

4. Sistema Operativo 394.1. Estructura del Sistema Operativo . . . . . . . . . . . . . . . . 404.2. Componentes del Sistema Operativo . . . . . . . . . . . . . . 414.3. Administracion de procesos . . . . . . . . . . . . . . . . . . . 42

4.3.1. Definicion de proceso . . . . . . . . . . . . . . . . . . . 424.3.2. Modelo de estados . . . . . . . . . . . . . . . . . . . . 424.3.3. Colas de procesos . . . . . . . . . . . . . . . . . . . . . 434.3.4. Bloque de control de proceso (BCP) . . . . . . . . . . 444.3.5. Planificador de procesos . . . . . . . . . . . . . . . . . 45

1

Page 3: ´Indice general - 148.206.53.231

4.3.6. Cambio de contexto . . . . . . . . . . . . . . . . . . . . 454.4. Administracion de memoria . . . . . . . . . . . . . . . . . . . 48

4.4.1. Reubicacion . . . . . . . . . . . . . . . . . . . . . . . . 494.4.2. Proteccion . . . . . . . . . . . . . . . . . . . . . . . . . 494.4.3. Comparticion . . . . . . . . . . . . . . . . . . . . . . . 494.4.4. Organizacion logica . . . . . . . . . . . . . . . . . . . . 504.4.5. Organizacion fısica . . . . . . . . . . . . . . . . . . . . 504.4.6. Particionamiento de memoria . . . . . . . . . . . . . . 50

5. Diseno y construccion del Sistema Operativo 555.1. Introduccion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555.2. Cargador del sistema operativo . . . . . . . . . . . . . . . . . 565.3. Servicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565.4. Nucleo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

5.4.1. Administracion de procesos . . . . . . . . . . . . . . . 605.4.2. Administracion de memoria . . . . . . . . . . . . . . . 65

5.5. Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

6. Conclusiones 67

7. Referencias 69

A. cargador.asm 71

B. creafdisk.c 81

C. nucleo.c 87

D. dirs.h 91

E. dirs.inc 95

F. servis.c 99

G. so.h 113

H. proc0.asm 119

I. int.asm 121

J. lib.c 123

K. lib1.c 131

2

Page 4: ´Indice general - 148.206.53.231

L. lib2.c 135

3

Page 5: ´Indice general - 148.206.53.231

4

Page 6: ´Indice general - 148.206.53.231

Capıtulo 1

Introduccion

En los inicios de la programacion de computadoras, el programador no solotenıa que enfrentarse a la complejidad del lenguaje maquina, sino que tam-bien con la administracion de recursos (almacenamiento o dispositivos deEntrada/Salida por citar algunos); mas aun el programador no solo debıaconocer en gran medida la computadora, sino la manera de programar paraacceder a los recursos. En otras palabras, los programas o aplicaciones debıande preocuparse por la administracion de los recursos.

Por lo anterior surgio la necesidad de construir un intermediario que dis-minuyera la complejidad de programar y que muestre una vista simple yagradable. La estrategia que ha evolucionado en forma gradual consiste encolocar una capa de software entre el hardware y los programas de usuario,con el objeto de manejar todas las partes del sistema y presentar al usuariouna interfaz que sea mas facil de entender y utilizar. Esta capa de softwarees llamada sistema operativo.

El sistema operativo es el que controla todos los recursos de una computadoratales como: procesadores, memoria principal, relojes, discos, interfaces enredes y otros dispositivos de entrada/salida; y ofrece la base sobre la cualpueden desarrollarse y ejecutarse los procesos1.

Otro trabajo fundamental del sistema operativo consiste en ofrecer una dis-tribucion ordenada y controlada de los procesadores, memorias y dispositivosde E/S entre los diversos programas que compiten por ellos, en esta vision elsistema operativo: lleva el control de quien utiliza cada recurso, concede re-quisiciones de recursos e intercede en conflictos en la asignacion de recursos.Para esta ultima tarea, el hardware es quien generalmente debe proporcio-nar al sistema operativo los mecanismos apropiados para asegurar el correcto

1Programas en ejecucion.

5

Page 7: ´Indice general - 148.206.53.231

funcionamiento del sistema.

Debido a la complejidad de los sistemas operativos actuales, y la falta de ma-terial didactico para su ensenanza, es complicado para los alumnos el poderentender y aplicar los conceptos y caracterısticas sobre sistemas operativos.Partiendo desde esa idea generamos el sistema operativo SO, el cual cuentacon las caracterısticas basicas de un sistema operativo, y va dirigido espe-cialmente a la ensenanza.

El trabajo que aquı se presenta, esta organizado de la siguiente manera:

Capıtulo 2. Debido a que el sistema operativo interacciona de manera direc-ta con el hardware, es necesario conocer la Arquitectura y organizacion dela computadora en la que se describen las partes que conforman una compu-tadora y la relacion que existe entre cada una de ellas.

El capıtulo 3 contiene El BIOS, un programa instalado en memoria ROM dela PC, utilizado por el sistema operativo para proporcionar a los programas deusuario algun servicio mediante el conjunto de rutinas que contiene llamadasinterrupciones.

En el capıtulo 4 se presenta el Sistema Operativo, en el que se describendiferentes tipos de sistemas operativos y tambien las partes fundamentalesque deben conformar uno.

Una vez situados en el contexto, el capıtulo 5 describe a suficiente nivelde detalle el Diseno y construccion del sistema operativo SO basado en losconceptos abordados en los capıtulos anteriores y en la arquitectura del mi-croprocesador Intel 8086.

En el capıtulo 6 presentamos las conclusiones sobre lo realizado en este tra-bajo.

Al final del documento, en los apendices mostramos el codigo generado delsistema operativo

6

Page 8: ´Indice general - 148.206.53.231

Capıtulo 2

Arquitectura y organizacion dela computadora

La computadora es un dispositivo electronico que sirve para procesar todotipo de datos, como podemos ver en la figura 2.1 los datos de entrada sonprocesados por la computadora para obtener un resultado.

Figura 2.1: Funcionamiento de la computadora

La arquitectura y la organizacion son elementos muy importantes que nossirven para poder entender el funcionamiento de la computadora.

La arquitectura de computadoras se refiere a los atributos de un sistema queson visibles a un programador, es decir, aquellos atributos que tienen un im-pacto directo en la ejecucion logica de un programa, como por ejemplo: elconjunto de instrucciones, el numero de bits usados para representar variostipos de datos, mecanismos de E/S y tecnicas para direccionamiento de me-

7

Page 9: ´Indice general - 148.206.53.231

moria. La organizacion de computadoras se refiere a las unidades funcionalesy sus interconexiones, que dan lugar a especificaciones arquitectonicas. En-tre los atributos de organizacion se incluyen aquellos detalles de hardwaretransparentes al programador: tales como senales de control, interfaces entreel computador y los perifericos y la tecnologıa de memoria usada[1].

Ya que sabemos cual es la diferencia entre arquitectura y organizacion em-pezaremos a hablar de como esta organizada la computadora.

Una computadora tıpica tiene cuatro componentes principales, una CPU(Central Processing Unit: unidad central de proceso) tambien llamada pro-cesador, una memoria principal, un sistema de E/S y un sistema de interco-nexion tambien conocido como bus del sistema, en la figura 2.2 podemos vercomo estan conectados.

Figura 2.2: Estructura interna de la computadora

2.1. CPU

La CPU controla el funcionamiento de la computadora al generar las senalesde control a los diferentes dispositivos de la computadora, lleva a cabo funcio-nes de procesamiento de datos al ejecutar las instrucciones que se encuentranlocalizadas en memoria. El procesador realiza su trabajo a la velocidad deter-minada por un reloj interno, denominado ciclo. El ciclo corresponde al nume-ro de pulsos por segundo, expresados en Hertz (Hz). En cada ciclo de reloj

1 Stalling William, “Organizacion y arquitectura de computadoras” Septima Edicion,

Prentice Hall, p 8

8

Page 10: ´Indice general - 148.206.53.231

el procesador ejecuta una accion que corresponde a su vez a una instrucciono bien a una parte de ella. La potencia del procesador puede caracterizarsepor el numero de instrucciones por segundo que es capaz de procesar.

En la actualidad, los procesadores mas conocidos son los de las familias: Intely AMD, estos procesadores pueden ser de 8, 16, 32 y 64 bits dependiendo desu ancho de bus.

En este trabajo debido a la implementacion del sistema operativo realizadasolo se describe el procesador intel 8086.

El procesador tiene tres componentes principales que son (ver fig. 2.3):

1. Unidad Aritmetica Logica

2. Registros

3. Unidad de control

Figura 2.3: Estructura de la unidad central de procesamiento

2.1.1. Unidad aritmetica-logica (ALU, Arithmetic Logic

Unit)

La ALU es capaz de realizar un conjunto de operaciones aritmeticas basicas(resta, suma, division y multiplicacion), y un conjunto de operaciones logicas

9

Page 11: ´Indice general - 148.206.53.231

(OR, NOT, AND, etc.). La seleccion de cada operacion que realiza la ALU, sehace mediante k lıneas de seleccion que ejecutan una operacion en particular;las lıneas de seleccion se decodifican dentro de la ALU de manera que las kvariables de seleccion pueden especificar hasta 2k operaciones diferentes.

2.1.2. Registros internos de microprocesadores Intel

Registros

Un registro es una pequena unidad de almacenamiento destinada a almace-nar datos. Puede estar en la memoria principal o en unidades de memoriade acceso rapido. En los microcontroladores es comun, que los registros selocalicen en la memoria, pero para los Intel los registros son una zona dealmacenamiento aparte, que se localiza dentro del procesador.

La CPU contiene varios registros para el almacenamiento temporal de datos,estos datos pueden representar: valores sobre los cuales se van a realizar ope-raciones, resultados de las operaciones, direcciones de localidades de memoriadonde se encuentran datos e instrucciones, direcciones de los dispositivos deentrada/salida sobre los que deseamos escribir o leer, o los datos a enviar orecibir de los dispositivos. Algunos de estos, denominados registros progra-mables, pueden ser accedidos mediante instrucciones de la propia CPU, losrestantes son inaccesibles al programador.

Los registros de la CPU pueden ser accedidos mas rapidamente que la memo-ria principal, y como consecuencia, las instrucciones cuyos operandos estanen registros de la CPU son mas rapidas que las instrucciones equivalentescuyos operandos estan en la memoria principal.

Los registros de la CPU pueden clasificarse en tres grupos: registros deproposito general, registros apuntadores e ındice y registros de segmentos.Adicionalmente existe un registro de banderas que indica el estado de laCPU despues que termino la ultima operacion.

La programacion requiere un claro entendimiento de la estructura de los regis-tros internos de la CPU, en la siguiente seccion se dara una breve descripcionde los registros de la familia de microprocesadores Intel.

Registros de proposito general

Como su nombre lo indica, se utilizan en la forma que desee el programador.Cada registro de proposito general se puede direccionar como un registro de32 bits, como uno de 16 bits o como uno de 8 bits, esto depende del modo

10

Page 12: ´Indice general - 148.206.53.231

de funcionamiento del procesador.

A continuacion se describe cada uno de los registros de proposito general,cabe senalar que los registros EAX, EBX, ECX y EDX son registros de 32bits; y AX, BX, CX y DX son de 16 bits como se muestra en la figura 2.4.

Las funciones primarias de los registros de proposito general son:

EAX o AX (Acumulador): almacena el resultado temporalmente des-pues de una operacion aritmetica o logica.

EBX o BX (Base): almacena la direccion de desplazamiento de los datosque hay en la memoria o la direccion base de una tabla de datos.

ECX o CX(Contador): contiene el dato para ciertas instrucciones comocorrimientos (CL) y de conteo (CX o ECX) para la instruccion LOOP.

EDX o DX (Datos): es un registro de uso general que tambien contienela parte mas significativa de un producto despues de una multiplicacionde 16 o de 32 bits: la parte mas significativa del dividendo antes de ladivision y el numero de puerto de E/S para una instruccion de E/S.

Figura 2.4: Registros de Proposito General

11

Page 13: ´Indice general - 148.206.53.231

Registros apuntadores e ındices

Los registros apuntadores e ındices son tambien de uso general pero su usomas frecuente es para direccionar a localidades de memoria donde se encuen-tran los datos de las instrucciones, estos registros son de 32 y 16 bits, losregistros que inician con E son de 32 bits mientras que los otros son de 16bits como podemos ver en la figura 2.5.Los registros apuntadores e ındices son:

ESP o SP (Apuntador de pila): se utiliza para direccionar datos en unapila de memoria LIFO (ultimo en entrar, primero en salir). Cada datoalmacenado en la pila es de longitud de 16 bits o 32 bits; cada vez quese introducen datos en la pila por medio de la instruccion de manejode pila (PUSH), el apuntador de pila se decrementa en dos; es decir,avanza hacia direcciones decrecientes; por el contrario, cuando se sacaun dato de la pila por medio de la instruccion de manejo de pila (POP),el apuntador se incrementa en dos.

EBP o BP (Apuntador de base): es un apuntador de uso general quefrecuentemente se utiliza para direccionar a una matriz de datos en lapila direccionada por los registros SS:SP y SS:BP.

ESI o SI (Indice de fuente): Utilizado como registro de ındice en ciertosmodos de direccionamiento indirecto, tambien se emplea para guardarun valor de desplazamiento en operaciones de cadenas.

EDI o DI (Indice de destino): Se usa en determinados modos de direc-cionamiento indirecto, y para almacenar un desplazamiento en opera-ciones con cadenas.

EIP o IP (Apuntador de instrucciones): Marca el desplazamiento dela instruccion en curso dentro del segmento de codigo. Es automatica-mente modificado con la lectura de una instruccion.

12

Page 14: ´Indice general - 148.206.53.231

Figura 2.5: Registro de Apuntadores

Registro de banderas

Cada bit representa una bandera que indica el estado del procesador despuesde ejecutar determinadas instrucciones aritmeticas o logicas a la vez que con-trola su funcionamiento. Algunas banderas se utilizan para controlar ciertascaracterısticas del procesador.

El registro de banderas tambıen tiene un tamano de 32 (EFLAGS) y 16(FLAGS) bits como se muestra en la figura 2.6, pero para fines de este pro-yecto solo hablaremos del registro de 16 bits.

Los bits de bandera para un procesador de 16 bits son los siguientes:

C (Acarreo): se pone a 1 siempre que se genera un acarreo a partirdel bit mas significativo de una operacion aritmetica. La bandera deacarreo tambien indica condiciones de error en ciertos programas yprocedimientos.

P (Paridad): es 1 para un numero par de unos y es un 0 para un numeroimpar de unos con respecto a los ocho bits menos significativos.

A (Acarreo auxiliar): se pone a 1 cuando sucede un acarreo en los 4bits menos significativos de alguna operacion.

Z (Cero): si Z = 1 indica que el resultado de una operacion aritmeticao logica es cero.

13

Page 15: ´Indice general - 148.206.53.231

S (Signo): indica el signo aritmetico del resultado de una suma o unaresta. Si S=1 el resultado es negativo. Este bit esta conectado con elbit mas significativo.

T (Trampa): cuando se activa la bandera de trampa, se activa la ca-racterıstica de depuracion del procesador.

I (Interrupcion): controla el funcionamiento de las interrupciones porhardware. Si I=1 se habilitan las interrupciones, y si I=0 se deshabi-litan. El estado de la bandera I se controla con las instrucciones STI(activar la bandera I) y CLI (desactiva la bandera I).

D (Direccion): controla la seleccion de incremento o decremento de losregistros DI o SI durante las instrucciones de cadenas o arreglos. Si D=1hay decremento en los registros y si D=0 hay incremento. La banderaD se activa con las instrucciones STD (activar direccion) o se borra conCLD (quitar direccion).

O (Sobreflujo): es una condicion que ocurre cuando se suman o restannumeros con signo. Un sobreflujo indica que el resultado ha excedidola capacidad de representacion de la maquina.

Figura 2.6: Registro de banderas

Registros de segmento

Para entender el uso de estos registros es necesario mencionar que hay dostipos de direccionamiento en la memoria, direccionamiento en modo real ydireccionamiento en modo protegido; de estos dos temas se hablara en elsiguiente apartado.

14

Page 16: ´Indice general - 148.206.53.231

Cabe senalar que para propositos de este proyecto solo se detallara el direc-cionamiento en modo real ya que nuestro Sisitema Operativo esta basado enmodo real por esta razon nos enfocaremos al uso de los registros de segmentoen modo real.

El procesador asigna a cada uno de los registros de segmento un significadodeterminado, cada registro de segmento es de 16 bits como se muestra en lafigura 2.7:

CS (Codigo): el registro de segmento de codigo define la direccion inicialde la seccion de memoria que tiene el codigo del programa que estasiendo ejecutado por el procesador en ese momento.

DS (Datos): el segmento de datos es una seccion de la memoria quecontiene la mayor parte de los datos utilizados por un programa.

ES (Extra o adicional): el segmento extra o adicional de datos lo utilizanalgunas instrucciones con cadenas.

SS (pila): el segmento de pila define el espacio de la memoria utilizadapara la pila. La ubicacion del punto inicial de entrada a la pila, sedetermina por el registro apuntador de la pila. El registro BP tambiendirecciona los datos que hay dentro del segmento de pila.

Figura 2.7: Registro de segmentos

15

Page 17: ´Indice general - 148.206.53.231

Notas:1. Las partes sombreadas no estan disponibles en los microprocesadores8086, 8088 y 80286.2. No se dan nombres especiales a los registros FS y GS.

2.1.3. Direccionamiento en modo real

Los microprocesadores 8088, 8086 y 80186 de Intel, nos permiten direccionaral primer MB (MegaByte) de memoria esta caracterıstica es conocida comodireccionamiento en modo real.

Tambien se puede ver que el modo real se caracteriza por:

Un MB es igual a 220 entonces su ancho de canal de direcciones es de20 bits.

El MB de memoria se divide en 16 segmentos de 64kbytes.

Acceso directo del software a las rutinas del BIOS y a perifericos nivelhardware.

No tiene conceptos de proteccion de memoria o multitarea a nivel dehardware.

Todos los microprocesadores x86 y posteriores empiezan en modo real alencenderse el computador. Los microprocesadores mas modernos de Intel(80286 y posteriores) pueden direccionar un mayor numero de localidades dememoria.

Los microprocesadores 8086, 8088 y 80186 solo funcionan en modo real, mien-tras que los microprocesadores a partir del 80386 en adelante para mantenercompatibilidad con el microprocesador 8086 tienen dos formas de operacion:una que simula el direccionamiento en modo real del microprocesador 8086y otro que explota todo el poder del procesador llamado modo protegido.Cuando se simula el modo real cuando se tiene el modo protegido se le cono-ce como modo virtual 8086, este modo permite la ejecucion de programasconcebidos para el modo real. Este modo solo se aplica en las computadoras80386 y modelos posteriores. A cada programa se le atribuye un espacio de1 Mb como en modo real, pero dentro del espacio del modo protegido.

Direccion logica y direccion fısica

Ya que los registros de segmentos son de 16 bits para el 8086 (CS, DS, ES ySS) no se puede direccionar a todas las localidades de la memoria, la solucion

16

Page 18: ´Indice general - 148.206.53.231

a este problema consistio en expresar las direcciones mediante dos palabras de16 bits, denominadas desplazamiento y segmento. Estas palabras se puedenrepresentar mediante un hexadecimal con un rango de 0000H-FFFFH. Elacceso a la memoria se realiza mediante dos direcciones, un segmento y undesplazamiento tambien llamada direccion logica.

Direccion logica = Segmento: Desplazamiento

La direccion fısica consiste en el lugar fısico que ocupa en memoria, estadireccion esta dada por:

Direccion Fısica = Segmento * 0010h + Desplazamiento

Segmentos y desplazamientos

Todas las direcciones de la memoria en modo real consisten en un segmen-to tambıen llamada direccion base y un desplazamiento. La direccion baseubicada en uno de los registros de segmento, define la direccion inicial decualquier bloque de memoria de hasta 64 Kb, este bloque de memoria nonecesariamente es de tamano de 64 Kb puede ser de menor tamano o in-cluso sobrepasar los 64 Kb. La direccion de desplazamiento selecciona unalocalidad dentro del bloque de memoria.

En la Figura 2.8 se muestra un esquema de direccionamiento de segmentomas desplazamiento seleccionando una localidad en la memoria 10000:F0000.

Figura 2.8: Direccionamiento en modo real

17

Page 19: ´Indice general - 148.206.53.231

La direccion del desplazamiento se suma a la del segmento para ubicar unadireccion en el segmento. Un ejemplo de como escribir una direccion de seg-mento mas una direccion de desplazamiento es 1000:2000 para una direccionde segmento de 1000H y un desplazamiento 2000H.

Registros de segmento y desplazamiento implıcito

El microprocesador tiene un grupo de reglas que se aplican siempre que sedirecciona a la memoria. Estas reglas que se aplican en modo real o modoprotegido, definen la combinacion del registro de segmento y de desplaza-miento, que se utilizan en ciertos modos de direccionamiento. Por ejemplo, elregistro de codigo siempre se utiliza con el registro apuntador de instruccio-nes (IP) para direccionar la siguiente instruccion a ejecutar en un programa.Esta combinacion es CS:IP o CS:EIP, segun sea el microprocesador y el modode funcionamiento. Otro direccionamiento implıcito es el de la pila. Se hacereferencia a los datos de la pila por medio del segmento de pila y por locali-dad de la memoria a la cual direcciona el apuntador de la pila (SP/ESP) oel apuntador de base, estas combinaciones se refieren como SS:SP (SS:ESP)o SS:BP (SS:EBP).

2.1.4. Direccionamiento de la memoria en modo pro-tegido

El direccionamiento en la memoria en modo protegido permite acceso a losdatos y programas ubicados arriba del primer MB de memoria. La direcciondel segmento, que se describio en relacion con el direccionamiento de la me-moria en modo real, ya no esta presente en el modo protegido. En lugar dela direccion del segmento, el registro del segmento contiene un selector queselecciona un descriptor; el cual describe la ubicacion, longitud y derechos deacceso al segmento de memoria. Debido a que el registro de segmento y la di-reccion de desplazamiento todavıa acceden a la memoria, las instrucciones enel modo protegido se ven iguales que en modo real. En la practica, la mayorparte de los programas escritos para funcionar en el modo real, funcionaransin ningun cambio en el modo protegido. La diferencia de los dos modos estaen la forma en que el registro de segmento accede a la memoria.

18

Page 20: ´Indice general - 148.206.53.231

Segmento DesplazamientoCS IPSS SP o BPDS BX, DI, SI o un registro de 16 bitsES DI para instrucciones con cadenas

Tabla 2.1: Segmento y desplazamiento implıcitos del 8086-80286

2.1.5. Unidad de control

La unidad de control es la que se encarga de que las instrucciones se ejecutencorrectamente. Estas instrucciones estan en la memoria principal.

La unidad de control genera las senales adecuadas para ejecutar las instruc-ciones contenidas en la memoria de programa.

Una unidad de control cuyas senales estan almacenadas en una memoria sedenomina unidad de control microprogramada. Cada palabra contenida enesa memoria de control contiene una microinstruccion. Una microinstruccionespecifica una o mas microoperaciones; una secuencia de microinstruccionesse llama microprograma o microcodigo. La secuencia de operaciones basicasque se pueden realizar sobre los registros, se llaman microoperaciones.

La Unidad de Control esta compuesta por:

IR o Registro de la instruccion. En este registro se almacena la ins-truccion que va a ser procesada para una posterior ejecucion. Estainstruccion lleva consigo el codigo de operacion.

Decodificador. La salida de la memoria de control de cada registrodebe decodificarse para que proporcione las distintas senales de controlpara ejecutar las microoperaciones; como se puede ver en la fig. 2.9hay un decodificador antes de el registro direcciones de control, estedecodificador sirve para decodificar cada instruccion y que tenga unadireccion asociada a la memoria de control.

Registro direcciones de control. Este registro almacena la direccion don-de se encuentra la microinstruccion dentro de la memoria de control dela instruccion que esta en el registro de instruccion.

Memoria de control. Su contenido esta organizado en palabras de con-trol con formato llamadas microinstrucciones, cada una de la cualesdefine un conjunto de senales de control que se activan durante unciclo de reloj.

19

Page 21: ´Indice general - 148.206.53.231

Logica de secuenciamiento. El generador de la siguiente direccion de lamemoria de control recibe el nombre de secuenciador de un micropro-grama, ya que determina la secuencia de direcciones que se lee de lamemoria de control.

Reloj. Proporcionar una sucesion de impulsos electricos a intervalosconstantes (frecuencia constante), que marcan los instantes en que hande comenzar los distintos pasos de que consta cada instruccion.

Figura 2.9: Unidad de control

La secuencia de senales tiene tres fases llamada ciclo de fetch ver fig. 2.10

Fetch o busqueda de la instruccion. Realiza la busqueda de la instruc-cion en memoria. El procesador extrae la direccion desde el registro

20

Page 22: ´Indice general - 148.206.53.231

apuntador de instrucciones, IP, para conocer la ubicacion de esa ins-truccion. Luego se realiza la lectura de la instruccion, quedando esta enel IR. El IP es incrementado en 1, para tener la direccion de la siguienteinstruccion.

Decodificacion de la instruccion. Ya teniendo el codigo de operacionde la instruccion que se encuentra en el IR, los circuitos de controlinterpretan ese codigo de operacion para determinar que operacion seva a ejecutar y dar las senales de control adecuadas.

Ejecucion de la instruccion. Una vez conocida la instruccion, y el ope-rando o los operandos han sido extraıdo desde memoria, el procesadorejecuta la operacion indicada por el codigo contenida en la instruccion.

Figura 2.10: Ciclo de instruccion

2.1.6. Conjunto de instrucciones

Una instruccion especifica una operacion a realizar. Las instrucciones estancompuestas por un OPCODE (codigo de operacion) y por el contenido de losregistros (operando 1 y operando 2) dependiendo de la instruccion, ya quehay instrucciones que no requieren de ambos operandos o que solo requierende uno, ver Figura 2.11.

21

Page 23: ´Indice general - 148.206.53.231

Figura 2.11: Formato de una instruccion

El OPCODE esta compuesto por unos y ceros pero debido a que esta re-presentacion es difıcil de recordar se crea una representacion mas sencilla derecordar llamada nemonico.

Debido a que el nucleo de sistema operativo, funcionara en modo real sehara hincapie principalmente en el conjunto de instrucciones del microproce-sador Intel 8086.

Estas instrucciones se dividen en categorıas que son:

Transferencia de datos, transfiere bytes o palabras de datos entre lamemoria y los registros ası como entre el acumulador y los puertos deE/S.

Aritmeticas, se suman, restan, multiplican y se dividen datos comobytes o palabras. El sistema suma o resta datos con signo o sin signo ydatos BCD o ASCII.

Manipulacion de bits, las instrucciones para la manipulacion de bitsbinarios se utilizan para controlar los datos hasta el nivel en bits. Estasinstrucciones incluyen operaciones logicas, corrimientos y rotaciones.

Instrucciones para cadenas, las instrucciones para cadenas o arreglosse emplean para manipular cadenas de datos en la memoria. Cada ca-dena consta, ya sea, de bytes o de palabras y tiene hasta 64 Kbytes delongitud.

Transferencia de programa, las instrucciones para transferencia de pro-grama incluyen brincos, llamadas (CALL) y para retorno. Ademas seenumeran algunas instrucciones adicionales para ciclos de programa.

Control del procesador, las instrucciones para control de procesador ha-bilitan y deshabilitan las interrupciones, modifican los bits de banderay sincronizan los eventos externos.

2.2. Memoria

Podemos visualizar a la memoria principal de una computadora como unconjunto de registros cada uno de un byte. Cada registro tiene su propia

22

Page 24: ´Indice general - 148.206.53.231

direccion. Dado que cada direccion es un numero entero, hay una relaciondirecta entre el numero de registros de la memoria y el tamano que debetener una direccion en bits. Una direccion de N bits nos permite direccionar2N direcciones diferentes.

En la memoria principal se almacenan tanto los programas como los datoscon que operan esos programas. Al estar ejecutando un programa, se requierecalcular las direcciones en las que estan almacenadas las instrucciones y datos.El calculo de las direcciones de memoria depende de como el procesadorvisualiza u organiza, la memoria.

En la figura 2.12 podemos ver la forma en que MS-DOS divide la memoria.

Figura 2.12: Mapa de la memoria DOS

23

Page 25: ´Indice general - 148.206.53.231

2.3. Entrada/Salida

El subsistema de entrada-salida de una computadora, denominado E/S, pro-porciona un modo de comunicacion eficiente entre el CPU y los dispositivosexternos. Una computadora no tiene ningun proposito util sin la capacidadde recibir informacion de una fuente externa y de transmitir los resultadosde una manera comprensible.

Los dispositivos de entrada o salida conectados a la computadora tambiense llaman perifericos. Entre los perifericos mas comunes esta el teclado, elmonitor y la impresora.

Un enlace de comunicacion tıpico entre el procesador y varios perifericos semuestra en la fig. 2.13. El canal de E/S, consta de conjuntos lıneas de datos,lıneas de direccion y lıneas de control, a las cuales tambien se les llama bus2.

Figura 2.13: Conexion de canal de E/S

2.3.1. Interfaces de entrada-salida

La interface de entrada-salida proporciona un metodo para transferir datosentre el CPU y los dispositivos de E/S externos. El proposito del enlace decomunicacion, es resolver las diferencias que existen entre la computadora

2El numero de lıneas depende en general del tamano de palabra del microprocesador,

y del espacio de direcciones.

24

Page 26: ´Indice general - 148.206.53.231

central y cada periferico. Las diferencias principales son:

Los perifericos pueden tener una manera de operar diferente a la delCPU y la memoria, por lo tanto puede requerirse una conversion desenales.

La velocidad de transferencia de datos de los perifericos por lo general esmenor que la velocidad de transferencia de la CPU, y en consecuencia,puede necesitarse un mecanismo de sincronizacion.

Los codigos de datos y los formatos de la palabra en los perifericos, sondiferentes del formato de la palabra en la CPU y en la memoria.

Los modos de operacion en los perifericos son diferentes uno de otro, ycada uno debe de estar controlado para no perturbar la operacion deotros perifericos conectados a la CPU.

Para resolver estas diferencias, la computadora incluye componentes de cir-cuiterıa especiales entre la CPU y los perifericos para supervisar y sincronizartodas las transferencias de entrada y salida. Estos componentes se llaman in-terfaces, porque se comunican tanto con el canal del procesador como con eldispositivo periferico.

Las consideraciones anteriores implican que los circuitos de interface de E/Sdeben de realizar las siguientes funciones:

1. Conversion de datos. La conversion de datos se refiere al acople delas caracterısticas fısicas y logicas de las senales de datos. Esto inclu-ye la conversion de senales entre las formas analogicas y digital, o laconversion entre el formato de transmision de datos serie (bit a bit),y los formatos paralelo (palabra a palabra) usados por la mayorıa demicroprocesadores.

2. Sincronizacion. La sincronizacion se necesita para acomodar las diferen-tes velocidades operativas de la CPU, memoria principal y dispositivosde E/S. Esto usualmente requiere en la inclusion en el circuito de in-terface de una o mas palabras de memoria temporal o intermedia. Losdispositivos de E/S y la CPU funcionan independientemente en el sen-tido de que sus relojes internos no estan sincronizados uno con otro.Por ello deben intercambiarse senales de control de conformidad (listo,peticion, reconocimiento, etc.) a traves de los circuitos de interface parainiciar o terminar las operaciones de E/S.

25

Page 27: ´Indice general - 148.206.53.231

3. Seleccion del dispositivo. La seleccion de dispositivo tambien implica elintercambio de senales de control. La seleccion de un dispositivo de E/Spor la CPU puede realizarse de la misma forma que una operacion delectura o escritura en memoria. La CPU situa una palabra de direccionasociada con el dispositivo en cuestion en el bus de direcciones delsistema, y activa las adecuadas lıneas de control de disponible paraentrada (leer) o salida (escribir).

26

Page 28: ´Indice general - 148.206.53.231

Capıtulo 3

El BIOS

El BIOS (Basic Input Output System), disenado para las computadoras IBM-PC compatibles, es un pequeno programa instalado en una memoria ROMque pertenece a la tarjeta principal de la PC. El BIOS cuenta con el conjuntode funciones principales, tambien llamadas rutinas, que utilizan los progra-mas para poder comunicarse tanto con el hardware como con los dispositivosperifericos conectados, esto disminuye la complejidad de la programacion, yaque el BIOS proporciona el acceso a las caracterısticas basicas del hardware.

IBM definio un mecanismo para realizar las llamadas a las diferentes rutinasdel BIOS, la cual se le llama Interrupciones por software; define la forma decomo son invocadas y de como se realiza el paso de parametros, del cual sehablara mas adelante.

Otro de los procedimientos que lleva a cabo el BIOS, es comprobar que el sis-tema este funcionando correctamente e inicializar los diferentes componentesde hardware, a este procedimiento se le conoce como POST o Power On SelfTest. Si durante las pruebas que realiza el POST se detecta un error (nor-malmente emite un sonido de aviso), en el monitor aparecera el mensaje deerror correspondiente y/o un codigo de error. Despues de haber comprobadoel estado de los dispositivos, se inicializan las variables del BIOS y la tablade vectores de interrupcion.

Despues del POST hay un proceso conocido como boostrap loader, que intentacargar el programa de arranque desde un punto determinado en algun dispo-sitivo (floppy, USB, RED, disco duro, CD), este programa de arranque es ensı el sistema operativo; de no encontrar ninguna unidad de almacenamientoque contenga alguna rutina de arranque, el boostrap loader fracasara.

27

Page 29: ´Indice general - 148.206.53.231

3.1. Interrupciones

Las interrupciones son un mecanismo por el cual un evento interno o externoasıncrono, solicita al CPU ser atendido, dependiendo de la interrupcion quese esta invocado, la CPU suspende la ejecucion del programa actual y ejecu-tara la rutina de atencion correspondiente. En la memoria existe una zonaque contiene las direcciones de las rutinas de atencion de cada interrupcion,llamada tabla de vectores de interrupcion; la CPU extrae de esta tabla ladireccion de la rutina del servicio de interrupcion, ejecuta la rutina, y cuan-do termina de ejecutarse, el programa que se suspendio continuara con suejecucion. En la fig. 3.1 se observa el proceso de atencion a la interrupcionmencionado anteriormente.

Figura 3.1: Proceso de atencion de una interrupcion.

28

Page 30: ´Indice general - 148.206.53.231

Existen 3 tipos de interrupciones las cuales se listan a continuacion:

Interrupciones por software. Este tipo de interrupciones son in-vocadas de forma explıcita dentro de un programa para hacer que seejecute un servicio, que puede ser proporcionado por el BIOS, el sis-tema operativo o algun otro proceso; esto se logra por medio de lainstruccion especial INT, seguido del numero de interrupcion. Al eje-cutar esta instruccion, la CPU toma el numero y extrae de la tabla devectores de interrupcion la direccion en donde se localiza el procedi-miento que atendera la interrupcion, y una vez que se haya ejecutadopodra continuar la ejecucion del programa que llamo a la interrupcion.

Interrupciones por hardware. Cuando un dispositivo de hardwarerequiere de la atencion del CPU1, hace una solicitud al controlador deinterrupciones, mediante su lınea de interrupcion (un pin en el micro-controlador); el controlador de interrupciones le indica a la CPU queinterrumpa la ejecucion del programa actual, extrae del vector de inte-rrupciones la direccion correspondiente a la rutina de atencion, y pos-teriormente ejecutara la rutina y regresara a la ejecucion del programaque se interrumpio. Sin embargo, existen interrupciones por hardwarelas cuales son llamadas enmascarables que tienen la propiedad de po-der ser inhabilitadas, lo cual implica que el CPU ignorara la solicitud;por otro lado hay interrupciones por hardware que se conocen como noenmascarables, las cuales no pueden ser inhabilitadas, estas se empleandentro de la PC en situaciones que requieren de toda la atencion delCPU, por ejemplo un fallo en la memoria.

Internas o excepciones. Durante la ejecucion de un programa puedensurgir circunstancias especiales dentro de la CPU, como por ejemplola division entre cero, o acceder a una direccion de memoria no per-mitida, por citar algunas; cuando esto sucede, el procesador genera loque se llama una excepcion, que sera tratada de forma similar a lasinterrupciones por hardware. Pero las excepciones no solo se producenpor un fallo, sino tambien para cubrir ciertas necesidades, por ejemplola depuracion de un programa.

Algunas interrupciones importantes a mencionar son las siguientes:

INT 0. Es generada por la CPU cuando en una division el divisor es ceroo cuando el cociente es demasiado grande como para ser almacenadoen el registro destino.

1Por ejemplo cuando un usuario presiona una tecla o mueve el mouse.

29

Page 31: ´Indice general - 148.206.53.231

INT 10H. Establece el modo video, es decir Entrada/Salida de pantalla.Esta interrupcion ejecuta diferentes servicios segun el valor que se leasigne al registro AH. Algunos servicios se muestran en la Tabla 3.1:

Servicio Descripcion00 Asignar modo de video01 Asignar modo de cursor02 Situar posicion del cursor03 Leer posicion del cursor08 Obtener atributo y caracter en el cursor09 Escribir atributo y caracter en el cursor0A Escribir unicamente caracter en el cursor

Tabla 3.1: Tabla de servicios de INT 10H

INT 21H. Interrupcion del DOS, tiene distintos servicios los cuales sonaccedidos mediante el registro AH. En la Tabla 3.2 se pueden ver algu-nos servicios que ofrece el sistema operativo MS-DOS.

Servicio Descripcion00 Terminacion de programa01 Entrada de caracteres con eco02 Salida de caracteres06 E/S directa de consola25 Asignar vector de interrupcion30 Obtener numero de version MS-DOS35 Obtener vector de interrupcion

Tabla 3.2: Tabla de servicios de INT 21H

3.2. Controlador de interrupciones 8259

El controlador de interrupciones tiene como mision recibir las solicitudes pro-venientes del hardware y transmitirlas al CPU; para realizar esta tarea, elcontrolador de interrupciones tiene varios pines de entrada por los cuales re-cibe las peticiones de interrupcion de los diferentes dispositivos de hardware,estas lıneas son llamadas IRQ (Interrupt ReQuest). Cada controlador posee8 IRQ’s enumeradas de la 0 hasta la 7, estos numeros tambien representanprioridades de tal manera que la IRQ0 tiene la prioridad mas alta, y la IRQ7

30

Page 32: ´Indice general - 148.206.53.231

tiene la mas baja2 ; las prioridades son de gran utilidad ya que cuando masde un dispositivo de hardware manda una senal de interrupcion (y debidoa que el procesador no puede atender a mas de un dispositivo a la vez), elcontrolador de interrupciones toma la IRQ que tenga la prioridad mas altay esa es la que atendera la CPU, posteriormente el orden de ejecucion de lasdemas interrupciones sera una detras de otra, formadas segun su prioridad,desde la mas alta a la mas baja.

3.3. Temporizador 8254 (U8254)

Una de las caracterısticas de un sistema operativo moderno, es que este cuen-ta con la capacidad de ejecutar mas de un programa de manera simultanea,es por esta razon que es importante incluir al temporizador 8254, ya queeste dispositivo consta de tres temporizadores que pueden ser programadospara ejecutar una interrupcion cada determinado tiempo y ası temporizarlos programas que se encuentran en ejecucion, y posteriormente permitir lasincronizacion de los mismos. Cada temporizador es de 16 bits y operan auna frecuencia de 1.193MHz aproximadamente, los cuales pueden contar enbinario o en decimal codificado (BCD). La descripcion del circuito es la si-guiente:

Figura 3.2: Temporizador U8254

D7-D0: Bus de datos bidireccional de 3 estados, conectado tambien albus de datos del sistema.

CLK 0: Entrada de reloj del temporizador 0.

2Sin embargo, es posible cambiar el esquema de prioridades.

31

Page 33: ´Indice general - 148.206.53.231

OUT 0: Salida del temporizador 0.

GATE 0: Puerta de entrada del temporizador 0.

WR3 : Entrada de control de escritura, permite al 8254 recibir datosde la CPU cuando la senal es baja.

RD: Entrada de control de lectura, permite enviar datos a la CPUcuando la senal es baja.

CS: Entrada de habilitacion de chip, permite habilitar el 8254 a lassenales RD y WR cuando la entrada es baja, en otro caso las ignora.

A1, A0: Entradas para seleccionar uno de los 3 temporizadores, o elregistro de la palabra de control: con 00, se selecciona el temporizador0; con 01, el temporizador 1; con 10 el temporizador 2; y con 11, elregistro de la palabra de control.

CLK 1: Entrada de reloj del temporizador 1

OUT 1: Salida del temporizador 1.

GATE 1: Puerta de entrada del temporizador 1.

CLK 2: Entrada de reloj del temporizador 2.

OUT 2: Salida del temporizador 2.

GATE 2: Puerta de entrada del temporizador 2.

Comunmente cada uno de los temporizadores se utiliza de la siguiente ma-nera:

Temporizador 0: Se programa para generar una interrupcion 18.2 vecescada segundo (interrupcion 8), esto produce un pulso (tic) de reloj. Elpulso se utiliza comunmente para temporizar programas y eventos.

Temporizador 1: Se programa para una salida de 15 microsegundos quees utilizado para refrescar la memoria RAM.

Temporizador 2: Se programa para generar un tono en la bocina de lacomputadora.

3Las senales que tienen barra superior se activan con una senal baja, es decir un 0

logico.

32

Page 34: ´Indice general - 148.206.53.231

3.4. Temporizador 0, 1 y 2

Los 3 temporizadores son identicos en su funcionamiento, independientesentre ellos y que tambien pueden ser programados en modalidades diferentes.El diagrama interno de bloques se puede ver en la fig. 3.3, en donde seobservan las partes que lo conforman y que describimos a continuacion:

Palabra de control: Permite controlar el funcionamiento de los tempo-rizadores.

Registro de estado: Contiene el valor del registro de la palabra de con-trol y el estado de salida.

CE (Counting Element): Este es un registro contador sıncrono descen-dente de 16 bits que puede ser modificado.

OLM y OLL (Output Latch): Son dos latch de 8 bits que forman partedel registro OL, donde OLM representa al byte mas significativo, mien-tras que OLL el byte menos significativo; estos dos latches siguen lacuenta descendente del registro CE, aunque la CPU puede enviar unasenal para congelar la cuenta por un momento y ası ser leıda medianteel registro OL.

Logica de control: Encargada de que un solo latch este activo en deter-minado tiempo, ya que el bus interno del 8254 es de 8 bits; la gestion dela conexion con el exterior se realiza a traves de los pines CLK, GATEy OUT.

CRM y CRM (Count Register): Son dos latch de 8 bits que en unionconforman el registro CR; CRM representa el byte mas significativo,mientras que CRL es el byte menos significativo; estos latches tienenel objetivo de almacenar la cuenta del contador que posteriormentesera enviada a CE.

33

Page 35: ´Indice general - 148.206.53.231

Figura 3.3: Diagrama de bloques internos del temporizador

3.4.1. Modos de Operacion

Cada temporizador puede trabajar en uno de 6 posibles modos (modo 0 -modo 5). A continuacion se describen cada uno de ellos:

1. Modo 0. Permite utilizar el temporizador como contador de eventos.Despues de que se escribe la palabra de control y el valor de cuentaN, la salida es 0 logico constante hasta que el valor de cuenta llegue acero, entonces cambiara la salida a 1; y permanecera en 1 hasta que seintroduzca una nueva cuenta o palabra de control; por ejemplo, si seintroduce una cuenta inicial de 6, la salida sera baja durante 6 ciclosde reloj.

2. Modo 1. El temporizador funciona como multivibrador monoestable(genera un tren continuo de pulsos cuadrados). Cuando se configurael dispositivo mediante la palabra de control y el valor de cuenta N,el temporizador produce una salida alta continua, hasta que llegue unflanco de subida GATE, enseguida la salida sera baja durante los si-guientes N ciclos de CLK. Posteriormente la salida sera alta hasta quese produzca otro flanco de subida en GATE; si durante un pulso de sa-lida, GATE realiza un nuevo flanco de subida, se reiniciara nuevamente

34

Page 36: ´Indice general - 148.206.53.231

la cuenta. Por ejemplo: si se da un valor de cuenta 4, el temporizadordara una salida alta a la espera de que GATE dispare el conteo conun flanco de subida, cuando este llegue, la salida sera baja durante lossiguientes 4 ciclos de CLK, inmediatamente despues la salida sera alta,a la espera de otro flanco de subida de GATE.

3. Modo 2. El temporizador funciona como generador de ritmo, empleadotıpicamente para las interrupciones de los relojes en tiempo real; cuandose configura el dispositivo mediante su palabra de control y el valor decuenta N, se comienza con una salida alta, cuando N llega a 1, la salidasera baja durante un pulso de CLK, tras ello volvera la salida a unasenal alta y recargarse la cuenta para volver a iniciar el ciclo; si la senalde GATE es baja durante un pulso de salida, la salida sera puestaen alta inmediatamente, mientras que un flanco de subida de GATErecargara la cuenta en el siguiente ciclo de CLK. Por ejemplo, si elvalor de cuenta es 5, la salida sera alta durante los siguientes 4 pulsosde reloj, posteriormente en el pulso de CLK siguiente la salida sera bajaen inmediatamente se recargara la cuenta y se repite el ciclo.

4. Modo 3. Este modo, genera una onda cuadrada continua en la salida,mientras el valor de GATE sea alto. Si el conteo es par, la salida es altadurante la primera mitad del conteo, y baja durante la segunda mitad;si es impar, la salida es alta durante un periodo de CLK mas largo quecuando es baja. Si en el transcurso del funcionamiento del contadorse escribe un nuevo valor de cuenta, no afecta la cuenta actual; si serecibe un flanco de subida de GATE antes del final del medio-perıodo,el contador se recargara con ese nuevo valor de cuenta tras el proximopulso de CLK y volvera a comenzar, en caso contrario se recargara conel nuevo valor tras finalizar con normalidad el medio-ciclo en curso. Porejemplo, si el conteo es de 7, la salida sera alta en los primeros 4 pulsosde reloj, y baja en los siguientes 3.

5. Modo 4. El temporizador produce un solo pulso de salida alto durante N+ 1 ciclos de CLK, donde N es el valor de conteo introducido, despuesla salida es baja durante un solo periodo de CLK, para nuevamenteproducir un solo pulso de salida. Por ejemplo, si se introduce un valorde cuenta de 7, la salida sera alta durante los siguientes 8 ciclos deCLK, bajara en el siguiente ciclo y volvera a subir para mantenerseahı.

6. Modo 5. El temporizador se comporta como un multivibrador mono-estable disparado externamente, parecido al modo 4, excepto por que

35

Page 37: ´Indice general - 148.206.53.231

necesita una senal de disparo.

3.4.2. Programacion del temporizador

Para programar un temporizador en alguno de los modos antes mencionados,primero se tiene que escribir una palabra de control al puerto 43h4 parahabilitar los pines del bus de direcciones A1 y A0, seguido de un conteo inicialen el puerto correspondiente al temporizador que se programara; se utiliza ladireccion 40h para el temporizador 0, 41h para el temporizador 1 y 42h parael temporizador 2. En la fig. 3.4 esta presente la palabra de control, de la cualse observa como estan agrupados los bits que la conforman y que explicamosa continuacion: BCD (ver tabla 3.3), permite seleccionar el tipo de cuenta, 0binario y 1 BCD; Seleccion de modo (ver tabla 3.4), que permite utilizar altemporizador en uno de los 6 modos de operacion mencionados anteriormentey esta conformado por M0, M1 y M2; control de lectura/escritura (ver tabla3.5), en el que se establece si se desea escribir o leer la cuenta y esta compuestopor RW0 y RW1; seleccion de contador (ver tabla 3.6), en el cual se especificael contador a seleccionar o tambien si se debe obtener la cuenta actual deltemporizador, esta conformado por SC0 y SC1.

Figura 3.4: Estructura de la palabra de control

4Recordemos que el 8254 requiere de algunas senales para poder acceder a sus registros

de control, de tal manera que esta conectado al bus de direcciones por los pines A1 y

A0, y la UC esta configurada de tal forma que genera Chip-Select solo en determinadas

direcciones para activar el 8254; de ahı que se empleen las direcciones 40H para acceder

al 8254.

36

Page 38: ´Indice general - 148.206.53.231

BCD Seleccion de conteo0 Conteo binario de 16 bits1 Codigo binario decimal (BCD) de 4 decadas

Tabla 3.3: Seleccion de conteo.

M2 M1 M0 Seleccion de modo0 0 0 Modo 00 0 1 Modo 1X 1 0 Modo 2X 1 1 Modo 31 0 0 Modo 41 0 1 Modo 5

Tabla 3.4: Seleccion del modo de operacion.

RW1 RW0 Control de lectura/escritura0 0 Capturar cuenta0 1 Lectura/escritura solo del byte menos significativo1 0 Lectura/escritura solo del byte mas significativo1 1 Primero el byte menos significativo de lectura/es-

critura, luego el byte mas significativo

Tabla 3.5: Control de lectura y escritura

SC1 SC0 Seleccion de contador0 0 Contador 00 1 Contador 11 0 Contador 21 1 Obtener cuenta actual del temporizador

Tabla 3.6: Seleccion de contador u obtener cuenta

Para ejemplificar mejor la programacion de los temporizadores, los siguientespasos y la fig. 3.5 muestran como programar el temporizador 0 en el modo 3:

1. Ingresamos la palabra de control 00110110 (36 en hexadecimal) en elpuerto 43h. Lo que indica esta palabra de control es: elegir al contador0, primero el byte menos significativo del valor de cuenta, luego el bytemas significativo del valor de cuenta, modo 3 (onda cuadrada continua),y conteo en binario.

37

Page 39: ´Indice general - 148.206.53.231

2. A continuacion se ingresa el valor de cuenta, y dado que se eligio ingre-sar primero el byte menos significativo y luego el byte mas significativo,enviamos al puerto 40h el valor de cuenta inicial del byte menos sig-nificativo, y despues enviamos nuevamente al puerto 40h el byte massignificativo.

Para ejemplificar de mejor manera los pasos anteriores, a continuacion esta elcodigo fuente.

...

;Valor de cuenta

mov dx, 0FFFFH

;Palabra de control

mov al, 036h

;Al puerto 43 para poder programar el temporizador 0

out 043h, al

mov al, dl

;Enviamos primero la parte baja de la cuenta

out 040h, al

mov al, dh

;Ahora la parte alta

out 040h, al

...

Figura 3.5: Programacion del temporizador 0 en modo 3

38

Page 40: ´Indice general - 148.206.53.231

Capıtulo 4

Sistema Operativo

Un sistema de computo se puede representar como un modelo de capas com-puesto por (ver Fig. 4.1):

Hardware, La capa de hardware proporciona los recursos de compu-tacion necesarios para ejecutar las instrucciones de los programas deusuario, esta capa solo interactua con el sistema operativo.

Sistema Operativo, esta capa funciona como intermediario entre elhardware y los programas de usuario.

Programas de Usuario, La capa de programas de usuario son el conjuntode instrucciones que apoyandose en la capa de sistema operativo deter-minan la forma de como se van a utilizar los recursos de la computadora(memoria, CPU, dispositivos de E/S, etc.) para resolver los problemasde usuario, apoyandose en la capa de sistema operativo.

Figura 4.1: Modelo de capas de un sistema de computo

39

Page 41: ´Indice general - 148.206.53.231

El sistema operativo es un intermediario entre el hardware y el usuario, elsistema operativo funciona de tal manera que el usuario no tenga que preo-cuparse por el manejo de la memoria, dispositivos de E/S, interrupciones,etc., con esto se quiere decir que el sistema operativo es un programa que seencarga de administrar los recursos de la computadora (memoria, tiempo deCPU, E/S, etc.), los programas del usuario y de proporcionar una interfazal usuario para que se pueda comunicar con el hardware de la computadora1. El sistema operativo debe de contar con los mecanismos necesarios paraque los programas del usuario puedan hacer uso de los recursos de la compu-tadora de forma adecuada y eficiente, de tal manera que, al haber mas deuna solicitud de recursos, se tiene que tomar la decision de a quien se lesasignaran.

4.1. Estructura del Sistema Operativo

Un sistema oprativo en base a su diseno e implementacion puede tener unaestructura monolitica, en capas o microkernel.

1. Monolitico. Este fue uno de los primeros tipos de sistemas operati-vos desarrollados, el cual consistıa de un solo programa que a su vezcontenıa varios procedimientos, los cuales eran invocados unos a otros;este tipo de sistema operativo no estaba modularizado por lo cual tenıamuchas lıneas de codigo en un solo programa y hacıa muy difıcil la in-troduccion de nuevas caracterısticas o modificar las que ya tenıa.

2. Capas. Es una estructura en capas jerarquica en donde cada capa secomunica adyacentemente, es decir la capa N no se puede comunicarcon la capa N-2, la capa mas baja (capa 0), es el hardware y la mas alta(capa N) es la interfaz de usuario, esta estructura hace menos complejoel sistema y mas escalable, ver Fig. 4.2.

1 Stalling William, “Sistemas Operativos” Quinta Edicion, Prentice Hall

40

Page 42: ´Indice general - 148.206.53.231

Figura 4.2: Nucleo por Capas

3. Microkernel. En esta estructura se encuentran las funciones esencialesdel sistema operativo en el nucleo. Los servicios y aplicaciones menosesenciales se contruyen sobre el micronucleo y se ejecutan en modousuario, ver Fig. 4.3.

Figura 4.3: Microkernel

4.2. Componentes del Sistema Operativo

El sistema operativo esta compuesto por 3 capas principales que son:

nucleo o kernel es el encargado de gestionar los recursos, tiene la maxi-ma autoridad para acceder a los recursos de la computadora, ademasde suministrar la funcionalidad principal del sistema operativo.

capa de servicios es una interfaz de programacion que ofrece algunasfunciones a los programas de usuario, para que estos puedan apoyarseen ellas.

41

Page 43: ´Indice general - 148.206.53.231

capa de shell (tambien llamado interprete de comandos) es la interfazque permite al usuario comunicarse con la computadora. Cuando elusuario proporciona las ordenes, el shell las recibe, las interpreta, yfinalmente dependiendo de la orden le muestra o no un resultado alusuario.

Para que los recursos de la computadora se puedan aprovechar de maneraeficiente se necesita que el sistema operativo tenga la capacidad de cargary ejecutar varios programas de forma concurrente por esta razon surge laadministracion de los programas.

4.3. Administracion de procesos

La administracion de procesos es una de las partes mas importantes delsistema operativo, su funcion principal es crear y eliminar procesos, gestionarlos procesos, y responder a las peticiones de recursos que los procesos realizan.Antes de continuar con la explicacion sobre la administracion de procesos, esnecesario definir el concepto de proceso.

4.3.1. Definicion de proceso

Un proceso es basicamente un programa en ejecucion (tambien consideradocomo la unidad de trabajo del sistema operativo). Un proceso necesita quese le asignen recursos (como memoria, CPU, disco duro, etc.) para poderejecutarse; los recursos se le pueden otorgar cuando se crea o posteriormentecuando comienza su ejecucion.

Existen distintas situaciones por las cuales los procesos no pueden ser ejecu-tados completamente en un solo paso por ejemplo, para que los procesos nomonopolicen el procesador, o bien si se desea contar con un sistema en dondepuedan interactuar mas de un usuario (sistemas de tiempo compartido), portal motivo se dice que un proceso puede pasar por diferentes estados durantesus ciclo de vida por esta razon se creo el modelo de estados que se describeen la siguiente seccion.

4.3.2. Modelo de estados

Hay 3 estados principales, los cuales son: listo, ejecucion y bloqueado; en laFig. 4.4 se pueden observar los 3 estados, ademas de transiciones que hayentre ellos.

42

Page 44: ´Indice general - 148.206.53.231

Figura 4.4: Modelo de 3 estados

En este modelo de 3 estados, cuando un proceso se crea inmediatamente suestado es de listo, y esperara a que se le asigne tiempo de procesador. Desdeel estado de listo un proceso cambia al estado de ejecucion cuando le tocatiempo de CPU. O bien un proceso en el estado de ejecucion puede pasar alestado de listo cuando se detecta que el proceso ha ocupado el tiempo maximode CPU que se le asigno. Tambien del estado de ejecucion, se puede pasar alestado de bloqueado cuando el proceso solicita, por ejemplo, una operacionde entrada/salida. O bien cuando ocurre el suceso que estaba esperando elproceso que se encuentra en el estado de bloqueado, su estado cambia alisto. Finalmente cuando el procesador ha terminado de ejecutar todas lasinstrucciones del proceso que se encuentra en el estado de ejecucion o haocurrido un error irrecuperable, el proceso da por terminada la ejecucion delproceso.

Ademas del modelo de 3 estados, existen mas modelos de estados que per-miten aprovechar mejor los recursos de la computadora2.

Para poder tener varios procesos en el modelo de estados se crearon las colasde procesos que se explican en la siguiente seccion.

4.3.3. Colas de procesos

Para representar los estados de listos y bloqueados, se puede utilizar la es-tructura de datos cola doblemente ligada (una cola para cada estado). Enla Fig. 4.5 se observa que cada nodo mantiene informacion de un proceso.

2 Para mayor detalle consultar algun libro de sistemas operativos indicados en la bi-

bliografıa.

43

Page 45: ´Indice general - 148.206.53.231

Ademas se tienen 2 apuntadores uno al primer elemento de la cola (cabeza)y otro al ultimo elemento de la cola (final).

Figura 4.5: Estructura de la cola

La informacion de cada proceso, se almacena en una estructura de datosllamada Bloque de control de procesos o BCP.

4.3.4. Bloque de control de proceso (BCP)

El bloque de control de proceso es una estructura que almacena la informa-cion de cada proceso. Esta informacion puede ser:

Informacion contable. Contiene el identificador de proceso (unico) einformacion de tiempos de CPU del proceso.

Estado del proceso. Identifica el estado en el que se encuentra elproceso de acuerdo al modelo de 3 estados.

Contador de programa. Contiene la direccion de la siguiente ins-truccion del proceso a ejecutar.

Registros de CPU. Contiene registros de proposito general, regis-tros de ındice y apuntadores de pila (pueden variar de acuerdo a laarquitectura).

Informacion de planificacion de la CPU. Contiene la informaciondel planificador de procesos utilizado (en el siguiente parrafo se explicacon mas detalle esto).

Informacion de administracion de memoria. Contiene la infor-macion de la memoria que esta ocupando el proceso.

44

Page 46: ´Indice general - 148.206.53.231

Informacion del estado de E/S. Contiene una lista de los recursosde E/S que estan asignados al proceso.

4.3.5. Planificador de procesos

El planificador de procesos es un modulo del sistema operativo que se encargade decidir en que orden se deben de ejecutar los procesos de la cola de listos.El principal objetivo del planificador es optimizar el rendimiento del sistema.Entre las medidas de rendimiento y criterios de optimizacion de un planifi-cador estan las siguientes: reparto equitativo del procesador, optimizaciondel uso del procesador, menor tiempo de respuesta en uso interactivo, menortiempo de espera, mayor numero de trabajos por unidad de tiempo, etc.

4.3.6. Cambio de contexto

Cuando el planificador le quita la CPU al proceso que lo esta ocupando y selo asigna a otro, es necesario almacenar los registros de CPU; contador deprograma, por citar algunos los cuales posteriormente ayudaran a retomar laejecucion del proceso. Cuando se le vuelva asignar CPU; se carga la informa-cion previamente almacenada del proceso al que se le asignara CPU para quecontinue con su ejecucion. A esta tarea se le denomina cambio de contexto.

Existen diferentes polıticas de planificacion, la seleccion de estas polıticaspuede estar basada en prioridades, requisitos sobre los recursos, o las carac-terısticas de ejecucion del proceso. Los algoritmos de planificacion puedenestar clasificados en dos categorıas:

Sin expulsion. Los procesos no son expulsados del procesador sin con-cluir su ejecuacion.

Con expulsion. Los procesos son expulsados del procesador antes deconcluir su ejecucion.

A continuacion se explicaran algunos algoritmos de planificacion.

Algoritmo primero en llegar, primero en ser atendido

En el planificador FCFS o First Come First Serve los procesos se van forman-do en la cola de listos (cola FIFO), y el planificador se encarga de seleccio-narlos y ejecutarlos en orden de llegada. Uno de los inconvenientes que tieneeste algoritmo, es que el tiempo de espera promedio en la cola de procesos eslargo. Ejemplo:

45

Page 47: ´Indice general - 148.206.53.231

Supongamos que tenemos los siguientes procesos de la Tabla 4.1 con susrespectivos tiempos de ejecucion. Los procesos llegan en el tiempo 0 en elorden: P2, P1, P3, P4. Aplicando el algoritmo de planificacion FCFS (verFig. 4.6) obtenemos el siguiente orden de ejecucion:

Proceso Tiempo de ejecucion (ms)P1 3P2 19P3 7P4 3

Tabla 4.1: Tabla de procesos

Figura 4.6: Ejemplo FCFS

El tiempo de espera para P2 fue de 0 ms, para P1 de 19 ms, para P3 de 22 msy para P4 de 29ms. El tiempo promedio de espera para este orden de llegadaes de 15 ms 3.

Algoritmo de prioridades

Para implementar este algoritmo, cada proceso debe tener un numero dentrode algun intervalo fijo preestablecido, que identifique el nivel de prioridad oimportancia que este tiene con respecto a los demas. Estas prioridades puedenser estaticas o dinamicas. Si la prioridad es estatica, no cambiara durantela vida del proceso, mientras que la prioridad dinamica si puede hacerlo.Los valores iniciales de prioridad pueden ser asignados tanto por el sistemaoperativo o por el usuario.

El algoritmo consiste en seleccionar de la cola de listos al proceso con priori-dad mas alta, para posteriormente ejecutarlo; si hay mas de un proceso conla prioridad mas alta, se debera seguir alguna polıtica de seleccion; por ejem-plo, seleccionar al proceso mediante el algoritmo FCFS. Uno de los problemas

3Nota: Suponemos que el tiempo que ocupa el cambio de contexto es 0 ms

46

Page 48: ´Indice general - 148.206.53.231

que tiene este algoritmo es que los procesos con prioridad muy baja puedennunca ser ejecutados, a esto se le conoce como inanicion. A continuacion seobserva un ejemplo de su funcionamiento.

Ejemplo:

Supongamos que al tiempo 0 llegan en este orden los siguientes procesos P2,P1, P3 y P4; en la Tabla 4.2 estan los tiempos de ejecucion y la prioridad quecada uno tiene.

Proceso Tiempo de ejecucion (ms) PrioridadP1 3 4P2 19 3P3 7 2P4 3 2

Tabla 4.2: Tabla de procesos

Aplicando el algoritmo de planificacion de prioridades, obtenemos orden deejecucion de la Fig. 4.7

Figura 4.7: Ejemplo Prioridades

El tiempo de espera para P3 es de 0 ms, para P4 de 7 ms, para P2 de 10 msy para P1 de 29. El tiempo promedio de espera para este orden de llegadaes de 11.5 ms

Algoritmo Round-Robin

El algoritmo Round- Robin (tambien conocido como planificador circular)consiste en repartir equitativamente el uso de CPU a todos los procesos,dandoles una porcion de tiempo fijo llamado quantum. El planificador realizael cambio de contexto cuando el proceso en ejecucion agota su quantum,o bien, cuando el proceso realiza una peticion de entrada/salida; entoncesel planificador tomara al siguiente proceso de la cola de listos. Un procesotermina su quantum cuando se genera una interrupcion por parte de un

47

Page 49: ´Indice general - 148.206.53.231

temporizador entonces el planificador forma en el final de la cola al procesoque ocupaba la CPU.

El desempeno de este algoritmo depende del tamano del quantum, si estevalor es muy pequeno, dara lugar a interrupciones y cambios de contextomuy constantes, lo que provocara que los procesos tarden mas en terminarde ejecutarse por completo; por otra parte, si el quantum es muy grande, lostiempos de espera promedios seran muy largos (el algoritmo tendra ciertasimilitud con el algoritmo FCFS).

Ejemplo:Consideremos que tenemos el siguiente conjunto de procesos en la Tabla 4.3con sus respectivos tiempos de ejecucion.

Proceso Tiempo de ejecucion (ms)P1 3P2 19P3 7P4 3

Tabla 4.3: Tabla de procesos

Y que llegan todos en el tiempo 0 en el siguiente orden: P2, P1, P3, P4.Supongamos que tenemos un quantum de 5 ms.

Aplicando el algoritmo de planificacion Round- Robin, obtenemos el siguienteorden de ejecucion que se muestra en la Fig. 4.8:

Figura 4.8: Ejemplo Round Robin

Nota: supongamos que el tiempo que ocupa el cambio de contexto es 0 ms

4.4. Administracion de memoria

En un sistema con multiprogramacion, el sistema operativo se encarga deasignar y administrar los recursos del sistema de la manera mas segura,

48

Page 50: ´Indice general - 148.206.53.231

transparente y eficientemente posible entre los procesos; entre estos recursosse encuentra la memoria. El administrador de memoria es la parte del sistemaoperativo que se encarga de asignar la memoria entre los procesos.

Dentro de los objetivos principales de administracion de memoria se encuen-tran los siguientes:

Reubicacion

Proteccion

Comparticion

Organizacion logica

Organizacion fısica

4.4.1. Reubicacion

En un sistema con multiprogramacion, la memoria disponible se comparteentre varios procesos. Normalmente el programador no sabe anticipadamente,donde seran ubicados sus programas en la memoria en tiempo de ejecucion.Ahora bien, las instrucciones que contienen los procesos, por lo general, hacenreferencia a posiciones de memoria como: referencias a datos empleados en elmismo programa, ya sea para carga de datos, almacenamiento, instruccionesaritmetico-logicas, o incluso referencias a otras instrucciones utilizadas prin-cipalmente en control de flujo e instrucciones de llamadas. Estas referenciasa posiciones de memoria mencionadas pueden no ser fijas durante toda lavida del proceso, ya que los procesos pueden ser desplazados a otra posi-cion de memoria, por lo que es necesario reubicar estas referencias hacia lasposiciones de memoria donde se hayan movido.

4.4.2. Proteccion

Consiste en proteger a los procesos de interferencias (accidentales o intencio-nales) de otros procesos. Por lo tanto, los procesos no deben ser capaces dereferenciar sin permiso posiciones de memoria de un proceso.

4.4.3. Comparticion

Cuando hay mas de un proceso ejecutandose, en ocasiones es ventajoso per-mitir que cada proceso tenga el privilegio de acceder a la misma copia del

49

Page 51: ´Indice general - 148.206.53.231

programa que tienen los demas, en lugar de tener su propia copia separa-da. Por lo tanto, el sistema de gestion de memoria debe permitir el accesocontrolado a areas de memoria compartidas sin comprometer la proteccionesencial.

4.4.4. Organizacion logica

Aunque comunmente las memorias estan organizadas linealmente con undireccionamiento secuencial, esto no corresponde con la estructura que tie-nen los programas, ya que en general, estos estan compuestos por diferentesmodulos (funciones, procedimientos, etc). La administracion de memoria de-be tratar de forma efectiva a los programas de usuario y los datos en la formade modulos de algun tipo. Con esto se tiene la ventaja de cargar y compilar acada modulo de forma independiente, ası como tener acceso directo al mismo.

4.4.5. Organizacion fısica

Debido al costo de almacenamiento de una memoria principal rapida, seutiliza una memoria secundaria (como pueden ser discos duros) mucho maslenta (y por consiguiente, barata) con el fin de extender su capacidad. Estaclasificacion de la memoria hace necesario que el administrador de memoriatome el control sobre la informacion entre esas dos clases de memoria.

4.4.6. Particionamiento de memoria

En la mayorıa de los esquemas de gestion de memoria se puede suponer queel SO ocupa una parte de la memoria principal y el resto de la memoriaesta disponible para ser utilizada por los procesos de usuario. A continuacionse presentaran algunas tecnicas para particionar ese espacio libre de memoria.

Particionamiento fijo

El esquema mas sencillo de gestion de la memoria es dividirla en regiones conlımites fijos. Una posibilidad es emplear particiones fijas de igual tamano,en este caso cualquier proceso con tamano menor o igual al tamano de laparticion puede cargarse en cualquier particion libre, si todas las particionesestan ocupadas el SO puede sacar un proceso de alguna de ellas y cargarotro. La utilizacion de particiones fijas plantea dos dificultades:

1. Un programa puede ser demasiado grande para caber en una particion.

50

Page 52: ´Indice general - 148.206.53.231

2. El uso de la memoria principal es extremadamente ineficiente, ya quecualquier programa sin importar lo pequeno que sea, ocupara una par-ticion completa. Este fenomeno donde se desperdician espacio internode una particion porque el bloque de proceso que es mas pequeno queella se le denomina fragmentacion interna (ver fig. 4.9).

Figura 4.9: Fragmentacion interna, donde se observa que algunos procesosocupan un espacio menor al total que se les fue asignado, dejando una porcionde memoria libre.

Con particionamiento fijo pero de distintos tamanos hay dos maneras posiblesde asignar los procesos a las particiones:

1. La forma mas simple es asignar cada proceso a la particion mas pequenaen la que quepa, en este caso hace falta una cola de planificacion paracada particion. Esta cola contendra a los procesos cuyo destino es dichaparticion. La ventaja de este enfoque es que los procesos se asignan deuna forma en la que se desperdicia el menor espacio de memoria posible,sin embargo aunque esta tecnica parece optima desde el punto de vistade una particion individual no lo es desde el punto de vista del sistemaglobal ya que puede darse la situacion de que existan particiones sinutilizar que podrıan ser aprovechadas por procesos que esperan en lascolas de planificacion de las particiones a las que han sido asignados(ver fig. 4.10).

51

Page 53: ´Indice general - 148.206.53.231

2. Consiste en seleccionar la particion mas pequena disponible que puedaalbergar al proceso.

Figura 4.10: Particionamiento fijo, con particiones de distintos tamanos

La utilizacion de particiones fijas ya sean de igual o distintos tamanos plantealos siguientes problemas:

El numero de particiones especificadas en el momento de la generaciondel sistema limita el numero de procesos activos en dicho sistema.

Puesto que los tamanos de particion se programan en el momento de lageneracion del sistema los trabajos pequenos no hacen un uso eficientedel espacio de las particiones en un entorno en el que los requisitosbasicos de almacenamiento de todos los procesos se conocen de ante-mano puede ser una tecnica razonable, pero en la mayorıa de los casoses ineficiente.

Particionamiento dinamico

En este esquema las particiones de memoria generalmente seran de distintotamano, ya que a los procesos se les asignara el espacio de memoria exactoque necesiten (ver fig. 4.11).

52

Page 54: ´Indice general - 148.206.53.231

Figura 4.11: Representacion del particionamiento dinamico.

Como se observa en la figura anterior, conforme va pasando el tiempo lamemoria libre va quedando dispersa, y no puede ser utilizada en forma con-junta por otro proceso que la necesite; a este fenomeno se le denomina frag-mentacion externa. Una manera de superar la fragmentacion externa es lacompactacion que consiste en reunir el espacio total de memoria libre; comorequisito para que se lleve a acabo la compactacion es la capacidad de movera los procesos de region de memoria sin afectar a las referencias de memoriaque contiene el proceso.

Existen diferentes metodos para asignar la memoria a los procesos en estetipo de particionamiento, aquı mencionamos tres y son los siguientes:

1. El primer ajuste (First Fit): Se localiza el primer bloque de memoriadisponible que pueda contener al proceso.

2. El siguiente ajuste (Next Fit): Similar al primer ajuste, excepto queese, comienza a buscar a partir de la ultima carga de proceso.

3. El mejor ajuste (Best Fit): Se busca el hueco de memoria que se adaptamas al proceso en base a su tamano.

53

Page 55: ´Indice general - 148.206.53.231

Otros metodos de asignacion de memoria

Existen ademas de los metodos mencionados anteriormente, otros que re-sultan mas eficientes, de los cuales no vamos a explicar, pero que se puedenconsultar en algun libro de sistemas operativos mencionados en la bibliografıade este documento.

54

Page 56: ´Indice general - 148.206.53.231

Capıtulo 5

Diseno y construccion delSistema Operativo

5.1. Introduccion

Hasta el momento ya hemos dado una explicacion sobre como esta confor-mado basicamente un sistema operativo, a continuacion en este capıtulo seexpone la implementacion de un sistema operativo. Los equipos disponiblescon los que contamos para realizar la implementacion contaron con las si-guientes caracterısticas:

Procesador Intel Pentium 4

Memoria RAM de 2GB

Unidad de disco flexible de 3 1/2”

Windows XP

Borland Turbo C

Ademas de lo anteriormente listado, se tuvo que extraer codigo de libreriasde Borland Turbo C.

La construccion del sistema operativo tiene como base, la arquitectura 8086de Intel con direccionamiento de memoria en modo real de hasta 1MB, porlo que el conjunto de registros que utilizamos es de 16 bits, incluyendo losregistros de segmento y desplazamiento. Con el objetivo de que el sistemaoperativo sea portable, se utiliza como medio de almacenamiento el discoflexible de 3 1/2”.

55

Page 57: ´Indice general - 148.206.53.231

Como se ha mencionado con anterioridad, un sistema operativo debe estarcompuesto de varias partes, las cuales deben realizar tareas muy especıficas,como pueden ser administrar los procesos, la memoria, etc. La estructuraciongeneral del sistema operativo esta compuesta por el cargador del sistemaoperativo, los servicios que ofrece a los programas de usuario, el nucleo quelleva a cabo la tarea de realizar el cambio de contexto, y por ultimo el shellque es la interfaz entre el sistema operativo y el usuario.

5.2. Cargador del sistema operativo

El cargador del sistema operativo es el encargado de configurar el sistema,entre estas configuraciones se encuentra: cargar en memoria los componentesdel sistema operativo, configurar el temporizador 8254, configurar los ser-vicios como la interrupcion 21h, el nuecleo como la interrupcion 08h. Estecargador, para poder ser ejecutado de arranque por la maquina, debe estarubicado en el primer sector y pista del disco flexible, de esta manera podra serencontrado por el proceso boostrap loader y posteriormente ejecutado por lacomputadora. La ubicacion en memoria de los otros componentes del sistemaoperativo es el siguiente:

Servicios en 98C0:0000,

Interrupcion 0 en 9880:0000 y

Nucleo en 99C0:0000

Una vez que el cargador ha terminado de configurar el sistema y cargado enmemoria todas las partes del sistema operativo, debe de asignarle el controla un proceso llamado proceso 0 que se encarga de ejecutar la instruccionhalt infinitamente con el objetivo de detener al procesador y esperar que seinvoque la interrupcion del nucleo.

5.3. Servicios

Nuestro sistema operativo proporciona diferentes servicios que deben ser ac-cedidos mediante la interrupcion 21h y el registro AH principalmente (otrosparametros son enviados por otros registros). Entre los servicios que se ofre-cen estan: la solicitud y liberacion de memoria, acceso al vector de interrup-ciones y operaciones con procesos, entre otras. En 5.3 se observa el metodopor el cual entran las peticiones a los servicios; la firma de este metodo inclu-ye la palabra reservada interrupt , esto es por que los servicios son invocados

56

Page 58: ´Indice general - 148.206.53.231

como una interrupcion; la forma en como llegan los parametros al metodoes mediante una estructura de datos llamada regpack que contiene los regis-tros: ax, bx, cx, dx, bp, si, di, ds, es y flags, que tienen que ser cargados porCARGA REGPACK para poder ser utilizados posteriormente.

1 void i n t e r r up t vS e r v i c i o s ( )2 {3 word wAX, wBX, wCX, wDX, wSI , wDI ;4 regpack srR ;5 byte bReg ;6 INI CORRECCION;7 CARGAREGPACK ( srR ) ;8 /∗Di r e c c i one s de memoria para l a s e s t r u c t u r a s ∗/9 bReg = wAX >> 8 ;10 switch (bReg )11 {12 case 0 :13 vSe rv i c i o 00 ( ) ; //∗Borrado de pan ta l l a ∗/14 break ;15 case 1 :16 vSe rv i c i o 01 ( ) ; /∗ F i j a r vec to r de i n t e r r upc i on ∗/17 break ;18 case 2 :19 vSe rv i c i o 02 ( ) ; /∗Obtiene vec to r de i n t e r r upc i on ∗/20 break ;21 case 3 :22 vSe rv i c i o 03 (&srR ) ; /∗ S o l i c i t a de memoria∗/23 break ;24 case 4 :25 vSe rv i c i o 04 (&srR ) ; /∗Libera memoria∗/26 break ;27 case 5 :28 vSe rv i c i o 05 (&srR ) ; /∗Redef ine memoria∗/30 break ;31 case 6 :32 vSe rv i c i o 06 ( ) ; /∗Carga proceso en memoria∗/33 break ;34 case 7 :35 vSe rv i c i o 07 ( ) ; /∗Ejecuta proceso en memoria∗/36 break ;37 case 8 :

57

Page 59: ´Indice general - 148.206.53.231

38 vSe rv i c i o 08 ( ) ; /∗Cambia estado de l proceso ∗/39 break ;40 case 9 :41 vSe rv i c i o 09 ( ) ; /∗Obtiene e l estado de l proceso ∗/42 break ;43 case 10 :44 vSe rv i c i o 10 (&srR ) ; /∗Obtiene Id de l proceso en e j e cu c i on45 break ;46 case 11 :47 vSe rv i c i o 11 (&srR ) ; /∗Obtiene bloque de memoria mas grande48 break ;49 case 12 :50 vSe rv i c i o 12 ( ) ; /∗Fin de proceso ( e l que l lama )∗/51 break ;52 case 13 :53 vSe rv i c i o 13 ( ) ; /∗Terminar proceso ( cua l qu i e r a )∗/54 break ;55 d e f au l t :56 break ;57 } ;58 CARGAREGS ( srR ) ;59 FIN ICORRECCION;60 }

A continuacion estan descritos cada uno de los servicios que ofrece el sistemaoperativo:

1. Borrado de pantalla (AH = 0). Este servicio tiene como funcionlimpiar el contenido de la pantalla. Utilizando la la funcion 03 de lainterrupcion 10.

2. Fijar vector de interrupcion (AH = 01). Almacena en el vector deinterrupcion la direccion de la rutina o procedimiento que debera ejecu-tarse cuando se invoque a la interrupcion. Como parametros el serviciorecibe a BX como el vector de interrupcion, DX el segmento del proce-dimiento y CX el desplazamiento del procedimiento.

3. Obtener vector de interrupcion (AH = 02). El objetivo de esteservicio es obtener la direccion donde esta almacenado el procedimien-to correspondiente al numero de vector de interrupcion determinadopor BX. Como salida DX contiene el segmento, mientras que CX eldesplazamiento.

58

Page 60: ´Indice general - 148.206.53.231

4. Solicitar memoria (AH = 03). Verifica que exista memoria sufi-ciente para el tamano de memoria solicitada y asignarlo al proceso queinvoca el servicio. Regresa AX = 1 y DX = Paginas de 256b de me-moria disponibles si no hay memoria; si la hay memoria, la asigna alproceso que invoco el servicio y regresa AX = 0 y en DX el segmentode memoria (el desplazamiento es 0).

5. Liberar memoria (AH = 04). La tarea de este servicio es liberar losbloques de memoria que fueron asignados a un proceso. Si tiene exitodevuelve 0 en AH de lo contrario 1, mientras en DX devuelve el numerode bloques de 256 bytes liberados.

6. Redefinir memoria (AH = 05). Lo que realiza este servicio es reasig-nar la cantidad de memoria que tiene un proceso; es decir puede solicitarmas memoria de la que tiene asignada o liberar algunos de los bloquesmemoria previamente asignados. Si el servicio tiene exito devuelve AH= 0, de lo contrario AH = 1 y en DX devuelve el numero de bloquesde 256 bytes de memoria reasignados.

7. Cargar proceso en memoria (AH = 06). Este servicio se encargade tomar un programa almacenado en un disco de 3 1/2”, crear unproceso nuevo y cargarlo en memoria. Como parametros recibe en ALel numero de sectores que deben ser leidos (bloques de 512 bytes), CHcontiene la pista, CL el sector, DH la cabeza y DL el disco. Como salidadevolvera AH = 0 si tuvo exito el servicio, en ES estara contenido elsegmento del proceso (con desplazamiento 0).

8. Ejecutar proceso en memoria (AH = 07). La funcion que tieneeste servicio es de ejecutar un proceso. La entrada se recibe por DXque es el identificador del proceso.

9. Cambiar estado de proceso (AH = 08). La finalidad del servicioes de modificar el estado actual de un proceso. Como entradas recibe elidentificador del proceso en DX y en BL el nuevo estado. Como salidadevolvera en AH el exito de la operacion (0 si se tuvo exito y 1 si no lotuvo).

10. Obtener estado de proceso (AH = 09). Este servicio obtiene elestado actual de un proceso, a partir de su identificador proporcionadocomo parametro en DX. El estado es devuelto en BL, mientras que AH= 0 indica que se obtenido exito de lo contrario tendra el valor de 1.

59

Page 61: ´Indice general - 148.206.53.231

11. Obtener id del proceso en ejecucion (AH = 10). Como su nombrelo indica, la finalidad de este servicio es obtener el identificador deproceso que se encuentra actualmente en ejecucion. DX contendra elidentificador del proceso y AH senalara si se tuvo exito (con 0 todosalio bien y 1 fracaso).

12. Obtener el bloque de memoria mas grande posible (AH = 11).Este servicio tiene como funcion buscar el bloque de memoria contiguomas grande disponible (que no este asignado a otro proceso), y devolverel numero de bloques de 256 bytes mediante el registro DX.

13. Finalizacion del proceso que llama (AH = 12). Este serviciotiene el objetivo de terminar la ejecucion del proceso que se encuentraactualmente utilizando el procesador.

14. Finalizar cualquier proceso (AH = 13). La funcion de este esterminar la ejecucion de un proceso; donde el parametro proporcionadoes el identificador de proceso. Como salida esta AH = 0 que indica quese tuvo exito y con AH = 1 no.

5.4. Nucleo

A continuacion en las siguientes dos subsecciones estan definidas dos partesimportantes para la asignacion de procesador y memoria, las cuales son: eladministrador de procesos y el administrador de memoria.

5.4.1. Administracion de procesos

Cada proceso del sistema operativo es representado como ya se vio en elcapıtulo anterior, por el bloque de control de proceso que a continuacion semuestra:

Identificador del proceso. Entero de 2 bytes que permite identificara cada proceso.

Prioridad y estado del proceso. Byte que indica que prioridad tieneel proceso y en que estado se encuentra (se describiran mas adelante).

Habilitado. Bandera de un byte que indica si la estructura esta siendoutilizada por algun proceso.

Segmento de inicio. Direccion de 16 bits donde inicia la memoria quese le asigno al proceso.

60

Page 62: ´Indice general - 148.206.53.231

Registros del proceso. Contenido de los siguientes registros: AX,BX, BX, CX, DX, SI, DI, BP, SP, IP, CS, DS, ES, SS y flags.

Identificador del proceso padre. Entero de 16 bits que identifica alproceso padre (proceso que lo creo).

Direccion del proceso siguiente. Direccion del proceso siguiente enla lista de procesos.

Direccion del proceso anterior. Direccion del proceso anterior enla lista de procesos.

La estructura de datos que repreenta al BCP se observa en la fig. 5.1. Enla imagen se observa como la estructura de datos tiene tambien apuntadorestanto al proceso siguiente (pspSig) como al proceso anterior (pspAnt), lo queindica que la lista de procesos es una lista doblemente ligada.

61

Page 63: ´Indice general - 148.206.53.231

typedef struct PROCESO proceso;

struct PROCESO

{ /*Estructura para procesos: longitud 44 bytes*/

word wIdProc; /*Id del proceso*/

byte bPriEdo; /*Prioridad y estado del proceso*/

byte bEnabled; /*Habilitado*/

word wSegIni; /*Segmento de inicio*/

word wAX; /*Registro AX*/

word wBX; /*Registro BX*/

word wCX; /*Registro CX*/

word wDX; /*Registro DX*/

word wSI; /*Registro SI*/

word wDI; /*Registro DI*/

word wBP; /*Registro BP*/

word wSP; /*Registro SP*/

word wIP; /*Registro IP*/

word wCS; /*Registro CS*/

word wDS; /*Registro DS*/

word wES; /*Registro ES*/

word wSS; /*Registro SS*/

word wF; /*Registro Flags*/

word wIdPadre; /*Id del proceso padre*/

proceso far *pspSig; /*Siguiente proceso en lista*/

proceso far *pspAnt; /*Anterior proceso en lista*/

};

Figura 5.1: Estructura de datos de BCP

Ahora bien, todos los procesos a lo largo de su ciclo de vida pueden pasarpor diferentes estados, estos estados como ya lo sabemos, pueden ser repre-sentados por un modelo que en particular para este sistema operativo es elde tres estados, la fig 5.2 muestra esta representacion:

62

Page 64: ´Indice general - 148.206.53.231

Figura 5.2: Modelo de 3 estados

El planificador de procesos utiliza el algoritmo Round-Robin, por lo tantohace uso de un quantum que determine la rebanada de tiempo que le asig-nara a cada proceso. Para realizar el cambio de contexto el sistema operativocuenta con un metodo llamado nucleo, que es ejecutado como la interrup-cion 08. La siguiente fig. ?? muestra como se realiza el cambio de contextotomando al siguiente proceso de la lista siempre y cuando haya concluido elquantum del proceso anterior.

63

Page 65: ´Indice general - 148.206.53.231

...

proceso far *psPAux, *psPAux1;

word wAux1, wAux2;

void interrupt nucleo ()

{

(*pBCntQuantum)++;

if ((*pBCntQuantum)==(*pBNumQuantum))

{ //Se termino su quantum, se debe hacer cambio de contexto

psPAux = *psPProcListoEjec;

psPAux1 = psPAux->pspSig;

(*psPProcListoEjec) = psPAux->pspSig;

if (psPAux!=psPProcListoEjec)

{

//Almacena los registros del proceso de salida

...

psPAux->wF = wAux1;

asm mov ax, [bp+si] //Para CS

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wCS = wAux1;

asm mov ax, [bp+si] //Para IP

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wIP = wAux1;

asm mov ax, [bp+si] //Para AX

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wAX = wAux1;

asm mov ax, [bp+si] //Para BX

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wBX = wAux1;

...

//Regresa los registros del proceso de entrada

...

wAux1 = psPAux1->wCS; //Coloca CS

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wIP; //Coloca IP

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wAX; //Coloca AX

asm mov ax, wAux1

asm push ax

64

Page 66: ´Indice general - 148.206.53.231

5.4.2. Administracion de memoria

Para el manejo de la memoria se tiene una estructura de longitud de 7 bytesla cual consta de los siguientes elementos:

bEnabled. Nos indica si el bloque de memoria fue asignado a un pro-ceso. Si es TRUE el bloque de memoria esta siendo utilizado por unproceso, en otro caso es FALSE.

wSeg. Contiene la direccion del segmento donde inicia el bloque dememoria.

wLen. Numero de bloques de memoria asignado, solo para el primerbloque.

wIdProc. Id del proceso dueno de la memoria.

La memoria esta dividida en particiones de 256 bytes, donde cada una deestos estas, esta mapeado a una de las estructuras de datos mostrada an-teriormente, por lo que a cada proceso que solicita memoria se le otorganmultiplos de 256 bytes, y la ubicacion de cada uno de estos bloques es con-tinuo.

5.5. Shell

Como todo sistema operativo, no podemos dejar fuera a nuestro Shell, yaque este sera el encargado de permitir la comunicacion entre el usuario y losrecursos del sistema ademas de permitir acceder a los servicios que ofrecenuestro sistema operativo; la implementacion del Shell es un tanto parecidaa la de un analizador lexicografico de un compilador.

65

Page 67: ´Indice general - 148.206.53.231

66

Page 68: ´Indice general - 148.206.53.231

Capıtulo 6

Conclusiones

A lo largo de este trabajo logramos identificar algunos aspectos importantesa destacar de un sistema operativo, ya que estos permiten aprovechar demejor manera los recursos, entre los que se encuentran:

modelo de estados,

planificador de procesos y,

la particion de la memoria

Entendiendo a quien va dirigido este trabajo estamos convencidos de que esuna buena herramienta para practicar y comprender el funcionamiento de unsistema operativo y creemos que puede ser adaptado a nuevos requerimientoscomo por ejemplo un esquema diferente de administracion de memoria o deprocesos.

Dado que nuestro sistema operativo esta basado en la arquitectura 8086y sabiendo que el direccionamiento de este es en modo real, identificamosel problema de que un programa de usuario puede modificar regiones dememoria que no le pertenecen, es decir, el sistema operativo actualmente notiene un mecanismo que evite la interferencia entre procesos; sin embargo, apesar de haberlo identificado, creemos que no es tan sencillo de resolver enesta arquitectura.

67

Page 69: ´Indice general - 148.206.53.231

68

Page 70: ´Indice general - 148.206.53.231

Capıtulo 7

Referencias

Andrew S. Tanenbaum, Organizacion de computadoras Un enfoque estructu-rado Tercera Edicion, Prentice Hall

M. Morris Mano, Arquitectura de computadoras Tercera Edicion, PrenticeHall 1994

Michael Tischer, PC Interno, Marcombo 1992

Stalling William, Organizacion y arquitectura de computadoras Septima Edi-cion, Pearson Prentice Hall

Barry B. Brey, Microprocesadores Intel 8086/8088, 80186, 80286, 80386 y80486 Arquitectura, programacion e interfaces Tercera Edicion, Prentice Hall

Barry B. Brey, Microprocesadores Intel 8086/8088, 80186/80188, 80286,80386, 80486, Pentium, Procesador Pentium Pro, Pentium II, Pentium III,Pentium 4 Arquitectura, programacion e interfaces Septima Edicion, PearsonPrentice Hall

Stalling William, Sistemas Operativos Aspectos internos y principios de di-seno Quinta Edicion, Pearson Prentice Hall

Jesus Carretero Perez, Felix Garcıa Carballeira, Pedro de Miguel Anasagasti,Fernando Perez Costoya, Sistemas Operativos Una vision aplicada, Mc GrawHill 2001

Abraham Silberschatz, Peter Baer Galvin, Sistemas Operativos Quinta Edi-cion, Pearson Addison Wesley Longman

Andrew S. Tanenbaum, Sistemas Oprativos: Diseno e implementacion, Pren-tice Hall 1998

69

Page 71: ´Indice general - 148.206.53.231

70

Page 72: ´Indice general - 148.206.53.231

Apendice A

cargador.asm

;Programa que se encarga de cargar a la PC los siguientes programas:

;

; * BOOT (este cargador)

; * Servicios

; * Nucleo

;

.8086

include dirs.inc

PROHEADDSP equ 00h ;Desplazamiento de las varibles.

PROTAILDSP equ 02h

PROACTDSP equ 04h

CNTPROCDSP equ 06h

;En el disco, disco y cabeza es cero. Los elementos se localizan en:

CAR_PISTA equ 0

CAR_SECTOR equ 1

CAR_HEAD equ 0

CAR_DISCO equ 0

SER_PISTA equ 1

SER_SECTOR equ 1

SER_HEAD equ 0

SER_DISCO equ 0

NUC_PISTA equ 2

71

Page 73: ´Indice general - 148.206.53.231

NUC_SECTOR equ 1

NUC_HEAD equ 0

NUC_DISCO equ 0

INT_PISTA equ 3

INT_SECTOR equ 1

INT_HEAD equ 0

INT_DISCO equ 0

P0_PISTA equ 4

P0_SECTOR equ 1

P0_HEAD equ 0

P0_DISCO equ 0

LEE_SEC_CARGAD equ 1 ;Sectores que se leeran para el cargado.

LEE_SEC_SERVIS equ 7 ;Sectores que se leeran para los servicios.

LEE_SEC_NUCLEO equ 2 ;Sectores que se leeran para el nucleo.

;Sectores que se leeran para codigo de atencion de interrupciones.

LEE_SEC_INTS equ 1

LEE_SEC_P0 equ 1 ;Sectores que se leeran para proceso 0

POS_MSG1 equ 160

POS_MSG2 equ 320

POS_MSG3 equ 480

POS_MSG4 equ 640

MEM_VIDEO equ 0B800h

;Inicio del cargador

CODIGO SEGMENT USE16

ASSUME CS:CODIGO, DS:CODIGO

org 0000

mov ax, cs ;Iniciamos los registros de segmento.

mov es, ax

mov ds, ax

;Se inicia la pila con lo que se ha establecido

mov ax, SEG_PILA

mov ss, ax

72

Page 74: ´Indice general - 148.206.53.231

mov sp, OFF_PILA

mov ax, 03h ;Se borra pantalla

int 10h

call SABER_IP ;Con esto AX = IP

sub ax, 22

mov bx, ax ;BX sera nuestro puntero base

mov si, offset MSG_CARGA ;Este es el mensaje de "Cargando nucleo..."

add si, bx

xor di, di

call IMPRIME_TEXTO

push bx

;************************ CARGA DE SERVICIOS ***********************

mov al, LEE_SEC_SERVIS

mov ch, SER_PISTA

mov cl, SER_SECTOR

mov dh, SER_HEAD

mov dl, SER_DISCO

mov bx, SEG_SERVICIOS

mov es, bx

xor bx, bx

call LEE_DISCO

xor bx, bx ;Asignar el vector de interrupcion

mov bl, INT_21

shl bl, 1

shl bl, 1

xor ax, ax

mov ds, ax

mov word ptr [bx], 0000h ;Primero el desplazamiento!

inc bx

inc bx

mov word ptr [bx], SEG_SERVICIOS ;Segmento

;******************* CARGA DE INTERRUPCIONES **********************

mov al, LEE_SEC_INTS

mov ch, INT_PISTA

mov cl, INT_SECTOR

mov dh, INT_HEAD

mov dl, INT_DISCO

mov bx, SEG_INT

73

Page 75: ´Indice general - 148.206.53.231

mov es, bx

xor bx, bx

call LEE_DISCO

xor bx, bx

mov bl, INT_00

shl bl, 1

shl bl, 1

xor ax, ax

mov ds, ax

mov word ptr [bx], 0000h

inc bx

inc bx

mov word ptr [bx], SEG_INT

;******************** CARGA DE NUCLEO **************

mov al, LEE_SEC_NUCLEO

mov ch, NUC_PISTA

mov cl, NUC_SECTOR

mov dh, NUC_HEAD

mov dl, NUC_DISCO

mov bx, SEG_NUCLEO

mov es, bx

xor bx, bx

call LEE_DISCO

;**************** Carga proceso 0 **************

mov al, LEE_SEC_P0

mov ch, P0_PISTA

mov cl, P0_SECTOR

mov dh, P0_HEAD

mov dl, P0_DISCO

mov bx, (SEG_MEMORIA-1)

mov es, bx

xor bx, bx

call LEE_DISCO

;**** CONFIGURACION DEL SISTEMA *****

;*** Inicia la estructura de los bloques de memoria ***

mov cx, NUMBLQMEM

mov dx, DIRINICIOMEM

mov ax, SEG_MEMORIA

mov ds, ax

74

Page 76: ´Indice general - 148.206.53.231

xor bx, bx

xor ax, ax

INICIA_MEM:

mov [bx], al ;bEnabled

inc bx

mov [bx], dx ;wSeg

inc bx

inc bx

add dx, ADD_PAGINA

mov [bx], ax ;wLen

inc bx

inc bx

mov [bx], ax ;wIdProc

inc bx

inc bx

loop INICIA_MEM

;***** Inicia la estructura de procesos ******

mov cx, NUMBLQPROC

mov ax, SEG_PROCESO

mov ds, ax

xor bx, bx

xor ax, ax

INICIA_PROC:

mov dx, 44

INICIA_PROC1:

mov [bx], ax

inc bx

inc bx

dec dx

dec dx

jnz INICIA_PROC1

loop INICIA_PROC

;Inicia configuracion de proceso 0

mov bx, 2

mov byte ptr [bx], PROC_RUN ;Prioridad/Estado

inc bx

mov byte ptr [bx], 1 ;Habilitacion

inc bx

mov word ptr [bx], (SEG_MEMORIA-1) ;Segmento de inicio

add bx, 16

mov ax, sp

75

Page 77: ´Indice general - 148.206.53.231

mov [bx], ax ;SP

add bx, 4

mov word ptr [bx], (SEG_MEMORIA-1) ;CS

add bx, 6

mov ax, ss

mov [bx], ax ;SS

add bx, 4

;El proceso cero es su propio padre

mov word ptr [bx], 0

inc bx

inc bx

mov ax, ds

mov word ptr [bx], 0

inc bx

inc bx

mov word ptr [bx], ax

inc bx

inc bx

mov word ptr [bx], 0

inc bx

inc bx

mov word ptr [bx], ax

;**** Inicia las variables del nucleo *******

mov ax, SEG_VARIABLES

mov ds, ax

mov cx, NUMVARS

xor ax, ax

xor bx, bx

INICIA_VAR:

mov [bx], ax

inc bx

loop INICIA_VAR

mov bx, NUMQUANTUM

mov byte ptr [bx], 5

mov bx, NUMPROCEJEC

mov byte ptr [bx], 1

mov bx, PROCE_EJEC

mov word ptr [bx], 0

mov word ptr [bx+2], SEG_PROCESO

;**** Configuracion del nucleo **********

76

Page 78: ´Indice general - 148.206.53.231

cli ;Fijamos la velocidad del temporizador.

mov dx, TEMPORIZADOR

mov al, 036h

out 043h, al

mov al, dl

out 040h, al

mov al, dh

out 040h, al

xor bx, bx ;Ahora colocamos en nucleo en la int 08h

mov bl, INT_08

shl bl, 1

shl bl, 1

xor ax, ax

mov ds, ax

mov word ptr [bx], 0000h

inc bx

inc bx

mov word ptr [bx], SEG_NUCLEO

mov ax, 03h ;Se borra pantalla

int 10h

;********* Carga Shell ***********

mov ah, 06h ;Servicio para cargar exe de disco

mov al, 6 ;Sectores a leer del disco

mov ch, 5 ;Pista

mov cl, 1 ;Sector

mov dh, 0 ;Cabeza

mov dl, 0 ;Disco

int 21h

;call ESPERA ;Esta es una espera inutil.

;******** Cedemos el control proceso 0 ****

sti

pop bx

mov ax, cs

mov ds, ax

mov si, offset MSG_LISTO ;Este es el mensaje de "Nucleo listo"

add si, bx

xor di, 0

call IMPRIME_TEXTO

call ESPERA ;Esta es una espera inutil.

db 0eah

77

Page 79: ´Indice general - 148.206.53.231

dw 0000h

dw (SEG_MEMORIA-1)

;**********************************************

MSG_CARGA db "Cargando...", 0

MSG_LISTO db "Listo", 0

SIN_FIN PROC NEAR

SIN_FIN_LBL:

hlt

jmp SIN_FIN_LBL

SIN_FIN ENDP

SABER_IP PROC NEAR

mov bp, sp

mov ax, [bp]

ret

SABER_IP ENDP

;Imprime un texto (terminado en 0), la linea se asigna por di

IMPRIME_TEXTO PROC NEAR

push ax ;Es muy importante guardar lo que se usa

push es

push di

mov ax, MEM_VIDEO ;Memoria de video en modo texto

mov es, ax ;ES:DI apuntado a B800:0000

SIGUIENTE1:

mov al, [si]

cmp al, 0

je SALIR1

;Copia el byte dado por DS:SI en ES:DI e incrementa indices

movsb

mov byte ptr ES:[di], 0Fh

inc di

jmp SIGUIENTE1

SALIR1:

pop di

pop es

pop ax

ret ;Regresa al punto donde lo llamaron

IMPRIME_TEXTO ENDP

78

Page 80: ´Indice general - 148.206.53.231

;Lee una unidad de disco,

;los argumentos son los mismo a los de la interrupcion

LEE_DISCO PROC NEAR

push ax

push dx

xor ax, ax ;Reset a disco

xor dx, dx

int 13h

pop dx

pop ax

mov ah, 02h ;Lectura del disco, carga de servicios

int 13h ;Posiblemente hay errores, verificar!!!

ret

LEE_DISCO ENDP

;Realiza una espera

ESPERA PROC NEAR

push cx

push dx

mov dx, 00400h ;Espera inutil, no tiene ningun proposito

xor cx, cx

ESPERA_LBL:

nop

loop ESPERA_LBL

dec dx

jnz ESPERA_LBL

pop cx

pop dx

ret

ESPERA ENDP

ORG 510

DB 55H, 0AAH ;Por si las dudas, algunas maquinas reconocen esta cadena.

CODIGO ENDS

END

79

Page 81: ´Indice general - 148.206.53.231

80

Page 82: ´Indice general - 148.206.53.231

Apendice B

creafdisk.c

/*Este programa se encarga de crear una unidad de disco de 1.44Mb*/

/*La unidad de disco posee las siguientes caracteristicas: */

/* */

/* Sectores por pista: 18 s:(1-18) */

/* Pistas por lado/cabeza: 80 P:(0-79) */

/* Lado/cabeza: 2 C:(0-1) */

/* Tamano del sector: 512 bytes */

/* Capacidad total: 1474560 bytes */

/* Nombre del archivo: fdisk.dsk */

/* */

/*La estructura del disco en el archivo de salida es: */

/* */

/* Se tienen bloques representando las pistas del disco, hay 80 */

/* pistas, por lo tanto hay 80 bloques. Cada bloque contiene dos */

/* grupos que representan el lado 0 y lado 1 del disco; por lo */

/*tanto cada bloque mide 18 sectores del lado 0, */

/*mas 18 sectores */

/* del lado 1, con una longitud total de 18432 bytes. */

/* */

/* PISTA 0 PISTA 1 PISTA 79 */

/* [18 sec | 18 sec][18 sec | 18 sec] . . . [ 18 sec | 18 sec] */

/* LADO 0 LADO 1 LADO 0 LADO 1 LADO 0 LADO 1 */

/* */

/*Este programa recibe un archivo de entrada */

/*en donde se indicara */

/*la localizacion de cada programa en el disco; el formato es: */

/* */

/* P S C PROGRAMA */

81

Page 83: ´Indice general - 148.206.53.231

/* */

/* P: indica la pista de inicio. */

/* S: el sector. */

/* C: la cabeza o el lado del disco. */

/* PROGRAMA: el nombre del programa que se va introducir. */

/* */

/* No olvidar que las pistas y las cabezas inician en 0, y los */

/*sectores en 1. */

/* */

/*La organizacion del disco es la siguiente: */

/* */

/* C:0,P:0,S:1: cargador.com */

/* C:0,P:3,S:1: int.com */

/* */

/* */

/* */

/* */

/* */

/* */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAX_CAD 250

#define MAX_DD 20

#define CABEZAS 2

#define SECTORES 18

#define PISTAS 80

#define TSECTOR 512

/*Direcciones para el cargador*/

#define CAR_PISTA 0

#define CAR_SECTOR 1

#define CAR_HEAD 0

#define CAR_DISCO 0

#define LEE_SEC_CARGAD 1

typedef struct DATADSK datadsk;

82

Page 84: ´Indice general - 148.206.53.231

struct DATADSK

{

int iPista, iSector, iCabeza;

char scFile[MAX_CAD];

};

long lFileLength (FILE *psfF);

int main (int iArgs, char *pscArgs[])

{

FILE *psfIn, *psfOut;

int v, w, x, y, z, iFiles;

long lAux;

char scBuffer[TSECTOR], scCERO[TSECTOR];

char scData[MAX_CAD], scAux[MAX_CAD];

datadsk *psdData;

if (iArgs!=2)

{

printf ("creafdisk ARCHIVO.\n");

exit (1);

}

/*Se llena de 0’s el buffer*/

for (x=0; x<TSECTOR; x++) scCERO[x] = 0;

/*Archivo de datos*/

psfIn = fopen (pscArgs[1], "rb");

if (!psfIn)

{

printf ("Error al abrir: %s\n", pscArgs[1]);

exit (2);

}

psdData = (datadsk *)malloc (MAX_DD*sizeof(datadsk));

if (!psdData)

{

printf ("No hay memoria.\n");

exit (3);

}

w = 0;

while (!feof(psfIn))

{

fgets (scData, MAX_CAD, psfIn);

x = -1; y = 0; z = 0;

83

Page 85: ´Indice general - 148.206.53.231

do

{

x++;

switch (scData[x])

{

case 0x0D:

case 0x0A:

case 0x00:

case ’ ’:

if (y)

{

scAux[y] = 0; y = 0;

switch (z)

{

case 0:

psdData[w].iPista = atoi (scAux); z++;

break;

case 1:

psdData[w].iSector = atoi (scAux); z++;

break;

case 2:

psdData[w].iCabeza = atoi (scAux); z++;

break;

default:

strcpy (psdData[w].scFile, scAux);

break;

}

}

break;

default:

scAux[y] = scData[x]; y++;

break;

}

}

while (scData[x]);

if (z) w++;

}

fclose (psfIn); iFiles = w;

printf ("Se encontraron %d archivos a introducir.\n", iFiles);

/*Archivo que contendra el disco*/

psfOut = fopen ("fdisk.dsk", "wb");

84

Page 86: ´Indice general - 148.206.53.231

if (!psfOut)

{

printf ("Imposible crear fdisk.dsk\n");

exit (4);

}

/*Ahora el cargador*/

printf ("Creando fdisk.dsk . . .\n");

psfIn = 0;

for (x=0; x<PISTAS; x++) /*Pistas*/

for (y=0; y<CABEZAS; y++) /*Cabezas*/

for (z=1; z<=SECTORES; z++) /*Sectores*/

{

for (w=0; w<iFiles; w++)

if ((psdData[w].iPista==x)&&

(psdData[w].iSector==z)&&

(psdData[w].iCabeza==y))

{

psfIn = fopen (psdData[w].scFile, "rb");

if (!psfIn)

{

printf ("No se puede abrir: %s\n",

psdData[w].scFile);

exit (4);

}

lAux = lFileLength (psfIn);

if (lAux%TSECTOR) v = (int)(lAux / TSECTOR) + 1;

else v = (int)(lAux / TSECTOR);

printf ("Ingresando: %s en P: %d, S: %d, C: %d,

[%ld:%d]\n", psdData[w].scFile,

psdData[w].iPista, psdData[w].iSector,

psdData[w].iCabeza, lAux, v);

w = iFiles;

}

if (psfIn)

{

fread (scBuffer, 1, TSECTOR, psfIn);

fwrite (scBuffer, 1, TSECTOR, psfOut);

v--;

if (!v)

{

fclose (psfIn);

85

Page 87: ´Indice general - 148.206.53.231

psfIn = 0;

}

}

else

fwrite (scCERO, 1, TSECTOR, psfOut);

}

fclose (psfOut);

printf ("Terminado!\n");

return (0);

}

long lFileLength (FILE *psfF)

{

long lRet;

fseek (psfF, 0L, SEEK_END);

lRet = ftell(psfF);

fseek(psfF, 0L, SEEK_SET);

return (lRet);

}

86

Page 88: ´Indice general - 148.206.53.231

Apendice C

nucleo.c

#include "dirs.h"

#define LIB_SO

#include "so.h"

proceso far *psPAux, *psPAux1;

word wAux1, wAux2;

void interrupt nucleo ()

{

(*pBCntQuantum)++;

if ((*pBCntQuantum)==(*pBNumQuantum))

{ //Se termino su cuantum, se debe hacer cambio de contexto

psPAux = *psPProcListoEjec;

psPAux1 = psPAux->pspSig;

(*psPProcListoEjec) = psPAux->pspSig;

if (psPAux!=psPProcListoEjec)

{

//Almacena los registros del proceso de salida

asm mov si, LEN_REG_PILA

asm mov ax, [bp+si] //Para banderas

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wF = wAux1;

asm mov ax, [bp+si] //Para CS

asm mov wAux1, ax

87

Page 89: ´Indice general - 148.206.53.231

asm dec si

asm dec si

psPAux->wCS = wAux1;

asm mov ax, [bp+si] //Para IP

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wIP = wAux1;

asm mov ax, [bp+si] //Para AX

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wAX = wAux1;

asm mov ax, [bp+si] //Para BX

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wBX = wAux1;

asm mov ax, [bp+si] //Para CX

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wCX = wAux1;

asm mov ax, [bp+si] //Para DX

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wDX = wAux1;

asm mov ax, [bp+si] //Para ES

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wES = wAux1;

asm mov ax, [bp+si] //Para DS

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wDS = wAux1;

asm mov ax, [bp+si] //Para SI

asm mov wAux1, ax

asm dec si

88

Page 90: ´Indice general - 148.206.53.231

asm dec si

psPAux->wSI = wAux1;

asm mov ax, [bp+si] //Para DI

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wDI = wAux1;

asm mov ax, [bp+si] //Para BP

asm mov wAux1, ax

asm dec si

asm dec si

psPAux->wBP = wAux1;

asm mov si, bp //Para SP

asm sub si, sp

asm add si, sp

asm add si, (LEN_REG_PILA+2)

asm mov wAux1, si

psPAux->wSP = wAux1;

asm mov ax, ss //Para SS

asm mov wAux1, ax

psPAux->wSS = wAux1;

//Regresa los registros del proceso de entrada

wAux1 = psPAux1->wSS; //Coloca SS

asm mov ax, wAux1

asm mov ss, ax

wAux1 = psPAux1->wSP; //Coloca SP

asm mov ax, wAux1

asm mov sp, ax

wAux1 = psPAux1->wF; //Coloca Flags

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wCS; //Coloca CS

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wIP; //Coloca IP

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wAX; //Coloca AX

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wBX; //Coloca BX

89

Page 91: ´Indice general - 148.206.53.231

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wCX; //Coloca CX

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wDX; //Coloca DX

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wES; //Coloca ES

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wDS; //Coloca DS

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wSI; //Coloca SI

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wDI; //Coloca DI

asm mov ax, wAux1

asm push ax

wAux1 = psPAux1->wBP; //Coloca BP

asm mov ax, wAux1

asm push ax

}

(*pBCntQuantum) = 0;

}

asm mov al, 0x20

asm out 0x20, al /*Fin de interrupcion*/

}

90

Page 92: ´Indice general - 148.206.53.231

Apendice D

dirs.h

/*Este archivo contiene las direcciones de memoria que se usaran a */

/*lo largo del */

/*nucleo, si hay algun cambio en este archivo, entonces habra que */

/*cambiar el archivo dirs.inc. Las direcciones de memoria se */

listan en el orden en que se localizan en la memoria. */

#define SEG_PILA 0x9800 /*Segmento de la pila*/

#define OFF_PILA 0x07FF /*Desplazamiento de la pila

(no olvidar que va de arriba a abajo)*/

#define SEG_INT 0x9880 /*Segmento de los procedimientos de

atencion de interrupcion*/

#define SEG_SERVICIOS 0x98C0 /*Segmento de los servicios*/

#define SEG_NUCLEO 0x99C0 /*Segmento del nucleo*/

#define SEG_MEMORIA 0x9A40 /*Segmento de estructuras de memoria*/

#define SEG_LIBRE 0x9E70 /*Segmento de memoria libre*/

#define SEG_ENCABEZADO 0x9F30 /*Segmento para almacenar temporalemente

el encabezado*/

#define SEG_PROCESO 0x9F70 /*Segmento de estructuras de procesos*/

#define SEG_VARIABLES 0x9FF0 /*Segmento de las variables*/

#define DIRINICIOMEM 0x0060 /*Primer segmento de memoria

libre de 256 bytes (pagina de 256)*/

#define DIRFINMEM 0x97F0 /*Ultimo segmento de memoria

libre de 256 bytes (pagina de 256)*/

#define NUMBLQMEM 2426 /*Numero de bloques en la estructura de memoria*/

#define NUMBLQPROC 46 /*Numero de bloques en la estructura de procesos

91

Page 93: ´Indice general - 148.206.53.231

(= Numero de procesos)*/

#define NUMVARS 240 /*Numero de bytes de variables para el SO*/

#define TAM_PAGINA 0x100 /*Tamano de pagina, 256 bytes*/

#define ADD_PAGINA 0x010 /*Para cambiar entre segmentos o

paginas agregar esta cantidad*/

#define INT_SER 0x021 /*Vector de interrupcion de los servicios

del SO*/

#define DIRVARIABLES 0x9FF00000 /*Direccion logica de las variables*/

#define LEN_REG_PILA 22 /*Tamano en bytes de los registros que

se meten en pila*/

/*Interrupciones*/

#define INT_00 0x0 /*Division entre cero*/

#define INT_01 0x1 /*Trampa*/

#define INT_02 0x2 /*NMI*/

#define INT_03 0x3 /*Trampa*/

#define INT_04 0x4 /*Sobreflujo*/

#define INT_08 0x8 /*Temporizador*/

#define INT_10 0x10 /*Interrupcion de video*/

#define INT_13 0x13 /*Interrupcion del floppy*/

#define INT_16 0x16 /*Interrupcion de teclado*/

#define INT_21 0x21 /*Interrupcion del SO*/

/*Direcciones logicas de la zona de variables del SO*/

#define CNTIDPROC 0x00 /*Cuenta el numero de procesos

y asigna el id (2)*/

#define NUMQUANTUM 0x02 /*Numero de Quatum de tiempo

a contar (1)*/

#define CNTQUANTUM 0x03 /*Este cuenta los Quantum (1)*/

#define NUMPROCEJEC 0x04 /*Numero de procesos en listos*/

#define PROCE_CABEZA 0x05 /*Apuntador a la cabeza de la cola en listos*/

#define PROCE_COLA 0x09 /*Apuntador al final de la cola en listos*/

#define PROCE_EJEC 0x0D /*Apuntador al proceso en ejecucion*/

#define PROCW_CABEZA 0x11 /*Apuntador a la cabeza de la cola

de bloqueados*/

#define PROCW_COLA 0x15 /*Apuntador al final de la cola

de bloqueados*/

92

Page 94: ´Indice general - 148.206.53.231

#define NUMPROCESPERA 0x19 /*Numero de procesos bloqueados*/

/*Estados de los procesos*/

#define PROC_INAC 0x00 /*Sin definir*/

#define PROC_ACT 0x01 /*Activo pero no en ejecucion*/

#define PROC_RUN 0x02 /*En ejecucion*/

/*Prioridad del proceso*/

/*Para hacer la relocalizacion de archivos ejecutables EXE */

/*Estas etiquetas indican la posicion en el arreglo de enteros*/

#define LEN_RESFILE 0x01 /*0x02 Residuo de longitud del archivo*/

#define LEN_FILE 0x02 /*0x04 Longitud del archivo

en bloques de 512*/

#define NUM_RELOC 0x03 /*0x06 Numero de elementos de relocalizacion*/

#define LEN_HEADER 0x04 /*0x08 Longitud del encabezado en bloques de 16*/

#define OFF_SS 0x07 /*0x0E Offset SS*/

#define INI_SP 0x08 /*0x10 Inicio de SP*/

#define INI_IP 0x0A /*0x14 Inicio de IP*/

#define OFF_CS 0x0B /*0x16 Offset CS*/

#define INI_RELOC 0x0C /*0x18 Primer elemento de relocalizacion*/

/*Cantidad de memoria para pila que se pedira para cada proceso*/

#define LEN_STACK 0x0C00

/*La frecuencia de operacion en el 8253 u 8254 es de 1193180Hz, */

/*si se desea una frecuencia */

/*diferente, hay que buscar un valor por el cual vamos a */

/*dividir; por ejemplo, si se desea */

/*una frecuencia de 18.2Hz, entonces habra que seleccionar el */

/*numero 0FFFFH, que es que */

/*se asigna por default. Con lo anterior, se estara llamando */

/*una interrupcion a cada 18.2s. */

#define TEMPORIZADOR 0xE90Bh

93

Page 95: ´Indice general - 148.206.53.231

94

Page 96: ´Indice general - 148.206.53.231

Apendice E

dirs.inc

;Este archivo contiene las direcciones de memoria que se usaran a lo largo del

;nucleo, si hay algun cambio en este archivo, entonces habra que cambiar el

;archivo dirs.h. Las direcciones de memoria se listan en el orden en que se

;localizan en la memoria.

SEG_PILA equ 09800h ;Segmento de la pila

;Desplazamiento de la pila (no olvidar que va de arriba a abajo)

OFF_PILA equ 007FFh

;Segmento de los procedimientos de atencion de interrupcion

SEG_INT equ 09880h

SEG_SERVICIOS equ 098C0h ;Segmento de los servicios

SEG_NUCLEO equ 099C0h ;Segmento del nucleo

SEG_MEMORIA equ 09A40h ;Segmento de estructuras de memoria

SEG_LIBRE equ 09E70h ;Segmento de memoria libre

SEG_ENCABEZADO equ 09F30h ;Segmento para almacenar temporalemente el encabezado

SEG_PROCESO equ 09F70h ;Segmento de estructuras de procesos

SEG_VARIABLES equ 09FF0h ;Segmento de las variables

;Primer segmento de memoria libre de 256 bytes (pagina de 256)

DIRINICIOMEM equ 00060h

;Ultimo segmento de memoria libre de 256 bytes (pagina de 256)

DIRFINMEM equ 097F0h

NUMBLQMEM equ 2426 ;Numero de bloques en la estructura de memoria

;Numero de bloques en la estructura de procesos (= Numero de procesos)

NUMBLQPROC equ 46

NUMVARS equ 240 ;Numero de bytes de variables para el SO

95

Page 97: ´Indice general - 148.206.53.231

TAM_PAGINA equ 0100h ;Tamano de pagina, 256 bytes.

;Para cambiar entre segmentos o paginas agregar esta cantidad.

ADD_PAGINA equ 0010h

;Interrupciones

INT_00 equ 0h ;Division entre cero

INT_01 equ 1h ;Trampa

INT_02 equ 2h ;NMI

INT_03 equ 3h ;Trampa

INT_04 equ 4h ;Sobreflujo

INT_08 equ 8h ;Temporizador

INT_10 equ 10h ;Interrupcion de video

INT_13 equ 13h ;Interrupcion del floppy

INT_16 equ 16h ;Interrupcion de teclado

INT_21 equ 21h ;Interrupcion del SO

;Direcciones logicas de la zona de variables

CNTIDPROC equ 00h ;Cuenta el numero de procesos y asigna el id (2)

NUMQUANTUM equ 02h ;Numero de Quatum de tiempo a contar (1)

CNTQUANTUM equ 03h ;Este cuenta los Quantum (1)

NUMPROCEJEC equ 04h ;Numero de procesos en listos

PROCE_CABEZA equ 05h ;Apuntador a la cabeza de la cola en listos

PROCE_COLA equ 09h ;Apuntador al final de la cola en listos

PROCE_EJEC equ 0Dh ;Apuntador al proceso en ejecucion

PROCW_CABEZA equ 11h ;Apuntador a la cabeza de la cola de bloqueados

PROCW_COLA equ 15h ;Apuntador al final de la cola de bloqueados

NUMPROCESPERA equ 19h ;Numero de procesos bloqueados

;Estados de los procesos

PROC_INAC equ 00h ;Sin definir

PROC_ACT equ 01h ;Activo pero no en ejecucion

PROC_RUN equ 02h ;En ejecucion

;Prioridad del proceso

;Para hacer la relocalizacion de archivos ejecutables EXE

;Estas etiquetas indican la posicion en el arreglo de enteros.

96

Page 98: ´Indice general - 148.206.53.231

LEN_RESFILE equ 01 ;0x02 Residuo de longitud del archivo

LEN_FILE equ 02 ;0x04 Longitud del archivo en bloques de 512

NUM_RELOC equ 03 ;0x06 Numero de elementos de relocalizacion

LEN_HEADER equ 04 ;0x08 Longitud del encabezado en bloques de 16

OFF_SS equ 07 ;0x0E Offset SS

INI_SP equ 08 ;0x10 Inicio de SP

INI_IP equ 0A ;0x14 Inicio de IP

OFF_CS equ 0B ;0x16 Offset CS

INI_RELOC equ 0C ;0x18 Primer elemento de relocalizacion

;Cantidad de memoria para pila que se pedira para cada proceso

LEN_STACK equ 0C00h

;La frecuencia de operacion en el 8253 u 8254 es de 1193180Hz,

;si se desea una frecuencia diferente, hay que buscar

;un valor por el cual vamos a dividir; por ejemplo, si se desea

;una frecuencia de 18.2Hz, entonces habra que seleccionar

;el numero 0FFFFH, que es que se asigna por default.

;Con lo anterior, se estara llamando una interrupcion a cada 18.2s.

TEMPORIZADOR equ 0E90Bh

97

Page 99: ´Indice general - 148.206.53.231

98

Page 100: ´Indice general - 148.206.53.231

Apendice F

servis.c

#include "dirs.h"

#define LIB_SO

#include "so.h"

void vSignal (); /*Funcion de prueba*/

proceso *malloc_proc (); /*Solicita memori para agregar el proceso*/

void vServicio00 (); /*-Borrado de pantalla*/

void vServicio01 (); /*-Fijar vector de interrupcion*/

void vServicio02 (); /*-Obtiene vector de interrupcion*/

void vServicio03 (regpack *psrR); /*-Solicita de memoria*/

void vServicio04 (regpack *psrR); /*-Libera memoria*/

void vServicio05 (regpack *psrR); /*-Redefine memoria*/

void vServicio06 (); /*Carga proceso en memoria*/

void vServicio07 (); /*Ejecuta proceso en memoria*/

void vServicio08 (); /*Cambia estado del proceso*/

void vServicio09 (); /*Obtiene el estado del proceso*/

void vServicio10 (regpack *psrR); /*Obtiene Id del proceso

en ejecucion*/

void vServicio11 (regpack *psrR); /*-Obtiene el bloque de memoria

mas grande disponible*/

void vServicio12 (); /*Fin de proceso (mata al que llama)*/

void vServicio13 (); /*Terminar proceso (cualquiera)*/

void interrupt vServicios ()

{ /*Entrada a las interrupciones*/

99

Page 101: ´Indice general - 148.206.53.231

/*Si se declaran mas variables, es necesario */

/*hacerlo al inicio del */

/*prodecimiento, pero NO SE DEBEN INICIAR EN ESE PUNTO, */

/*SINO DESPUES. */

word wAX, wBX, wCX, wDX, wSI, wDI;

regpack srR;

byte bReg;

INI_CORRECCION;

CARGA_REGPACK (srR); /*Carga en regpack los correspondientes

registros*/

/*Direcciones de memoria para las estructuras*/

bReg = wAX >> 8;

switch (bReg)

{

case 0:

vServicio00 (); /*Borrado de pantalla*/

break;

case 1:

vServicio01 (); /*Fijar vector de interrupci0n*/

break;

case 2:

vServicio02 (); /*Obtiene vector de interrupcion*/

break;

case 3:

vServicio03 (&srR); /*Solicita de memoria*/

break;

case 4:

vServicio04 (&srR); /*Libera memoria*/

break;

case 5:

vServicio05 (&srR); /*Redefine memoria*/

break;

case 6:

vServicio06 (&srR); /*Carga proceso en memoria*/

break;

case 7:

vServicio07 (); /**/

break;

case 8:

vServicio08 (); /*Cambia estado del proceso*/

100

Page 102: ´Indice general - 148.206.53.231

break;

case 9:

vServicio09 (); /*Obtiene el estado del proceso*/

break;

case 10:

vServicio10 (&srR); /*Obtiene Id del proceso en ejecucion*/

break;

case 11:

vServicio11 (&srR); /*Obtiene el bloque de memoria mas grande

disponible*/

break;

case 12:

vServicio12 (); /*Fin de proceso (el que llama)*/

break;

case 13:

vServicio13 (); /*Terminar proceso (cualquiera)*/

break;

default:

break;

};

CARGA_REGS (srR); /*Carga en los registros los valores

que hay en regpack*/

FIN_ICORRECCION;

}

void vSignal ()

{ /*Funcion de prueba*/

asm push es

asm push bx

asm push cx

asm mov ch, 65

asm mov bx, 0b800h

asm mov es, bx

asm xor bx, bx

asm mov byte ptr es:[bx], ch

asm pop cx

asm pop bx

asm pop es

}

/*Borrar pantalla */

101

Page 103: ´Indice general - 148.206.53.231

/*Entrada: */

/* AH = 0 */

/*Salida: */

/* Nada */

void vServicio00 ()

{ /*Borrar pantalla*/

regpack srR;

srR.ax = 0x3;

intr (0x10, &srR);

}

/*Fijar vector de interrupcion */

/*Entrada: */

/* AH = 1 */

/* BX = Numero de vector de interrupcion. */

/* DX = Segmento del procedimiento. */

/* CX = Desplazamiento del procedimiento. */

/*Salida: */

/* Nada */

void vServicio01 ()

{ /*Fijar vector de interrupcion*/

asm push bx

asm push ax

asm push cx

asm push ds

asm SHL BX, 1

asm SHL BX, 1

asm XOR AX, AX

asm MOV DS, AX

asm MOV [BX], CX

asm INC BX

asm INC BX

asm MOV [BX], DX

asm pop ds

asm pop cx

asm pop ax

asm pop bx

}

/*Obtiene vector de interrupcion */

/*Entrada: */

102

Page 104: ´Indice general - 148.206.53.231

/* AH = 2 */

/* BX = Numero de vector de interrupcion. */

/*Salida: */

/* DX = Segmento del procedimiento. */

/* CX = Desplazamiento del procedimiento. */

void vServicio02 ()

{ /*Obtiene vector de interrupcion*/

asm PUSH BX

asm PUSH DS

asm PUSH AX

asm SHL BX, 1

asm SHL BX, 1

asm XOR AX, AX

asm MOV DS, AX

asm MOV CX, [BX]

asm INC BX

asm INC BX

asm MOV DX, [BX]

asm POP AX

asm POP DS

asm POP BX

}

/*Solicita memoria */

/*Entrada: */

/* AH = 3 */

/* DX = Cantidad de memoria en paginas de 256b. */

/*Salida: */

/* AH = 0 si hay exito. */

/* DX = Segmento de memoria (desplazamiento es 0). */

/* AH = 1 si no hay exito. */

/* DX = Paginas de 256b de memoria disponibles. */

/* Es posible que exista memoria, pero no pudo */

/* obtenerse el Id del proceso, eso se puede saber */

/* debido a que DX retorna la memoria que se pide. */

void vServicio03 (regpack *psrR)

{ /*Solicita memoria*/

/*Primero se busca un bloque libre, se supone estan ordenados*/

byte bEncontrado;

word wLenMax;

word x, y, wPos, wCmp;

103

Page 105: ´Indice general - 148.206.53.231

regpack srR;

wCmp = psrR->dx;

bEncontrado = FALSE;

wLenMax = 0;

for (x=0; x<NUMBLQMEM; x++)

if (!(psMMem[x].bEnabled))

{

wPos = x; y = 0;

while ((!(psMMem[y+wPos].bEnabled))&&((y+wPos)<NUMBLQMEM))

y++;

if (wCmp<=y)

{ /*Se ha encontrado un bloque, activa el principal y

todos los demas*/

srR.ax = 0;

if (srR.ax&0xFF00) break;

psMMem[wPos].bEnabled = TRUE;

psMMem[wPos].wLen = wCmp;

psMMem[wPos].wIdProc = srR.dx;

for (x=1; x<wCmp; x++) psMMem[wPos+x].bEnabled = TRUE;

x = NUMBLQMEM; bEncontrado = TRUE;

}

wLenMax = y; /*La longitud maxima que se determino*/

}

if (bEncontrado)

{

wLenMax = psMMem[wPos].wSeg;

wPos = 0;

}

else wPos = 0x0100;

psrR->dx = wLenMax;

psrR->ax = wPos;

}

/*NOTA: Verificar Id y segmento de memoria */

/*Libera memoria */

/*Entrada: */

/* AH = 4 */

/* DX = Segmento de memoria (desplazamiento es 0). */

/*Salida: */

/* AH = 0 si hay exito. */

/* DX = Paginas de 256 bytes de memoria liberadas. */

104

Page 106: ´Indice general - 148.206.53.231

/* AH = 1 si no hay exito. */

void vServicio04 (regpack *psrR)

{ /*Libera memoria*/

word wPos, x, y, z;

wPos = psrR->dx;

for (x=0; x<NUMBLQMEM; x++)

{

if (psMMem[x].wSeg==wPos)

{

if ((psMMem[x].bEnabled))

{

z = psMMem[x].wLen + x;

for (y=x; y<z; y++) psMMem[y].bEnabled = FALSE;

psrR->ax = 0;

psrR->dx = y;

}

else psrR->ax = 0x0100;

x = NUMBLQMEM;

}

}

}

/*NOTA: Verificar Id y segmento de memoria */

/*Reasigna la memoria */

/*Entrada: */

/* AH = 5 */

/* DX = Segmento de memoria (desplazamiento es 0). */

/* CX = Nuevo tamano de memoria en bloques de 256b. */

/*Salida: */

/* AH = 0 si hay exito. */

/* DX = Paginas de 256 bytes de memoria reasignadas.*/

/* AH = 1 si no hay exito. */

void vServicio05 (regpack *psrR)

{

word wBlq, w, y, x, z, wPos;

byte bFlag;

wPos = psrR->dx;

wBlq = psrR->cx;

bFlag = FALSE;

for (x=0; x<NUMBLQMEM; x++)

{

105

Page 107: ´Indice general - 148.206.53.231

if (psMMem[x].wSeg==wPos)

{

if ((psMMem[x].bEnabled))

{

z = psMMem[x].wLen;

if (wBlq<z)

{ /*Disminuye la memoria*/

for (y=wBlq+x; y<(z+x); y++)

psMMem[y].bEnabled = FALSE;

/*La cantidad de nuevos bloques*/

psMMem[x].wLen = wBlq;

bFlag = TRUE;

}

else

{ /*Aumenta la memoria*/

y = wBlq - z; w = 0;

while ((!(psMMem[w+x+z].bEnabled))&&

((w+x+z)<NUMBLQMEM)&&(w<y))

w++;

if (w>=y)

{

for (y=z+x; y<(z+x+w); y++) {

vSignal ();

psMMem[y].bEnabled = TRUE;

}

/*Cantidad de nuevos bloques*/

psMMem[x].wLen = wBlq;

bFlag = TRUE;

}

}

}

x = NUMBLQMEM;

}

}

psrR->dx = wBlq;

if (bFlag) psrR->ax = 0;

else psrR->ax = 0x0100;

}

/*Carga proceso en memoria y lo ejecuta */

/*Entrada: */

106

Page 108: ´Indice general - 148.206.53.231

/* AH = 6 */

/* AL = Numero de sectores del proceso (512 bytes). */

/* CH = Pista. */

/* CL = Sector. */

/* DH = Cabeza. */

/* DL = Disco. */

/*Salida: */

/* AH = 0 si hay exito. */

/* DX = Id del proceso ejecutado. */

/* AH = diferente de cero si no hay exito. */

void vServicio06 (regpack *psrR)

{ /*Carga proceso en memoria y lo ejecuta*/

regpack srReg;

word wLenHead, wNumSec, wSeg;

word wPosRel, wNumRel, x;

char far *pscHead, *pscArchivo, *pscMemStack;

int far *pswHead, *pswArchivo;

long lLenArchivo, far *pslArchivo;

byte bSector, bPista, bCabeza, bDisco;

proceso far *pspAux, *pspAux1;

pspAux = malloc_proc ();

if (!pspAux)

{

psrR->ax = 0x0100;

return;

}

pscHead = MK_FP (SEG_ENCABEZADO, 0);

pswHead = MK_FP (SEG_ENCABEZADO, 0);

srReg.ax = 0x0000;

srReg.dx = 0x0000;

intr (0x13, &srReg); /*Reset de disco*/

srReg.es = SEG_ENCABEZADO;

srReg.cx = psrR->cx;

srReg.dx = psrR->dx;

/*Solo se lee un sector, pero se puede leer mas*/

srReg.ax = 0x0201;

srReg.bx = 0;

intr (0x13, &srReg);

wLenHead = *(pswHead + LEN_HEADER) * 16;

lLenArchivo = (*(pswHead + LEN_FILE) - 1) * 512 +

107

Page 109: ´Indice general - 148.206.53.231

*(pswHead + LEN_RESFILE);

lLenArchivo = lLenArchivo - wLenHead;

pscArchivo = (char far *)malloc (lLenArchivo);

wSeg = FP_SEG (pscArchivo);

pswArchivo = MK_FP (wSeg, 0);

if (*(pswHead + LEN_RESFILE)) wNumSec = *(pswHead + LEN_FILE);

else wNumSec = *(pswHead + LEN_FILE) - 1;

bSector = (byte)(psrR->cx);

bPista = (byte)((psrR->cx)>>8);

bDisco = (byte)psrR->dx;

bCabeza = (byte)((psrR->dx)>>8);

srReg.ax = 0x0000;

srReg.dx = 0x0000;

intr (0x13, &srReg); /*Inicia la lectura del resto del archivo*/

do

{

if (bPista<80)

{

if (bSector<18) bSector++;

else

{

bPista++;

bSector = 1;

if (bPista>79)

{

bCabeza++;

bPista = 0;

}

}

}

srReg.ax = 0x0201;

srReg.es = wSeg;

srReg.cx = WORD (bPista, bSector);

srReg.dx = WORD (bCabeza, bDisco);

srReg.bx = 0;

intr (0x13, &srReg);

wSeg = wSeg + 0x20;

wNumSec--;

}

while (wNumSec!=1);

/*Se realiza la relocalizacion*/

108

Page 110: ´Indice general - 148.206.53.231

/*Numero de elementos a relocalizar*/

wNumRel = *(pswHead+NUM_RELOC);

/*En donde inician los elementos de relocalizacion*/

wPosRel =*(pswHead+INI_RELOC);

/*Inicia la creacion del bloque de procesos*/

wSeg = FP_SEG (pscArchivo);

pslArchivo = (long far *)(pscHead + wPosRel);

for (x=0; x<wNumRel; x++)

{

pswArchivo = (word *)(pscArchivo + *(pslArchivo+x));

*(pswArchivo) = *(pswArchivo) + wSeg;

}

/*Pedimos memoria para la pila*/

pscMemStack = (char far *)malloc (LEN_STACK);

/*Se va agregar a la lista de procesos listos para ejecucion*/

(*pWCntProc)++;

pspAux1 = *psPProcListoEjec;

pspAux->wIdProc = *pWCntProc;

pspAux->bPriEdo = PROC_RUN;

pspAux->bEnabled = 1;

pspAux->wSegIni = wSeg;

pspAux->wAX = 0;

pspAux->wBX = 0;

pspAux->wCX = 0;

pspAux->wDX = 0;

pspAux->wSI = 0;

pspAux->wDI = 0;

pspAux->wBP = 0;

pspAux->wSP = FP_OFF(pscMemStack) +LEN_STACK;

pspAux->wIP = 0;

pspAux->wCS = wSeg;

pspAux->wDS = wSeg;

pspAux->wES = wSeg;

pspAux->wDS = wSeg;

pspAux->wSS = FP_SEG (pscMemStack);

pspAux->wF = 0x200; /*Permite la interrupcion*/

pspAux->wIdPadre = pspAux1->wIdProc;

/*Se agrega a la lista*/

pspAux->pspSig = pspAux1->pspSig;

109

Page 111: ´Indice general - 148.206.53.231

pspAux1->pspSig = pspAux;

pspAux->pspAnt = pspAux1;

pspAux1 = pspAux->pspSig;

pspAux1->pspAnt = pspAux;

psrR->ax = 0;

psrR->dx = *pWCntProc;

}

/* */

void vServicio07 ()

{ /**/

}

/*Cambia estado del proceso */

/*Entrada: */

/* AH = 8 */

/* DX = Id del proceso. */

/* BL = Nuevo estado del proceso. */

/*Salida: */

/* AH = 0 Si hay exito. */

/* AH = 1 Si no hay exito */

void vServicio08 ()

{ /*Cambia estado del proceso*/

}

/*Obtiene el estado del proceso */

/*Entrada: */

/* AH = 9 */

/* DX = Id del proceso. */

/*Salida: */

/* AH = 0 Si hay exito. */

/* BL = Estado del proceso. */

/* AH = 1 Si no hay exito */

void vServicio09 ()

{ /*Obtiene el estado del proceso*/

}

/*Obtiene Id del proceso en ejecucion */

110

Page 112: ´Indice general - 148.206.53.231

/*Entrada: */

/* AH = 10 */

/*Salida: */

/* AH = 0 Si hay exito. */

/* DX = Id del proceso. */

/* AH = 1 Si no hay exito */

void vServicio10 (regpack *psrR)

{ /*Obtiene Id del proceso en ejecucion*/

psrR->ax = 0;

}

/*Obtiene el bloque de memoria mas grande disponible*/

/*Entrada: */

/* AH = 11 */

/*Salida: */

/* DX = Paginas de 256b de memoria disponibles. */

void vServicio11 (regpack *psrR)

{ /*Obtiene el bloque de memoria mas grande disponible*/

word x, y;

word wLenMax;

wLenMax = 0;

for (x=0; x<NUMBLQMEM; x++)

if (!(psMMem[x].bEnabled))

{

y = x;

while ((!(psMMem[y].bEnabled))&&(y<NUMBLQMEM)) y++;

if (wLenMax<y) wLenMax = y;

}

psrR->dx = wLenMax;

}

/*Fin de proceso (el que llama) */

/*Entrada: */

/* AH = 12 */

/* AL = Estado */

/*Salida: */

/* Ninguna */

void vServicio12 ()

{ /*Fin de proceso (el que llama)*/

}

111

Page 113: ´Indice general - 148.206.53.231

/*Terminar proceso (cualquiera) */

/*Entrada: */

/* AH = 13 */

/* DX = Id del proceso */

/*Salida: */

/* AH = 0 Si hay exito */

/* AH = 1 Si no hay exito */

void vServicio13 ()

{ /*Terminar proceso (cualquiera)*/

}

#undef LIB_SO

#include "lib\lib1.c"

#include "lib\lib2.c"

112

Page 114: ´Indice general - 148.206.53.231

Apendice G

so.h

#define MK_FP( seg,ofs )( (void _seg * )( seg ) +( void near * )( ofs ))

#define FP_SEG( fp )( (unsigned )( void _seg * )( void far * )( fp ))

#define FP_OFF( fp )( (unsigned )( fp ))

/*Crea un word con dos bytes*/

#define WORD(HB, LB) (((word)(HB)<<8)|(LB))

/*Crea un dword con dos word*/

#define DWORD(HW, LW) (((dword)(HW)<<16)|(LW))

/*Obtienen el word mas significativo de un dword*/

#define HWORD(a) ((a>>16)&0x0000FFFF)

/*Obtiene el word menos significativo de un dword*/

#define LWORD(a) (a&0x0000FFFF)

/*Obtienen el byte mas significativo de un word*/

#define HBYTE(a) ((a>>8)&0x000000FF)

/*Obtiene el byte menos significativo de un word*/

#define LBYTE(a) (a&0x000000FF)

#define TRUE 1

#define FALSE 0

/*************************************************************************/

/*La INI_CORRECCION se debe colocar inmediatamente despues de haber

declarado las variables */

/*locales del procedimiento. La funcion debe llevar la palabra

reservada interrupt. */

/*Estas macros no se deben usar en funciones o procedimientos que

no reciban argumentos, */

/*excepto por los registros salvo bp, sp y ds, ya que estos ultimo

se modifican. */

113

Page 115: ´Indice general - 148.206.53.231

#define INI_CORRECCION

asm { mov si, bp;

sub si, sp;

mov di, [bp];

mov [bp+16], di;

mov di, [bp+6];

add bp, 16;

mov sp, bp;

sub sp, si;

mov si, bp;

mov bp, sp;

mov [bp-2], di;

mov bp, si;

sub sp, 2;

mov si, [bp-12];

mov di, [bp-14] }

#define FIN_CORRECCION asm { pop ds; mov sp, bp; pop bp; iret }

#define FIN_ICORRECCION asm { pop ds; mov sp, bp; pop bp; iret }

#define FIN_FCORRECCION asm { pop ds; mov sp, bp; pop bp; retf }

/*****************************************************************/

/*Estas son unas macros para cargar de los registros a la estructura o*/

/*de la estructura a los registros. Antes de usarlos,

/*es necesario que se*/

/*declaren las siguientes variables: word wAX, wBX, wCX, wDX, wSI,

wDI; */

#define CARGA_REGPACK( srrp )

asm { mov wAX, ax; mov wBX, bx; mov wCX, cx; mov wDX, dx;

mov wSI, si; mov wDI, di };

srrp.ax = wAX; srrp.bx = wBX; srrp.cx = wCX; srrp.dx = wDX;

srrp.si = wSI; srrp.di = wDI;

#define CARGA_REGS( srrp ) wAX = srrp.ax; wBX = srrp.bx;

wCX = srrp.cx; wDX = srrp.dx; wSI = srrp.si; wDI = srrp.di;

asm { mov ax, wAX; mov bx, wBX; mov cx, wCX; mov dx, wDX;

mov si, wSI; mov di, wDI };

/*****************************************************/

typedef unsigned int word;

typedef unsigned char byte;

typedef unsigned long dword;

/************** Zona de estructuras *****************/

114

Page 116: ´Indice general - 148.206.53.231

#ifndef ESTRUCTURA_SO

#define ESTRUCTURA_SO

typedef struct MEMORIA memoria;

struct MEMORIA

{ /*Estructura para memoria; longitud 7 bytes*/

byte bEnabled; /*Habilitado*/

word wSeg; /*Segmento*/

word wLen; /*Numero de bloques de memoria asignado,

solo para el primer bloque*/

word wIdProc; /*Id del proceso dueno de la memoria*/

};

typedef struct DIV_T div_t;

struct DIV_T

{

word wCos;

word wRes;

};

typedef struct PROCESO proceso;

struct PROCESO

{ /*Estructura para procesos: longitud 44 bytes*/

word wIdProc; /*Id del proceso*/

byte bPriEdo; /*Prioridad y estado del proceso*/

byte bEnabled; /*Habilitado*/

word wSegIni; /*Segmento de inicio*/

word wAX; /*Registro AX*/

word wBX; /*Registro BX*/

word wCX; /*Registro CX*/

word wDX; /*Registro DX*/

word wSI; /*Registro SI*/

word wDI; /*Registro DI*/

word wBP; /*Registro BP*/

word wSP; /*Registro SP*/

word wIP; /*Registro IP*/

word wCS; /*Registro CS*/

word wDS; /*Registro DS*/

word wES; /*Registro ES*/

word wSS; /*Registro SS*/

word wF; /*Registro Flags*/

word wIdPadre; /*Id del proceso padre*/

115

Page 117: ´Indice general - 148.206.53.231

proceso far *pspSig; /*Siguiente proceso en lista*/

proceso far *pspAnt; /*Anterior proceso en lista*/

};

typedef struct REGPACK regpack;

struct REGPACK

{

word ax, bx, cx, dx;

word bp, si, di, ds, es, flags;

};

#endif

/*************************************************************************/

#ifdef LIB_SO

memoria far *psMMem = MK_FP (SEG_MEMORIA, 0); /*Para memoria*/

proceso far *psPMem = MK_FP (SEG_PROCESO, 0); /*Para procesos*/

/*Consecutivo Proceso Id*/

word far *pWCntProc = (word far *)(DIRVARIABLES + CNTIDPROC);

/*Longitud del quantum*/

byte far *pBNumQuantum = (byte far *)(DIRVARIABLES + NUMQUANTUM);

/*Contador del quantum*/

byte far *pBCntQuantum = (byte far *)(DIRVARIABLES + CNTQUANTUM);

/*Numero de procesos en cola*/

byte far *pBNumProc = (byte far *)(DIRVARIABLES + NUMPROCEJEC);

/*Cabeza de listos*/

proceso far **psPProcListoCabeza = (proceso far *)

(DIRVARIABLES + PROCE_CABEZA);

/*Cola de listos*/

proceso far **psPProcListoCola = (proceso far *)

(DIRVARIABLES + PROCE_COLA);

/*En ejecucion*/

proceso far **psPProcListoEjec = (proceso far *)

((long)DIRVARIABLES + (long)PROCE_EJEC);

/*Cabeza en bloqueados*/

proceso far **psPProcBloqCabeza = (proceso far *)

(DIRVARIABLES + PROCW_CABEZA);

/*Cola en bloqueados*/

proceso far **psPProcBloqCola = (proceso far *)

(DIRVARIABLES + PROCW_COLA);

#else

extern memoria far *psMMem; /*Para memoria*/

extern proceso far *psPMem; /*Para procesos*/

116

Page 118: ´Indice general - 148.206.53.231

extern word far *pWCntProc; /*Consecutivo Proceso Id*/

extern byte far *pBNumQuantum; /*Longitud del quantum*/

extern byte far *pBCntQuantum; /*Contador del quantum*/

extern byte far *pBNumProc; /*Numero de procesos en cola*/

extern proceso far **psPProcListoCabeza; /*Cabeza de listos*/

extern proceso far **psPProcListoCola; /*Cola de listos*/

extern proceso far **psPProcListoEjec; /*En ejecucion*/

extern proceso far **psPProcBloqCabeza; /*Cabeza en bloqueados*/

extern proceso far **psPProcBloqCola; /*Cola en bloqueados*/

#endif

/******************* Algunas Funciones ***********/

void intr(int int_type, struct REGPACK *preg);

/********************************************/

/*********** Nuestras Funciones *****************/

void gotoxy (byte X, byte Y);

void printf (char far *pcTxt);

void clrscr ();

void gets (char far *pcCad);

void putchar (char cC);

int strlen (char far *pcCad);

void strcat (char far *pcDes, char far *pcOri);

int strcmp (char far *pcDes, char far *pcOri);

int atoi (char far *pcCad);

void itoa (word wVal, char far *pcDes, word wBase);

div_t div (word wNum, word wDen);

div_t ldiv (dword dNum, dword dDen);

void strcpy (char far *pcDes, char far *pcOri);

void far *malloc (dword dMem);

void free (void far *pvMem);

void far *realloc (void far *pvMem, dword dMem);

word wGetMem ();

void exit (byte bRet); /*PENDIENTE*/

/*convierte una letra minuscula a mayuscula*/

int toupper(char letra);

/*convierte una letra mayuscula a minuscula*/

int tolower(char letra);

/*********************************************/

/********* Funciones de Prueba ***************/

void vSinFin ();

/*********************************************/

117

Page 119: ´Indice general - 148.206.53.231

118

Page 120: ´Indice general - 148.206.53.231

Apendice H

proc0.asm

;Codigo del proceso CERO.

;Este proceso sirve para mantener detenido el

;procesador.

.8086

CODIGO SEGMENT USE16

ASSUME CS:CODIGO, DS:CODIGO

org 0000

SIN_FIN_PROC0:

hlt

jmp SIN_FIN_PROC0

CODIGO ENDS

END

119

Page 121: ´Indice general - 148.206.53.231

120

Page 122: ´Indice general - 148.206.53.231

Apendice I

int.asm

.8086

CODIGO SEGMENT USE16

ASSUME CS:CODIGO, DS:CODIGO

include dirs.inc

INT_00H PROC

push ax

push bx

push cx

push dx

push es

push di

push si

mov ax, SEG_INT

mov ds, ax

mov si, offset MSG

;obtenemos la posicion actual del cursor

mov ah, 03h

mov bh, 00h ;pagina de video

int 10h

;dh contiene posicion en y, dl contiene posicion en x

mov ax, 160

mul dh

121

Page 123: ´Indice general - 148.206.53.231

shl dl, 1

xor dh, dh

add ax, dx

mov di, ax

mov ax, 0B800H

mov es, ax

mov cl, 07h ;color de letra blanco y fondo negro

cld

SIGUIENTE:

lodsb

and al,al

jz SALIR

mov es:[di], al

inc di

mov es:[di], cl

inc di

jmp SIGUIENTE

SALIR:

pop si

pop di

pop es

pop dx

pop cx

pop bx

pop ax

iret

ENDP

MSG DB "Division entre cero", 0

CODIGO ENDS

END

122

Page 124: ´Indice general - 148.206.53.231

Apendice J

lib.c

#include "dirs.h"

#include "so.h"

/*****************************************************/

void gotoxy (byte X, byte Y)

{ /*Coloca el cursor en la coordenada (X, Y)*/

regpack srR;

srR.ax = 0x0200;

srR.bx = 0;

srR.dx = WORD (Y, X);

intr (INT_10, &srR);

}

/*****************************************************/

void printf (char far *pcTxt)

{

int i=0;

regpack srR;

srR.bx = 0x001F;

while (pcTxt[i]!=0)

{

putchar (pcTxt[i]);

i++;

}

}

/*****************************************************/

void clrscr ()

{

regpack srR;

123

Page 125: ´Indice general - 148.206.53.231

srR.ax = 0x0003;

intr (INT_10, &srR);

}

/*****************************************************/

void gets (char far *pcCad)

{

int iAux, iPcCad = 0;

char z = 1;

regpack reg;

byte bSalir;

bSalir = FALSE;

while(!bSalir)

{

do

{

reg.ax = 0x0100;

intr(INT_16,&reg);

}

while(!(reg.flags & 0x40));

reg.ax = 0;

intr(INT_16, &reg);

iAux = reg.ax;

switch (iAux&0x00FF)

{

case 8: /*Borrar*/

if (iPcCad > 0)

{

iPcCad = iPcCad - 1;

pcCad[iPcCad] = (char)0;

putchar (8);

putchar (32);

}

break;

case 13: /*ENTER*/

pcCad[iPcCad] = (char)0;

putchar (10);

putchar (13);

bSalir = TRUE;

break;

default: /*Otro*/

pcCad[iPcCad] = LBYTE(reg.ax);

124

Page 126: ´Indice general - 148.206.53.231

iPcCad = iPcCad + 1;

break;

}

if (!bSalir) putchar (iAux&0x00FF);

}

}

/****************************************************/

void putchar (char cC)

{

regpack srR;

srR.ax = WORD (0x0e, cC);

intr (INT_10, &srR);

}

/*****************************************************/

int strlen (char far *pcCad)

{

register int x;

for (x=0; *(pcCad+x); x++);

return (x);

}

/****************************************************/

void vSinFin ()

{

SinFin:

asm hlt

asm jmp SinFin

}

/***************************************************/

void strcat (char far *pcDes, char far *pcOri)

{

int i, j;

for(i=0; pcDes[i]!=0; i++);

for(j=0; pcOri[j]!=0; j++)

{

pcDes[i] = pcOri[j];

i++;

}

pcDes[i] = 0;

}

/***************************************************/

void strcpy (char far *pcDes, char far *pcOri)

125

Page 127: ´Indice general - 148.206.53.231

{

int i;

for(i=0; pcOri[i]!=0; i++)

pcDes[i] = pcOri[i];

pcDes[i] = 0;

}

/***************************************************/

void far *malloc (dword dMem)

{

word wPagMem;

byte bRet;

void far *pvRet;

div_t sdtAux;

regpack srR;

if (!dMem) return (0);

wPagMem = (word)(dMem % TAM_PAGINA);

sdtAux = ldiv (dMem, (dword)TAM_PAGINA);

if (!wPagMem) wPagMem = sdtAux.wCos;

else wPagMem = sdtAux.wCos + 1;

srR.ax = 0x0300;

srR.dx = wPagMem;

intr (INT_21, &srR);

wPagMem = srR.dx;

bRet = HBYTE (srR.ax);

if (bRet) wPagMem = 0;

pvRet = MK_FP (wPagMem, 0);

return (pvRet);

}

/*************************************/

void free (void far *pvMem)

{

regpack srR;

srR.ax = 0x0400;

srR.dx = FP_SEG (pvMem);

intr (INT_21, &srR);

}

/***********************************/

void far *realloc (void far *pvMem, dword dMem)

{

word wPagMem;

byte bRet;

126

Page 128: ´Indice general - 148.206.53.231

void far *pvRet;

div_t sdtAux;

regpack srR;

wPagMem = (word)(dMem % TAM_PAGINA);

sdtAux = ldiv (dMem, (dword)TAM_PAGINA);

if (!wPagMem) wPagMem = sdtAux.wCos;

else wPagMem = sdtAux.wCos + 1;

srR.cx = wPagMem;

srR.dx = FP_SEG (pvMem);

srR.ax = 0x0500;

intr (INT_21, &srR);

bRet = HBYTE (srR.ax);

if (!bRet) return (pvMem);

return (0);

}

/******************************************/

word wGetMem ()

{ /*Regresa los bloques consecutivos de 256b de memoria libre*/

regpack srR;

srR.ax = 0x0b00;

intr (INT_21, &srR);

return (srR.dx);

}

/*****************************************/

div_t ldiv (dword dNum, dword dDen)

{

div_t sdtAux;

word wAX, wDX, wCX;

wDX = (word)((dNum >> 16) & (dword)0xFFFF);

wAX = dNum & (dword)0xFFFF;

wCX = (word)(dDen & (dword)0xFFFF);

asm push ax

asm push cx

asm push dx

asm mov dx, wDX

asm mov ax, wAX

asm mov cx, wCX

asm div cx

asm mov wAX, ax

asm mov wDX, dx

asm pop dx

127

Page 129: ´Indice general - 148.206.53.231

asm pop cx

asm pop ax

sdtAux.wCos = wAX;

sdtAux.wRes = wDX;

return (sdtAux);

}

/**************************************/

div_t div (word wNum, word wDen)

{

div_t sdtAux;

word wAX, wDX;

byte bAH, bCX;

wAX = wNum;

bCX = (byte)(wDen & (word)0x00FF);

asm push ax

asm push cx

asm push dx

asm mov ax, wAX

asm mov cl, bCX

asm div cl

asm mov bAH, ah

asm mov bCX, al

asm pop dx

asm pop cx

asm pop ax

sdtAux.wCos = bCX;

sdtAux.wRes = bAH;

return (sdtAux);

}

/*********************************************/

int strcmp (char far *pcDes, char far *pcOri)

{

int i ;

for (i=0; (pcOri[i]!=0)&&(pcDes[i]!=0); i++)

if (pcOri[i]!=pcDes[i]) return (1);

if ((pcOri[i]==0)&&(pcDes[i]!=0)) return (1);

if ((pcDes[i]==0)&&(pcOri[i]!=0)) return (-1);

return (0);

}

/*********************************************/

void itoa (word wVal, char far *pcDes, word wBase)

128

Page 130: ´Indice general - 148.206.53.231

{

word x=0, y;

char scAux[20];

do

{

y = wVal % wBase;

if (y>9) scAux[x] = (char)y + 55;

else scAux[x] = (char)y + 48;

x++;

wVal = wVal / wBase;

}

while (wVal);

y = 0;

do

{

x--; pcDes[y]= scAux[x]; y++;

}

while (x!=0);

pcDes[y]= 0;

}

/******************************************/

int atoi(char far *pcCad)

{

int val= 0, i= 0;

if(pcCad)

{

while((pcCad[i]>=’0’)&&(pcCad[i]<=’9’)&&(pcCad[i]!=0))

{

val = (pcCad[i] - 48) + (val * 10);

i++;

}

}

return (val);

}

/*****************************************/

//convierte una letra minuscula a mayuscula

int toupper(char letra)

{

if(letra >= ’a’ && letra <= ’z’)

letra = letra - 32;

return ((int)letra);

129

Page 131: ´Indice general - 148.206.53.231

}

/*****************************************/

//convierte una letra mayuscula a minuscula

int tolower(char letra)

{

if(letra >= ’A’ && letra <= ’Z’)

letra = letra + 32;

return ((int)letra);

}

/******************************************/

130

Page 132: ´Indice general - 148.206.53.231

Apendice K

lib1.c

#include "so.h"

/***************************************************************/

/*El siguiente codigo fue extraido de las biblitecas del */

/*Borland Turbo C. Se usa por default el modelo de memoria HUGE.*/

/****************************************************************/

#define LES_ LES

#define ES_ ES:

#define SS_ SS:

#define DPTR_(ea) (dword ptr (ea))

#define dPtrSize 4

#define pushDS_ asm push DS

#define LDS_ LDS

#define popDS_ asm pop DS

#define CPTR_(ea) (dword ptr (ea))

#define EXTPROC(x) (far ptr (x))

#define cPtrSize 4

#define WhereIsBP -36

#pragma inline

#pragma option -r+

void intr(int int_type, struct REGPACK *preg)

{

void (far * Vector)(void);

char Code[14];

/*Save caller context */

asm push bp

asm push ds

131

Page 133: ´Indice general - 148.206.53.231

asm pushf

/*Prepare Interrupt call */

asm lea cx, Code

asm mov word ptr Vector, cx

asm mov word ptr Vector+2, ss

asm mov word ptr Code, 06E8Bh

asm mov byte ptr Code+2, WhereIsBP

asm mov byte ptr Code+3, 0CDh

asm mov ax, int_type

asm mov byte ptr Code+4, al

asm cmp al, 025h

asm jb NormalIntr

asm cmp al, 026h

asm ja NormalIntr

asm mov byte ptr Code+5, 036h

asm mov word ptr Code+6, 00068Fh

asm mov word ptr Code+8, cx

asm mov byte ptr Code+10, 0CAh

asm mov word ptr Code+11, 2

asm jmp SetRegs

asm popf_proc proc near

asm iret /* this proc does a bullet-proof popf */

asm popf_proc endp

NormalIntr:

asm mov byte ptr Code+5, 0CAh

asm mov word ptr Code+6, 2

/*Set registers with register structure content */

SetRegs:

asm LDS_ di, preg

asm push ds

asm push di

asm mov ax,[di].ax

asm mov bx,[di].bx

asm mov cx,[di].cx

asm mov dx,[di].dx

/* BP will be loaded before int xx */

asm push word ptr [di].bp

asm mov si,[di].si

asm mov es,[di].es

asm lds di,[di].di

132

Page 134: ´Indice general - 148.206.53.231

/*Call the interrupt routine */

(* Vector)();

/*Set register structure with registers */

asm push ds

asm push di

asm push bp

asm pushf

asm mov bp,sp

asm lds di,[bp+8] /* DS:DI points to the reg structure*/

asm mov [di].ax,ax

asm mov [di].bx,bx

asm mov [di].cx,cx

asm mov [di].dx,dx

asm mov [di].si,si

asm mov [di].es,es

asm pop [di].flags /* flags */

asm pop [di].bp /* BP */

asm pop [di].di /* DI */

asm pop [di].ds /* DS */

asm add sp,4 /* Remove saved DS:DI*/

asm push cs

asm call popf_proc /* pop flags */

asm pop ds

asm pop bp

}

#pragma option -r.

/*************************************************/

133

Page 135: ´Indice general - 148.206.53.231

134

Page 136: ´Indice general - 148.206.53.231

Apendice L

lib2.c

#include "so.h"

/******************************************************/

/*Contiene el codigo que sera empleado por algunos de */

/*los servicios del nucleo. */

/*****************************************************/

/*****************************************************/

proceso *malloc_proc()

{

int i=0;

proceso far *pspAux=0;

while ((psPMem[i].bEnabled!=FALSE)&&(i<NUMBLQPROC)) i++;

if (i<NUMBLQPROC)

{

psPMem[i].bEnabled=1;

pspAux = &psPMem[i];

}

return (pspAux);

}

/****************************************************/

135