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

1 comment:

JJsoft said...

Hola Matías, te escribo para decirte que tu proyecto me resulta bastante interesante y me emociona bastante ver este tipo de proyectos, yo apenas estoy empezando en la programación, Estudio Ingeniería en sistemas , tengo 17 años soy de República Dominicana y tengo un año y cuatro meses que inicie mis estudios universitarios, me encantaría colaborar contigo en algo , sé diseñar webs en php y mysql, la única aplicación que he hecho la realice en Object pascal(Delphi) y un Blog en php hecho por mi , otra web la realice en php poo algo similar a taringa, y la aplicación que hice en pascal trata de una aplicación de administración de consultorios médicos,puedes ver un ejemplo de la web que realice completamente en php , www.jjsoftcompany.tk , es una especie de blog para publicar las aplicaciones que realizo de forma gratuita todo lo hice yo , incluso el programa que tengo publicado, si necesitas ayuda en algo de este tema puedes contar conmigo.

Tengo unas preguntas acerca de este tema , me intriga bastante y deseo aprender sobre sistemas operativos , desde que inicie la universidad me da curiosidad saber como funcionan los sistemas operativos desde adentro y poder crear o manipular uno me parece algo fantástico, quería preguntarte , qué es lo que necesito profundizar para poder crear un proyecto de esta magnitud , en la web he buscado documentación sin embargo todo lo que aparece está en ingles y no hablo ingles, sin embargo me gustaría saber para un futuro que se necesita para poder crear un proyecto de un sistema operativo aunque sea básico , sé que existen algoritmos ya diseñados , pero no he podido entender,me gustaría que si tienes tiempo , puedas por lo menos responder , que se requiere o lo que se necesita estudiar para poder apoyar proyectos como este y poder desarrollar un sistema operativo te lo agradeceré bastante, espero que estés bien, y que Dios te bendiga y puedas continuar con este maravilloso proyecto.

puedes responderme a este correo, o a jeffreyharry23@hotmail.com.