Modo protegido, dolor de cabeza

Iniciado por lweb20, 4 Marzo 2013, 01:43 AM

0 Miembros y 7 Visitantes están viendo este tema.

lweb20

Todo el kernel está muy estable (obviamente el manual me ayudó un montón). Muchas cosas no las entendía pero poco a poco mientras modificaba el kernel tuve que leer un poco más para pasarlo a español las funciones y tratar de implementar el lenguaje C++ (orientado a objetos). Y discúlpenme pero creo que está mal ubicado el tema en asm (yo lo puse en C). Uso el IDE de Visual Studio porque acostumbro a crear múltiples algoritmos en un solo programa y así tener una gran librería ordenada. Para mi es bueno asm (ya que es ensamblador y no compilador, nasm y masm sí los comprendo muy bien). Comprendo lo de no usar tantas herramientas, pero mi entorno preferido, como dije, es y será siendo Visual Studio (>2010) ya que con él aprendí a programar. Y respecto a las referencias pues son las que todo el mundo usa. Osdev, Osdever, Wikipedia, Wikibooks, El tutorial de JamesM, entre otros. Existe otra que como veo no muchos la conocen y como veo que mucho insisten (no lo tomen a mal) no veo por qué no mostrarlo (Brokenthorn). Bueno ya lo dije, ejem.

¿Qué es lo que pretendo realmente hacer con el formato PE?
- Estudiarlo poco a poco para más adelante crear mi propio formato más liviano. Por qué digo más liviano: Porque para mi ese formato ocupa demasiado espacio en el disco y de esta forma el sistema operativo, aparte del tiempo que demora en buscar el archivo en la unidad de almacenamiento, demora en leer el archivo (ya que probablemente esté dividido en varios fragmentos) y cargarlo en la memoria.

- Crear una librería para mi sistema operativo y así crear aplicaciones en base a mi sistema operativo y de esta forma facilitar el llamado a syscall. Por ejemplo para leer un archivo usaría una sintaxis muy simple y en español.

Archivo archivo = SysAbrirArchivo("C:\\archivo.txt");
char* buffer = malloc(Archivo->Tamaño);
SysEstablecerPosiciónArchivo(archivo, 0); // es como un seek
SysLeerArchivo(archivo, buffer, Archivo->Tamaño);
SysCerrarArchivo(archivo);


Algo súper simple y entendible.

Todo esto lo digo porque tuve la oportunidad de leer un sistema operativo hecho en ASM con librería en C de 64 bits (que seguramente muchos saben de cuál se trata) que tenía syscalls e hice algunos programas en base a ese sistema (nasm y gcc).

Eternal Idol

Cita de: lweb20 en  4 Marzo 2013, 15:39 PMY discúlpenme pero creo que está mal ubicado el tema en asm (yo lo puse en C).

Ahi estaria peor ubicado cuando es necesario para la mitad de lo que mostras inline assembly  ;) Aca no tenemos un sub-foro para desarrollo de Kernel/SOs, tal vez debas buscar un foro especifico, pero todos los temas tratados estan mas cercanos a ensamblador que a C++.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

lweb20

#12
Cita de: Eternal Idol 7D en  4 Marzo 2013, 15:46 PM
Ahi estaria peor ubicado cuando es necesario para la mitad de lo que mostras inline assembly  ;)

... todos los temas tratados estan mas cercanos a ensamblador que a C++.

Eso es cierto.

Cita de: Eternal Idol 7D en  4 Marzo 2013, 15:46 PM
... tal vez debas buscar un foro especifico

¿Cómo así?

Cita de: Eternal Idol 7D en  4 Marzo 2013, 15:46 PM
Aca no tenemos un sub-foro para desarrollo de Kernel/SOs,

Debería haber :D

Ahh y una pregunta. Estoy depurando con Bochs y quiero que mediante el código hacer un punto de interrupción ¿se podrá? (disculpen la ignorancia xD) Por ejemplo ejecutando int 0x3? o int 0x1?

Eternal Idol

Cita de: lweb20 en  4 Marzo 2013, 15:54 PM¿Cómo así?

Uno como OSDev, especifico del tema.

Cita de: lweb20 en  4 Marzo 2013, 15:54 PMDebería haber :D

No realmente, los sub-foros se crean de acuerdo a la demanda, de esto sobran los dedos de las manos para contar a los realmente interesados  ::)

Cita de: lweb20 en  4 Marzo 2013, 15:54 PMAhh y una pregunta. Estoy depurando con Bochs y quiero que mediante el código hacer un punto de interrupción ¿se podrá? (disculpen la ignorancia xD) Por ejemplo ejecutando int 0x3? o int 0x1?

http://bochs.sourceforge.net/doc/docbook/user/internal-debugger.html
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

lweb20

