Autor Thema: Ausgabe in C erfolgt nicht  (Gelesen 6808 mal)

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« am: 13. December 2005, 22:12 »
Hallo,
Ich bin nun endlich in C, glaube ich zumindest und habe gleich ein Problem mit der Ausgabe eines Textes, ich glaube das er den C Kernel mit seinen Anhängseln lädt weil wenn ich zum Beispiel die Textausgabe auskommentiere in der main.c macht er gar nichts, oder wenn ich alles an lasse dann zeigt er in der linken oberen Ecke einen Querstrich an, wiso gibt er dort nicht meinen gewollten Text aus, ich habe mal meinen gesamten code angehängt vielleicht kann mir jemand helfen wäre wirklich wichtig.
Hier noch eine kleine Erklärung:
meine bootloader.bin lädt meine kernel.bin, meine kernel.bin wächselt in den Protected Mode und springt dann zu meinem kernel2.bin der aus den gelinkten *.o files besteht (kernel_to_c.asm, main.c, video.c, ports.c)
Danke

bootloader.bin:

org 0x7C00

start:

cli
mov ax, 0x9000
mov ss, ax
mov sp, 0
sti

mov [bootdrv], dl

call kernel

mov ax, 0x1000
mov es, ax
mov ds, ax
push ax
mov ax,0
push ax
retf

bootdrv db 0
loadmsg db "Loading...",13,10,0

putstr:
lodsb
or al, al
jz short putstrd

mov ah, 0x0E
mov bx,0x0007
int 0x10
jmp putstr
putstrd:
retn

kernel:

push ds
mov ax, 0
mov dl, [bootdrv]
int 13h
pop ds
jc kernel

load:
mov ax,0x1000
mov es, ax
mov bx,0

mov ah, 2
mov al, 5
mov cx, 2
mov dx, 0
int 13h
jc load
mov si, loadmsg
call putstr
retn

times 512-($-$$)-2 db 0
dw 0AA55h




kernel.bin:

org 0x10000
[BITS 16]       ; We need 16-bit intructions for Real mode

        cli                     ; Disable interrupts, we want to be alone

        mov ax, 0x1000
        mov ds, ax              ; Set DS-register to 0 - used by lgdt

        lgdt [gdt_desc]         ; Load the GDT descriptor

        mov eax, cr0            ; Copy the contents of CR0 into EAX
        or eax, 1               ; Set bit 0
        mov cr0, eax            ; Copy the contents of EAX into CR0

        jmp dword 08h:clear_pipe      ; Jump to code segment, offset clear_pipe


[BITS 32]                       ; We now need 32-bit instructions

clear_pipe:
        mov ax, 10h             ; Save data segment identifyer
        mov ds, ax              ; Move a valid data segment into the data segment register
        mov ss, ax              ; Move a valid data segment into the stack segment register
        mov esp, 090000h        ; Move the stack pointer to 090000h

        ;mov byte [ds:0B8000h], 'X'      ; Move the ASCII-code of 'P' into first video memory
        ;mov byte [ds:0B8001h], 1Bh      ; Assign a color code


jmp 0x10095

;hang:
 ;       jmp hang                ; Loop, self-jump


gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
        dd 0
        dd 0

gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0FFFFh
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

gdt_data:               ; Data segment, read/write, expand down
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0

gdt_end:                ; Used to calculate the size of the GDT



gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd gdt                  ; Address of the GDT




kernel_to_c.asm:


[BITS 32]

extern _main  
global start  

start:
 call _main  

Stop:
 jmp Stop



main.c:

const char *tutorial3;

int main()
{

  clrscr();
  print(tutorial3);
  for(;;);
}

const char *tutorial3 = "Hallo, Willkommen in C";


video.c:

void clrscr()
{
  unsigned char *vidmem = (unsigned char *)0xB8000;
  const long size = 80*25;
  long loop;

  // Clear visible video memory
  for (loop=0; loop<size; loop++) {
    *vidmem++ = 0;
    *vidmem++ = 0xF;
  }

  // Set cursor position to 0,0
  out(0x3D4, 14);
  out(0x3D5, 0);
  out(0x3D4, 15);
  out(0x3D5, 0);
}

