# Kernel Coden - Problem



## indylein (7. April 2005)

Hallo, ich bin gerade dabei einen Kernel zu coden 
 Zuerst einen Assemblerteil zum starten und dann den eigendlichen Kernel in C.

 Ich poste hier einfach mal den Code und schildere damit das Problem:


 boot.asm (kompiliert boot.bin)

```
org 0x7C00
 
 start:
 cli
 mov ax, 0x9000
 mov ss, ax
 mov sp, 0
 sti
 
 mov [bootdriv], dl
 call load
 
 mov ax, 0x1000
 mov es, ax
 mov ds, ax
 push ax
 mov ax, 0
 push ax
 retf
 
 bootdriv db 0
 loadmsg db "Loading Blueberry Kernel",13,10,0
 
 putstr:
 lodsb
 or al,al
 jz short putstrd
 mov ah,0x0E
 mov bx,0x0007
 int 0x10
 jmp putstr
 
 putstrd:
 retn
 
 load:
 push ds
 mov ax, 0
 mov dl, [bootdriv]
 int 13h
 pop ds
 jc load
 
 
 loadl:
 mov ax,0x1000
 mov es,ax
 mov bx, 0
 mov ah, 2
 mov al, 5
 mov cx, 2
 mov dx, 0
 int 13h
 jc loadl
 mov si,loadmsg
 call putstr
 retn
 
 
 times 512-($-$$)-2 db 0
 dw 0AA55h
```
 

 kernel1.asm (kompiliert kernel1.bin - lädt den protect mode etc.)

```
[BITS 16]
 jmp start
 		
 NULL_Desc:
 dd 0
 dd 0
 		
 CODE_Desc:
 dw 0xFFFF
 dw 0
 db 0
 db 10011010b
 db 11001111b
 db 0
 		
 
 DATA_Desc:
 dw 0xFFFF
 dw 0
 db 0
 db 0x92
 db 0xCF
 db 0
 
 gdt:
 Limit		dw		0
 Base		dd		0
 
 
 start:									    
 		
 cli
 
 mov eax, cs
 mov ds, ax
 				
 shl eax, 4
 
 mov [CODE_Desc+2], ax
 mov [DATA_Desc+2], ax
 shr eax, 16
 mov [CODE_Desc+4], al
 mov [DATA_Desc+4], al
 
 mov eax, cs
 shl eax, 4
 add eax, NULL_Desc
 
 mov [Base], eax
 mov [Limit], WORD gdt - NULL_Desc -1
 
 lgdt		[gdt]
 
 mov eax, cr0
 or eax, 1
 mov cr0, eax
 		
 db 0xea
 dw PMODE
 dw 0x8
 		
 
 [BITS 32]
 
 PMODE:
 mov WORD [CODE_Desc+2], 0
 mov WORD [DATA_Desc+2], 0
 mov BYTE [CODE_Desc+4], 0
 mov BYTE [DATA_Desc+4], 0
 		
 mov eax, 2
 shl eax, 3
 		
 mov ds, ax
 mov ss, ax
 mov es, ax
 mov eax, 0
 mov fs, ax
 mov gs, ax
 mov esp, 0x1FFFFF
 		
 jmp 0x8:0x10000 + PMODE2
 					    
 PMODE2:		
 jmp END
 		
 times 512-($-$$) db 0;
 
 
 END:
```
 

 kernel2.asm (kompiliert kernel2.bin - kann nicht kompiliert werden wegen einem fehler: "binary output format dosnt support external references - normal verantwortlich für den C-Teil zu laden")

```
[Bits 32]
 extern _main
 global start
 start:
 call _main
 stop:
 jmp stop
```
 

 kernel_main.c (kompiliert kernel_main.obj - der eigendliche Kernel)

```
int main()
 {
 
   char *Text = "Welcome to Protected Mode";
   char *VideoMem = (char*)0xA8000;
 
   while(*Text)
   {
 
 	*VideoMem = *Text;
 	*VideoMem++;
 	*VideoMem = 7;
 	*VideoMem++;
 	*Text++;
 
   }
 
 return(0);
 
 }
```
 

 Kann mir jemand sagen warum ich diese kernel2.asm nicht kompilieren kann? 

 Danke schonmal,
 IndY


----------



## {red}ASM (7. April 2005)

Hi,
 die Fehlermeldung sagt doch alles oder? Es dürfen keine externen Routinen verwendet werden -Fertig.
 Kannst es ja anstatt "extern _main" mal mit "extrn _main" versuchen. Ich glaube nämlich, dass das so heißt.
 Gruß red!


----------



## stephsto (7. April 2005)

servus,

du hast einen kleinen fehler bei der Compilierung. Du darfst aus deinem Assembler-Teil in dem ja externe Funktionen vorkommen nicht gleich einen Binärfile machen. Erst eine Objektdatei aus dem 32bit Kernel dann eine Objektdatei aus dem C-File und beide zusammen linkst du dann zu deiner Binärdatei, die du hinter die erste kopieren kannst.

Gruß stephsto


----------



## indylein (8. April 2005)

So kompilieren hat anstatt mit bin mit elf geklappt 

 So jetz gibts ein Problem:
 WIe krieg ich das hin, dass der Bootloader den Kernel lädt?
 Wenn ich das Image jetz in Bochs (VirtualPC programm) lade, kommt der ladetext des Bootloaders und der PC restartet dann immer ganz schnell...
 Was kann ich da jetz machen?

 Sources:

http://devel.indy-web.org/blueberry/boot.asm (Bootloader)
http://devel.indy-web.org/blueberry/kernel1.asm (Kernelteil 1)
http://devel.indy-web.org/blueberry/kernel2.asm (Kernelteil 2)
http://devel.indy-web.org/blueberry/kernel_main.c (Hauptkernel - C)


 Wie gesagt, das ganze is aus Tutorials zusammengebastelt


----------



## stephsto (8. April 2005)

Also das es aus Tutorials zusammengebastelt ist habe ich mir fast gedacht. Mir kam dert code so bekannt vor...;-)

Naja, also leider kann ich dir folgendes nicht bestätigen aber ich glaube das stimmt. Bei mir war es ähnlich...

Also, du lädst den Kernel an die Adresse 10000. Das sagst du aber deinem Assembler beim Kompilieren des Kernels nicht. Versuch mal die folgende Zeile an den Anfang der Kernel1 datei zu hängen. Gib zusätzlich noch an bestimmten stellen einen weiteren String aus. Dann weißt du genau wann er restartet. Ich glaube nämlich eher das es mit dem FAR Jump in den Protected Mode zusammenhängt und da bin ich leider auch noch feste dran zu lernen.

org 0x1000

Das könnte es aber sein. Grund dafür ist einfach, dass die Adressen ja angepasst werden müssen, sonst hätte dein erster Befehl die Adresse 0x0 und da liegt ja bekanntlich das BIOS.....

Gruß stephsto


----------