#14
Desgracia: (xD)



Se pasó hasta abajo del código. Quería un breakpoint ahí.

voy a ver el enlace que me dejaste.

EDIT:

El problema es que quiero parar en una línea específica mas no en una parte de la memoria. La verdad que nunca pude hacer eso, ¿alguna idea? usé el trace y show pero muuuucho "trace" de lo que espero. Como hay varios controladores aparece un trace gigantesco (se cuelga y no continúa) y no logro captar el código que realmente quiero ver.

El Bochs debería tener un puerto (out) para hacer debug :P

Eternal Idol

Busca la direccion de la instruccion especifica y listo ... fijate si podes generar simbolos de depuracion (ahi en el enlace que te deje lo mencionan), asi se te simplificaria bastante el asunto ...
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

lweb20

#16
Gracias :D ya tengo la dirección. Todos se equivocan :) (yo)

Qué bonita dirección xD: 0xC0004330

Ups problema, creo que me equivoqué. La dirección que necesito es la dirección antes de ejecutar ese código verdad? yo la obtuve de la función a ejecutar. ¿Cómo obtengo la dirección de la posición actual? ni idea :S

Por sea caso: cuando pregunto algo siempre voy buscando y viendo la forma de solucionarlo, no me quedo estático esperando la respuesta.

Eternal Idol

Registro EIP = EXTENDED INSTRUCTION POINTER.

No se que usas para compilar el Kernel pero en VC++ podes generar listings con archivos .asm y .map (/FAcs, /map o cosas por el estilo) por ejemplo, ahi verias las direcciones facilmente.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

~

#18
Editado por un detalle práctico que olvidé: Para modo de 64 bits, para poder ejecutar interrupciones como las de video, no hay más opción que implementar o usar un emulador como x86emu (referenciado ampliamente en la Wiki y el foro de OSDev):

x86emu.zip

Por esto aconsejo ir rápido, pero también escuchar lo que otros tenemos que decir en lo que hemos intentado antes. En otras palabras, es mejor olvidarse en mayor medida del modo v86 virtual del modo de 32 bits y usar emulación de software, si uno no tiene drivers de video y aun así quiere poder cambiar modos de video.





Cita de: lweb20 en  4 Marzo 2013, 15:39 PM
Todo el kernel está muy estable (obviamente el manual me ayudó un montón). Muchas cosas no las entendía pero poco a poco mientras modificaba el kernel tuve que leer un poco más para pasarlo a español las funciones y tratar de implementar el lenguaje C++ (orientado a objetos). Y discúlpenme pero creo que está mal ubicado el tema en asm (yo lo puse en C). Uso el IDE de Visual Studio porque acostumbro a crear múltiples algoritmos en un solo programa y así tener una gran librería ordenada. Para mi es bueno asm (ya que es ensamblador y no compilador, nasm y masm sí los comprendo muy bien). Comprendo lo de no usar tantas herramientas, pero mi entorno preferido, como dije, es y será siendo Visual Studio (>2010) ya que con él aprendí a programar. Y respecto a las referencias pues son las que todo el mundo usa. Osdev, Osdever, Wikipedia, Wikibooks, El tutorial de JamesM, entre otros. Existe otra que como veo no muchos la conocen y como veo que mucho insisten (no lo tomen a mal) no veo por qué no mostrarlo (Brokenthorn). Bueno ya lo dije, ejem.
BokenThorn también es una referencia común que todos conocemos, y es muy similar a la de JamesM.

Sobre Visual Studio, al fin de cuentas sería irrelevante en un nuevo sistema operativo, y sería necesario aprender otras herramientas, incluso propias. De lo contrario uno sería demasiado dependiente, el sistema sería débil también en ese aspecto, y de todas maneras Visual Studio o cualquier herramienta son lo de menos cuando uno escribe un sistema operativo, tratando de entender todos los formatos, convenciones y estándares por uno mismo.

Es mejor dejar de depender de estas herramientas en este ámbito. Yo también empecé programando en Visual Basic 6, pero ahora no pienso sino en que si uso esos lenguajes, sea yo quien los implemente, o mi esfuerzo quedaría atrapado esclavo a esas herramientas y lenguajes, en lugar de estar totalmente a mi cargo y ser libre.

Cita de: lweb20 en  4 Marzo 2013, 15:39 PM¿Qué es lo que pretendo realmente hacer con el formato PE?
- Estudiarlo poco a poco para más adelante crear mi propio formato más liviano. Por qué digo más liviano: Porque para mi ese formato ocupa demasiado espacio en el disco y de esta forma el sistema operativo, aparte del tiempo que demora en buscar el archivo en la unidad de almacenamiento, demora en leer el archivo (ya que probablemente esté dividido en varios fragmentos) y cargarlo en la memoria.
Yo no recomendaría crear un formato propio de ejecutable. Incluso gente mucho más experta evita hacer esto, simplemente porque esto representa una desconexión total con el resto del mundo informático.