void print(const char *_message)
{
  unsigned short offset;
  unsigned long i;
  unsigned char *vidmem = (unsigned char *)0xB8000;

  // Read cursor position
  out(0x3D4, 14);
  offset = in(0x3D5) << 8;
  out(0x3D4, 15);
  offset |= in(0x3D5);

  // Start at writing at cursor position
  vidmem += offset*2;

  // Continue until we reach null character
  i = 0;
  while (_message[i] != 0) {
    *vidmem = _message[i++];
vidmem += 2;
  }

  // Set new cursor position
  offset += i;
  out(0x3D5, (unsigned char)(offset));
  out(0x3D4, 14);
  out(0x3D5, (unsigned char)(offset >> 8));
}



ports.c:

unsigned char in(unsigned short _port)
{
  // "=a" (result) means: put AL register in variable result when finished
  // "d" (_port) means: load EDX with _port
  unsigned char result;
  __asm__  ("in %%dx, %%al" : "=a" (result) : "d" (_port));
  return result;
}

void out(unsigned short _port, unsigned char _data)
{
  // "a" (_data) means: load EAX with _data
  // "d" (_port) means: load EDX with _port
  __asm__ ("out %%al, %%dx" : :"a" (_data), "d" (_port));
}



makefile2.bat mit den link anweisungen:

nasm -f aout -o kernel2.o kernel.asm

gcc -ffreestanding -c main.c -o main.o

gcc -c video.c -o video.o

gcc -c ports.c -o ports.o

ld -e _main -Ttext 0x10095 -o kernel.o kernel2.o main.o video.o ports.o

objcopy -R .note -R .comment -S -O binary kernel.o kernel2.bin

pause

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 14. December 2005, 22:14 »
Jetzt erhalte ich das "Loading..." vom Bootloader wie immer und danach ein "S " aus dem C Kernel als ausgabe, warum nicht meinen text ?

hannibal

  • Host
  • Beiträge: 400
    • Profil anzeigen
    • brainsware - the rock.
Gespeichert
« Antwort #2 am: 15. December 2005, 17:15 »
Zitat von: syxce
Jetzt erhalte ich das "Loading..." vom Bootloader wie immer und danach ein "S " aus dem C Kernel als ausgabe, warum nicht meinen text ?


warum weist du der const-variable nicht gleich den wert zu? hat das irgendeinen tieferen sinn?
\\o
o//
\o/

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 15. December 2005, 17:25 »
Ah, danke, jetzt löscht er schon mal den ganzen Bildschirm und schreibt ins linke obere eck wieder ein "S ", aber auch schon in der gewollten Schrift.
Er sollte jedoch den gewollten Text schreiben, wie kann das sein das er nur ein "S " ausgibt anstatt "Wir sind in C", vll is im Videospeicher irgendeine Adresse schon belegt oder so ?

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 15. December 2005, 19:22 »
hi,
oder dein beim Linken stimmt was mit den Offsets bei den Variablen nicht.
wenn ich den Text, der an Adresse 0 steht, ausgebe kommt auch ein "S "  :D

ich kenn mich mit C++ Compilern nicht aus aber:
ld -e _main -Ttext 0x10095 -o kernel.o kernel2.o main.o video.o ports.o

bedeutet das dass NUR der Code auf eine Basisadresse von 0x10095 abgestimmt wird oder Code und Data ?

mfg,
stefan

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 15. December 2005, 19:35 »
Ich würde mit ziemlicher Sicherheit sagen das beide darauf abgestimmt werden, aber wenn er den C Kernel findet und meine clrscr Funktion sowie meine getch Funktion verwendet warum geht dann die Ausgabe print nicht, da müsste der Fehler dann eigentlich in der Video.c liegen oder nicht, genauer in der Funktion print, aber wo  :?:

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 15. December 2005, 20:03 »
hi
Funktionen werden inzwischen normalerweise unabhängig von der Basisadresse aufgerufen (außer bei Far-Jump), sondern per Differenz angegeben.
Und da du bei Clrscr lokale Variablen benutzt, die auf den Stack gespeichert werden und deshalb auch unabhängig sind, kommt nur noch diese Variable in Fragen, die als Global deklariert ist und abhängig vom Data-Addr ist.

mfg,
stefan

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 15. December 2005, 20:13 »
Achso, aber wo der Fehler dann in der "Print" Funktion liegt weißt du auch nicht direkt oder, diese hält mich mittlerweile schon einige Tage auf !? :?

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 19. December 2005, 07:39 »
Weiß niemand weiter ? :(

syxce

  • Beiträge: 45
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 20. December 2005, 19:51 »
Ich habe eine interessante Feststellung gemacht und zwar wenn ich den kernel_to_c.asm komplett weglasse dann passiert das gleiche wie vorher, es wird nur der Bildschirm gelöscht  und ein "S " ausgegeben, wie kann das sein ?

 

Einloggen