c++ c assembly operating-system kernel

c++ - ¿Cómo escribir un kernel hola mundo?



assembly operating-system (4)

Estoy escribiendo un kernel, de modo que estoy empezando con un programa de hello world en kernel.

He escrito un kernel hola mundo en c ++ y se compila con éxito.

Pero cuando lo arranco, no muestra nada en la pantalla.

¿Qué hay de malo con este código?

link.ld

OUTPUT_FORMAT("binary") ENTRY(start) SECTIONS{ . = 0x00100000; .text :{ *(.text) } .rodata ALIGN (0x1000) : { *(.rodata) } .data ALIGN (0x1000) : { *(.data) } .bss : { sbss = .; *(COMMON) *(.bss) ebss = .; } }

loader.asm

[BITS 32] global start extern _main start: call _main cli hlt

video.h

#ifndef VIDEO_H #define VIDEO_H class Video{ public: Video(); ~Video(); void clear(); void write(char *cp); void put(char c); private: unsigned short *videomem; unsigned int off; unsigned int pos; }; #endif

video.cpp

#include "Video.h" Video::Video(){ pos = 0; off = 0; videomem = (unsigned short*)0xb8000; } Video::~Video(){} void Video::clear(){ unsigned int i; for(i=0;i<(80*25);i++){ videomem[i] = (unsigned short)'' ''|0x0700; } pos = 0; off = 0; } void Video::write(char *cp){ char *str = cp, *ch; for(ch=str;*ch;ch++){ put(*ch); } } void Video::put(char c){ if(pos>=80){ pos = 0; off+=80; } if(off>=(80*25)){ clear(); } videomem[off+pos] = (unsigned short)c|0x0700; pos++; }

Kernel.cpp

#include "Video.h" int _main(void){ Video vid; vid.clear(); vid.write("Hello World!"); }

Lo estoy compilando usando estos comandos:

g++ -c video.cpp -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions g++ -c Kernel.cpp -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions nasm -f aout Loader.asm -o Loader.o ld -T linker.ld -o Kernel.bin Loader.o Video.o Kernel.o

No da ningún error.

Si es posible depurar, por favor ayúdeme a cómo depurar.

Lo estoy arrancando en la caja virtual.

Cualquier ayuda será apreciada.


¿Has probado qemu? Cuando se hizo un pequeño sistema operativo en la universidad, resultó ser el mejor programa para este tipo de cosas.


Cuando se inicia una PC, el BIOS cargará lo que esté en el MBR en la dirección física 0x7c00 y luego saltará a esa dirección. Por lo tanto, debe vincular su código a partir de 0x7c00 en lugar de a 0x00100000.

Por lo tanto, cambiar el script del enlazador de la siguiente manera debería resolver el problema:

... SECTIONS{ . = 0x7c00; ... }

EDITAR: Después de mirar su código, noté algunos problemas más. Si no está utilizando un gestor de arranque, hay algunas cosas que debe configurar antes de poder comenzar a ejecutar el código de 32 bits, lo que es más importante, habilitar el modo protegido. Here hay algunos tutoriales para ayudarte en tu camino.


Para que esto funcione tendrás que:


Si lo desea, puede revisar el sistema operativo que se usó como ejemplo en mi clase este semestre. Se hace en c . Estábamos usando el gestor de arranque GRUB, y qemu para ejecutar cosas.

Está escrito de forma bastante clara en incrementos, el primer incremento es precisamente el sistema operativo "Hello world" y el último incremento que contiene todo desde un shell completo, subprocesos y procesos y muchas otras cosas. Puede encontrar ejemplos de códigos fuente, makefiles y scripts de vinculador allí (desde los simples hasta los ejemplos bastante complejos)

http://sourceforge.net/projects/oszur11/

También enlazaría con el script después de los incrementos, pero desafortunadamente no en inglés.

Ah, y también, hay un incremento dedicado especialmente a la depuración allí, pero eso es más para depurar los procedimientos realizados para su sistema operativo que depurar el sistema operativo en su conjunto (si recuerdo bien, estábamos usando dos consolas, una con qemu y otra con gdb conectado al sistema operativo que se ejecuta en el otro).