Una vez tras otra he comprobado que solo porque crear algo como un formato me resulte aparentemente más fácil que entender otro que alguien más hizo, y que todo el mundo usa, no significa que diseñarlo sea conveniente, comenzando porque será mucho menos robusto y nadie más lo va a usar (en otras palabras, un punto de muerte para un proyecto).

Pero tal vez sirva este formato de ejecutable que he creado para mi kernel. Este es capaz de importar funciones del kernel. Hasta ahora no necesito modo de usuario ni multitareas porque estoy aprendiendo hasta los detalles más intrincados del hardware, y para asegurarme de que mi entendimiento en eso no tenga fallas, estoy creando un emulador de PC.


Este es el programa de muestra, y se puede definir perfectamente en C++ o en C, etc:;v2012-06-29
;
;This is a version of CMDARGS2 that uses only imported functions
;from the kernel, and a new, slightly expanded header, to make possible
;for the kernel to link functions/variables imported by the application,
;for itself, instead of having the application do that.
;;


APPBASE equ 1048576*2

bits 32
org APPBASE



%include "include/external_exported_variables.inc"
%include "include/external_exported_functions.inc"



;Our kernel must read this address, jump
;to it and then skip it:
;;
IntendedBaseAddress  dq APPBASE
NumberOfFieldsBelow  dq 7
CommandLinePtr       dq 0
CommandLineLength    dq 0
CommandLineParamsPtr dq 0
KernelFnExportsTable dq 0
KernelVrExportsTable dq 0
AppFnImportsTable    dq myImportsFunctionsTable
AppVrImportsTable    dq 0



;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++





;Clean the screen:
;;
call dword[clrscr]





;;;INIT: Print each command line parameter in a separate line
;;;INIT: Print each command line parameter in a separate line
;;;INIT: Print each command line parameter in a separate line
;;;INIT: Print each command line parameter in a separate line





;Prepare to show the command line, one parameter a line.
;See if the length of the application's command line can possibly
;contain parameters. If it is 11 bytes or less, it cannot contain
;parameters as of our current kernel:
;;
mov eax,[CommandLineLength]
cmp dword[eax],11
jbe .noparams



;Get rid of the application's raw FAT file name,
;as of our current kernel:
;;
mov esi,[CommandLinePtr]
call dword[adjustCommandLineFATname]

;If we detected that there are no parameters after
;stripping the file name, end:
;;
cmp eax,0
 je .noparams






;Print the received command line:
;;
;      ESI == ASCIIZ string to print
;
;;
 ;Also get rid of the application's command line in our
 ;command line pointer:
 ;;
  mov esi,eax
  mov [CommandLinePtr],esi
  call dword[console_kprint_visible]


;Go to a new line:
;;
call dword[console_doCRLFeffect]




;Get the number of parameters in the command line. At this
;point there cannot possibly be an parameter-less command line:
;;
;Inputs:
;      ESI == ASCIIZ string
;
;Outputs:
;      EAX == Number of present parameters in the command line,
;             each other separated with blank spaces.
;;
 mov esi,[CommandLinePtr]
  call dword[getCommandLineArgsCount]
   mov ebx,eax
   xor ecx,ecx


;Set our destination pointer to copy the specified
;parameters one by one:
;;
mov edi,cmdstrbuff





;Do a loop to print all of the command line parameters
;individually:
;;
.parloop:



;Copy the current argument:
;;
 ;Inputs:
 ;       ESI == Command line string
 ;       EDI == String buffer to copy the argument to
 ;       ECX == Argument number (from 0)
 ;
 ;
 ;Outputs:
 ;       EAX == Nonzero if the argument was found, or 0 if the argument was not found
 ;
 ;;
    call dword[copyCommandLineArg]



;Print the argument we just copied:
;;
 ;Print the received command line:
 ;;
  ;      ESI == ASCIIZ string to print
  ;
  ;;
   xchg esi,edi
    call dword[console_kprint_visible]
    call dword[console_doCRLFeffect]
   xchg esi,edi



;Go to the next parameter. If it is still
;below the natural parameter count, keep
;looping:
;;
 inc ecx
 cmp ecx,ebx
 jb .parloop






;;;END:  Print each command line parameter in a separate line
;;;END:  Print each command line parameter in a separate line
;;;END:  Print each command line parameter in a separate line
;;;END:  Print each command line parameter in a separate line



;We will jump here if our program has no parameters, which means
;that this program won't do anything if we have no command line
;parameters:
;;
.noparams:





;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++







;Return control to the kernel:
;;
ret







