Sunday, November 06, 2005

Generando un kernel con FreePascal

Bueno tal vez el titulo no sea muy descriptivo pero básicamente lo que tratare de explicar es como generar un ejecutable en freepascal sin que este utilice llamadas al sistema , llevando obviamente a la caída del sistema .

A la hora de comenzar a escribir un S.O. la principal duda q se me planteo fue que compilador iba a utilizar . Elegí Freepascal , porque además de gustarme el lenguaje me era fácil portarlo puesto que es independiente del S.O. sobre el cual corra , esto no significa que no utilice llamadas al sistema sino que posee un capa de abstracción de llamadas primitivas las cuales son adaptadas al S.O. sobre el cual corra , es por eso que al compilador no le interesa el S.O. sobre el que se ejecuta .

En el caso de la versión 1.0.6 de FP utilizando el extensor go32v2 el tema es bastante fácil . Cuando se utilizan procedimientos y funciones dependientes del S.O. como por ejemplo writeln , write , read ,etc . ( no así sizeof () , len() , etc . ) el compilador enlazada nuestro ejecutable al archivo objeto donde se encuentran estas llamadas , básicamente lo que se hizo en Toro es capturar estas llamadas , creando el archivo Lib/fpclib/fpclib.pas con estas llamadas y linkeandolo junto con todo el kernel .
Por ejemplo :

llamada muy utilizada para el tratamiento de strings

procedure int_strconcat(s1,s2:pointer);[public,alias:'FPC_SHORTSTR_CONCAT'];
var
s1l, s2l : byte;
type
pstring = ^string;
begin
if (s1=nil) or (s2=nil) then
exit;
s1l:=length(pstring(s1)^);
s2l:=length(pstring(s2)^);
if s1l+s2l>255 then
s1l:=255-s2l;
move(pstring(s1)^[1],pstring(s2)^[s2l+1],s1l);
pstring(s2)^[0]:=chr(s1l+s2l);
end;


También se podría haber linkeado directamente el archivo objeto de FP donde se encontrase la llamada , pero haría crecer el kernel enormemente!!! .


En las unidades mientras no se utilicen llamadas que depende del S.O. o que provengan de unidades externas no hay problema , el compilador no realizara llamadas al sistema .
La cosa cambia con un ejecutable . Cuando se compila el archivo kernel/kernel.pas , este ya no es una unidad sino que es un programa , para volverlo “limpio” de llamadas al sistema lo que se hace es simplemente quitarlas del código assembler :

Extracto del archivo /kernel/Makefile .

$(FPC) $(FPC_FLAGS) kernel.pas

$(GREP) -iv "INIT$$SYSTEM" kernel.s > kernel.tmq
$(GREP) -iv "FPC_INITIALIZEUNITS" kernel.tmq > kernel.tmp
$(GREP) -iv "FPC_DO_EXIT" kernel.tmp > kernel.kkk
$(GREP) -iv "OBJPAS" kernel.kkk > kernel.s


Estas son los símbolos que deben ser retirados y que llevan a la caída del kernel cuando bootea ( a la caída me refiero a una excepción , muy común la 13 )


Una vez compilados todos los archivos objetos son linkeados con ld , puede pasar que tire errores de símbolos desconocidos , es decir hay funciones o procedimiento que están llamando a otros que no se encuentran en los archivos objetos linkeados . Lo mas posible es que haya errores en el tipeado de nombres , o que el head de la función no haya sido declara como publica . Si todo esto no es correcto habría que ver si es una llamada a librerías del compilador , si es así , se debería buscar el procedimiento o función en el código de FP , copiarlo al archivo lib/fpclib/fpclib.pas y declararlo como publico con el alias devuelto como error en ld .



FPC 2.0.0 sobre win32 y linux :

Sobre estas plataformas la cosa no me resulto fácil , lamento informa que no he llegado a una versión booteable del kernel de toro compilado sobre win32 , es por eso que las distribuciones se harán por ahora para go32v2 y para linux , o tal ves solo para linux puesto que se dejaron producir versiones de FPC para DOS .

Para el caso de FPC 2.0.0 sobre linux , al compilar el archivo kernel/kernel.pas solo se quita el símbolo :

$(GREP) -i 'FPC_INITIALIZEUNITS' -v kernel.s > kernel.q


Para el caso de llamadas al sistema lo que opte hacer ahora fue directamente el linkeo de los archivos objeto que contienen las llamadas utilizadas por el compilador estas son :

/usr/lib/fpc/2.0.0/units/i386-linux/rtl/prt0.o
/usr/lib/fpc/2.0.0/units/i386-linux/rtl/system.o
/usr/lib/fpc/2.0.0/units/i386-linux/rtl/objpas.o

Lo que hace es incrementar enormemente el archivo toro-1.1 , que posee casi el triple del mismo archivo generado con el FPC para DOS .


La unidad Lib/fpclib/fpclib.pas deja de utilizarse para el FPC sobre linux . Por supuesto , posiblemente dentro de estos archivos objetos hayan funciones que realicen llamadas al sistema , pero no causaran problemas mientras no se las llame :) .




Espero que este articulo les sirva para saber como se puede generar un ejecutable totalmente booteable (por ejemplo un elf para grub o un binario para un booteador propio) sin que posibles llamadas del compilador lleven a excepciones no deseadas .

Aclaración! si el elf generado va a ser utilizado por un booteador como grub tiene que ser creado bajo la norma multiboot sino grub no podrá levantarlo , toro fue creado bajo ese Standard , en próximos documentos describiré como hacer un elf que pueda ser levantado con grub .



Matias Vara
Toro.sourceforge.net
matiasvara@yahoo.com

Tuesday, November 01, 2005

Compilando el kernel de Toro – 1.1

Este procedimiento es aplicable a partir de la versión 1.1 de Toro .


Una vez obtenido el paquete zip de la versión de Toro debe ser extraído sobre un directorio cualquiera o bien sobre un disket sobre el cual previamente se debe haber instalado grub . En el raíz del disket deben figurar tres directorio : usr , bin y boot , para que grub pueda bootear .

Para comenzar la compilación se debe modificar el archivo /usr/toro-1.1/make.rules completando las variables de make con sus ubicaciones correctas .

El siguiente paso es hacer un make sobre el directorio /usr/toro-1.1/ y listo! , si todo resulta bien será generado el archivo elf ejecutable toro-1.1 y se moverá al directorio /boot para ser levantado por grub durante el booteo .

También deberán ser compiladas la utilidades que se encuentran en el directorio /usr/tools realizando un make en cada directorio y los ejecutables serán movidos al directorio /bin donde se encuentran todos los binarios .

Una vez tenido compilado correctamente Toro sobre el disket podrá ser booteado bien sobre un emulador o directamente sobre la maquina .

También pude ser compilado sobre linux cualquiera sea el booteador instalado mientras levante el elf de Toro , pero de todos modos en este caso también Toro buscara la shell en la disketera .

En próximas versión Toro podrá bootear sobre discos duros o cualquier dispositivo siempre y cuando tenga los drivers requeridos .


Matias E. Vara
Toro.sourceforge.net
matiasvara@yahoo.com

Nuevos posteos

Ire posteando los documentos que se encontraban en papers y otros docuementos de como programar sobre , etc . Espero que les sea interesante . Un sa ludo Matias Vara .