;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps
;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps
;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps
;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps
;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps
;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps
;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps
;;;INIT: This is the most decent place to put application variables and data without memory management and without code jumps










myImportsFunctionsTable:
                  ImportsCount dd 6
                          clrscr dd clrscr@KernelCore
          console_kprint_visible dd console_kprint_visible@KernelCore
          console_doCRLFeffect   dd console_doCRLFeffect@KernelCore
adjustCommandLineFATname          dd adjustCommandLineFATname@KernelCore
getCommandLineArgsCount           dd getCommandLineArgsCount@KernelCore
copyCommandLineArg                dd copyCommandLineArg@KernelCore






cmdstrbuff times 1024 db 0










;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps
;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps
;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps
;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps
;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps
;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps
;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps
;;;END:  This is the most decent place to put application variables and data without memory management and without code jumps


Cita de: lweb20 en  4 Marzo 2013, 15:39 PM- Crear una librería para mi sistema operativo y así crear aplicaciones en base a mi sistema operativo y de esta forma facilitar el llamado a syscall. Por ejemplo para leer un archivo usaría una sintaxis muy simple y en español.

Archivo archivo = SysAbrirArchivo("C:\\archivo.txt");
char* buffer = malloc(Archivo->Tamaño);
SysEstablecerPosiciónArchivo(archivo, 0); // es como un seek
SysLeerArchivo(archivo, buffer, Archivo->Tamaño);
SysCerrarArchivo(archivo);


Algo súper simple y entendible.

Todo esto lo digo porque tuve la oportunidad de leer un sistema operativo hecho en ASM con librería en C de 64 bits (que seguramente muchos saben de cuál se trata) que tenía syscalls e hice algunos programas en base a ese sistema (nasm y gcc).
Eso parece simple pero crear una librería capaz no solo de crear manejadores de archivo de forma estable, sino entender el formato del disco es algo avanzado, y no necesita modo de usuario para poder experimentar con esos algoritmos. Incluso en FAT12, definir unidades e ir más allá del directorio raíz necesita más estudio.

Yo ofrezco definir una investigación en este tema sobre lo que sé (leer archivos del directorio raíz de FAT12), y desde ahí definir cómo se logra más que eso, de forma implementada, con código y explicaciones reales.





Y sobre Bochs, este tiene una instrucción o un puerto de depuración, pero nunca lo he usado porque lo considero contaminar el código.

Lo que hago simplemente es hacer microprogramas con funciones de una futura librería, y los depuro incluso bajo Windows, o usando javascript, o en DOS. De esta forma es mucho más fácil saber qué está mal.

También es posible hacer un dump de la memoria de Bochs, y examinar si esta contiene la estructura que uno esperaría (especialmente en versiones de Bochs cercanas a la 2.6, etc.).





Todo esto es algo que puedo hacer (leer un programa del floppy y ejecutarlo). Tal vez hay problemas con el código de modo usuario, pero sin ver nada de código, y menos aun sin saber la lógica con la que se ha pensado, es imposible saber o ayudar demasiado.

Como digo, para apdender sobre muchos algoritmos, incluso cargar programas de forma multitarea, no requiere modo usuario (y se puede comenzar a hacer algo útil para un kernel que realmente uno vaya a usar de forma entusiasta y que aporte conocimiento -necesario para avanzar con paso firme, evitando estos errores de principiantes y superarlos a lo sumo en 1 año en lugar de en mucho mas que eso-, como visualizar GIFs, BMPs, documentos de texto, iconos, y trucos de hardware, entrar a modo de 64 bits, crear compiladores o ensambladores simples, etc.).

La idea es que lo que se aprenda en el lado de un kernel propio sea usable en cualquier otro entorno. O sino, ¿cuál sería el objetivo, y cuál sería el verdadero beneficio más allá de crear un kernel simple, que muchos hemos creado, pero de forma incompleta e inestable (inestable en que no lo usaremos demasiado ni podríamos fácilmente agregarle demasiadas cosas útiles)?
Sitio web (si la siguiente imagen no aparece es porque está offline):

lweb20

#19
Cita de: ~ en  4 Marzo 2013, 16:56 PM
Por esto aconsejo ir rápido, pero también escuchar lo que otros tenemos que decir en lo que hemos intentado antes. En otras palabras, es mejor olvidarse en mayor medida del modo v86 virtual del modo de 32 bits y usar emulación de software, si uno no tiene drivers de video y aun así quiere poder cambiar modos de video.
.......


Mmm. Amigo no lo tomes a mal, pero sobre el modo usuario sólo es una alternativa para aislar las aplicaciones normales del kernel. No estoy TAN (!) obsesionado con eso. Sé lo que me dices. Llevo meses con ese kernel y he estudiado la FAT como tu.