Autor Thema: BOCHS bootet mein os der PC aber nicht :-(  (Gelesen 13315 mal)

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« am: 27. March 2006, 18:26 »
hi!

jetzt hab ich ein ganz stranges problem! ich verwende folgenden bootloader:
http://hazelnoot.ha.funpic.de/RAILEX/sources/boot.asm

und mein kernel ist 18385 Bytes gros!

mit diskCopy.c(http://hazelnoot.ha.funpic.de/diskCopy.c) kopiere ich diesen auf die diskette hab ihn mit(nasm boot.asm -o boot -f bin) assembliert! und mit diskCopy_os(http://hazelnoot.ha.funpic.de/diskCopy_os.c) kopiere ich den kernel auf die disk! soweit so gut! starte ich bochs bootet er mir dies ohne probleme boote ich aber den pc mit eingelegter diskette funkt es nicht es wirft mir dann die fehlermessage d.h das carryflag ist nicht so wie es sollte!! das komische ist nur das ganze ging von heut auf morgen ich hab es schon paar mal gebootet mit dem pc dann hab ich einige aenderungen am kernel vorgenommen nun funkts nicht mehr!! :-((( woran kann das liegen!!!!! kompilieren tu ich mit dem compiler von [MM]!!

thx

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 27. March 2006, 20:07 »
äähm schreibt man [ORG 0x7C00] schon immer in eckigen klammern? ich bin zwar selber total-noob aba laut ausgabe 1 sieht das anders aus....

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 27. March 2006, 20:12 »
nein, das ist nicht der Fehler org kann man auch in eckigen Klammern schreiben

maumo

  • Beiträge: 182
    • Profil anzeigen
    • http://maumo.50webs.com/
Gespeichert
« Antwort #3 am: 28. March 2006, 16:04 »
also vielleicht solltest du die segment register beim start auf das von cs setzen. und dann kannste das Print succmsg weglassen. ausserdem fehlt die bootsignatur, oder?

maumo

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 28. March 2006, 20:44 »
hi danke fuer die antwort die bootsignatur fuegt das programm diskcopy hinzu!
ich hab den bootsector mal so abgeaendert:


MOV ax, 200h + KERNEL_SIZE
PUSH word KERNEL_SEGMENT
POP cs ;es <--- aenderung
XOR bx, bx
MOV cx, KERNEL_START + 1
MOV dx, 0
INT 13h
JNC ok
Print failmsg
JMP $
ok:
Print bootmsg2

leider kummt nun auch beim grub gleich die fehlermessage!! :-(

maumo

  • Beiträge: 182
    • Profil anzeigen
    • http://maumo.50webs.com/
Gespeichert
« Antwort #5 am: 29. March 2006, 14:17 »
ich meinte sowas:

...

start:
mov ax, cs  ; segment register für die nachrichten usw setzen
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x9000 ; stack für den int einrichten
mov ss, ax
mov sp, 0xff

...


POP cs ;es <--- aenderung

 zurück ändern!!! du willst ja das der kernel
 dahin geladen wird, also ES;
 CS gibt an wo du dich gerade befindest!

maumo

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 23. April 2006, 18:33 »
hi!
danke erstmal fuer eure antworten aber ich blick langsam nicht mehr durch :-( mein bootloader sieht nun so aus:


[BITS 16]    ;16 bit mode
[ORG 0x7C00] ;place for the bootloader

jmp start

KERNEL_START equ 1    ; Disk block where kernel starts
KERNEL_SIZE equ 35    ; Kernel size in disk blocks
KERNEL_SEGMENT equ 1000h ; Segment where kernel will be loaded

;
; The print funktion
;

Print_m:
Print_p:
lodsb ; next sign

INT 10h
CMP al,0
JNE Print_p

RET

%macro Print 1

MOV si,%1

XOR ax,ax

MOV ah,0Eh ; tell the int we want print
MOV bx,0F00h ; color from 0000h(black) to 0F00h(white)

CALL Print_m

%endmacro


;
; Load kernel
;

bootmsg db "BOOTING THE RAILEX KERNEL!", 0
bootmsg2 db "boot...", 0
failmsg db "failed", 0
succmsg db "succeed", 0

start:

mov ax, cs  ; segment register für die nachrichten usw setzen
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x9000
mov ss, ax
mov sp, 0xff

Print bootmsg

PUSH word KERNEL_SEGMENT
POP es
XOR bx, bx
MOV cx, KERNEL_START + 1
MOV dx, 0
INT 13h
JNC ok
Print failmsg
JMP $
ok:
Print bootmsg2
;
; Jump to kernel
;
jmp KERNEL_SEGMENT:0

Print succmsg


alles was ich von diesem code will ist dass er mir eine  21393 Bytes grosse bin laedt den rest macht diese dann... BITTE BITTE aendert mir diesen code so ab dass dies funkt oder sagt mir was ich falsch mache... DANKE!

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 23. April 2006, 19:31 »
sag du erst was das problem ist.

mal ein bisschen was, das ich beim überfliegen sehe:

mov ax, cs  ; segment register für die nachrichten usw setzen
ist so nicht korrekt. das org 0x7c00 impliziert, dass die datensegmentregister auf 0 gesetzt werden müssen. also xor ax, ax

MOV bx,0F00h ; color from 0000h(black) to 0F00h(white)
du setzt nicht die farbe auf weiss (0fh) sondern die bildschirmseite auf 00h. es muss 000fh heissen. (siehe interrupt 10h, funktion 0eh)

ausserdem gibst du keine funktionsnummer für int 13h an. ich denke mal du willst einen sektor auslesen. das geht mit funktion 02h.

ist alles nicht getestet, aber ich hoffe du kannst damit was anfangen.
Dieser Text wird unter jedem Beitrag angezeigt.

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 23. April 2006, 20:12 »
hi danke fuer deine antwort!!

hab nun das mit der funktionsnummer hinzugefuegt:
MOV ax, 200h + KERNEL_SIZE


; THIS IS THE RAILEX OS BOOTLOADER
;
; AUTHOR: Rainer Sickinger
; LICENCE: GNU GPL
; COPYRIGHT: Rainer Sickinger
;            Alexander Zahrer
;

[BITS 16]    ;16 bit mode
[ORG 0x7C00] ;place for the bootloader

jmp start

KERNEL_START equ 1    ; Disk block where kernel starts
KERNEL_SIZE equ 35    ; Kernel size in disk blocks
KERNEL_SEGMENT equ 1000h ; Segment where kernel will be loaded

;
; The print funktion
;

Print_m:
Print_p:
lodsb ; next sign

INT 10h
CMP al,0
JNE Print_p

RET

%macro Print 1

MOV si,%1

XOR ax,ax

MOV ah,0Eh ; tell the int we want print
MOV bx,0F00h ; color from 0000h(black) to 0F00h(white)

CALL Print_m

%endmacro


;
; Load kernel
;

bootmsg db "BOOTING THE RAILEX KERNEL!", 0
bootmsg2 db "boot...", 0
failmsg db "failed", 0
succmsg db "succeed", 0

start:

mov ax, cs  ; segment register für die nachrichten usw setzen
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x9000
mov ss, ax
mov sp, 0xff

Print bootmsg

MOV ax, 200h + KERNEL_SIZE
PUSH word KERNEL_SEGMENT
POP es
XOR bx, bx
MOV cx, KERNEL_START + 1
MOV dx, 0
INT 13h

JNC ok
Print failmsg
JMP $
ok:
Print bootmsg2
;
; Jump to kernel
;
jmp KERNEL_SEGMENT:0

Print succmsg


waenn ich dann den code ausfuehre gibt mir bochs folgendes aus:
Device: [CPU0]
Message: prefetch: RIP > CS.limit


hat von euch noch niemand code geschrieben der anderen code laedt? vl koennt ihr mir den zeigen... danke!

ps waenn ich ax auf 0 setze mit xor ax, ax dann werden irgendwie in ner endloschschleife lehrzeichen ausgegeben...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 24. April 2006, 12:15 »
KERNEL_SIZE ist zu klein.

so müsste es gehen:
org 0x7c00

KERNEL_SIZE equ 50
KERNEL_SEGMENT equ 0x1000
KERNEL_START equ 1

start:
mov ax, KERNEL_SEGMENT
mov es, ax
xor bx, bx

mov ax, 0x0200 + KERNEL_SIZE
mov dh, 0x00
mov cx, 0x0001 + KERNEL_START
int 0x13
jc error

jmp KERNEL_SEGMENT:0x0000

error:
mov ah, 0x0e
mov al, 'R'
mov bx, 0x0004
int 0x10
jmp $

times 510+$$-$ db 0
dw 0xaa55
Dieser Text wird unter jedem Beitrag angezeigt.

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 24. April 2006, 18:35 »
hi!

danke hab deinen code probiert!! leider funkt es wieder nicht :-(( er gibt mir das R(pc und bochs machen das selbe!!) aus das heisst das mit dem interrupt was nicht stimmt oder? mein kernel ist 38551 Bytes gross daher hab ich nun in KERNEL_SIZE 76 eingestellt(da 38551/512 == ~75.294) kann es sein dass man das mit dem interrupt 13 anders machen soll? ich bin schoen langsam am verzweifeln...

ps waenn ich das jc error auskommentiere kommt wieder der error:  Device: [CPU0]
Message: prefetch: RIP > CS.limit

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 24. April 2006, 19:50 »
ich hab mal ein wenig herumprobiert und ich denke man kann einfach nicht mehr als 50 sektoren am stück laden. warum auch immer. ich hab wohl zufällig die obergrenze erwischt.

du musst also das auslesen auf mehrere aufrufe von int 13h aufsplitten.
Dieser Text wird unter jedem Beitrag angezeigt.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #12 am: 24. April 2006, 20:09 »
Zitat von: PorkChicken
ich hab mal ein wenig herumprobiert und ich denke man kann einfach nicht mehr als 50 sektoren am stück laden. warum auch immer. ich hab wohl zufällig die obergrenze erwischt.

du musst also das auslesen auf mehrere aufrufe von int 13h aufsplitten.
Wie gesagt, ich lade immer nur ein Sektor pro int 13h, und das ist so gut wie genau so schnell.
In the Future everyone will need OS-64!!!

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 24. April 2006, 20:34 »
ok hab nun gesplittet und es funkt!!!! danke!!

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 24. April 2006, 22:06 »
jetzt merk ich, dass ich genau den gleichen Fehler auch erst gemacht hab,
aber ich frage mich echt warum es da eine Grenze gibt

dass man nicht über Zylinder Grenzen lesen kann wär ja noch verständlich,
aber da scheint die Grenze nicht zu sein

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 25. April 2006, 12:04 »
hi!

ich hab nun folgenden code:

org 0x7c00

jmp start

KERNEL_SIZE equ 70
KERNEL_SEGMENT equ 0x1000
KERNEL_START equ 1

start:

; STAGE1
stage1:
   MOV ax, 0x1000    ; ES:BX = 1000:0
   MOV es, ax
   MOV bx, 0

   MOV ah, 2
   MOV al, 35        ; sectors to read
   MOV cx, 2         ; cylinder=0, sector=2
   MOV dx, 0         ; head=0, disk=0
   INT 0x13          ; operate the interrupt
   JC  stage1        ; on error try again

;STAGE 2
stage2:  
   ADD   bx, 512*35

   MOV ah, 2
   MOV al, 70       ;70
   MOV cl, 1        ;1
   MOV ch, 1        ;1
   MOV dx, 0
   INT 0x13
   JC  stage2

; STAGE 3
stage3:  
   ADD   bx, 512*70

   MOV   ah, 2
   MOV   al, 10     ;10
   MOV   cl, 2
   MOV   ch, 1
   MOV   dx, 0
   INT   0x13
   JC   stage3  

   jmp KERNEL_SEGMENT:0x0000



dann funkts aender ich das MOV   al, 10     ;10 auf MOV   al, 70     ;10 dann gehts nicht mehr kann mir mal jemand sagen wie ich das am bestem mache waenn ich pro stage 18 sectoren auslese (da pro head ja 18 sectoren) funkts auch nicht koennt ihr mir eventl sagen wie viel ich pro stage immer auslesen sollte?

DANKE!!!

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #16 am: 25. April 2006, 14:46 »
jmp start

KERNEL_SIZE equ 70
KERNEL_SEGMENT equ 0x1000
KERNEL_START equ 1

start:


hehehe *g*
In the Future everyone will need OS-64!!!

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 25. April 2006, 17:32 »
Zitat
koennt ihr mir eventl sagen wie viel ich pro stage immer auslesen sollte


les einfach in jedem Schritt (wenn du das mit Stage meinst) ein Sektor aus, dann gibts keine Probleme
und langsamer wirds auch nicht wirklich

Zitat
jmp start

KERNEL_SIZE equ 70
KERNEL_SEGMENT equ 0x1000
KERNEL_START equ 1

start:



hehehe *g*


hab ich früher auch immer so gemacht -.-

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 26. April 2006, 11:32 »
hi!

hab nun folgenden code geschrieben:


org 0x7c00

KERNEL_SIZE equ 76
KERNEL_SEGMENT equ 0x1000
KERNEL_START equ 1


%define LOOPS_1    bp-2
%define CYLINDER bp-4
%define HEADS   bp-6
%define SECTORZ   bp-8
%define LOGICAL bp-10
%define BUFFER      bp-12

SUB sp, 12

MOV cx, KERNEL_SIZE
MOV [LOOPS_1], cx

MOV al, 1
CLI
MOV ax, 0x9000
MOV ss, ax
MOV sp, sp
STI

MOV ax, KERNEL_SEGMENT
MOV es, ax
XOR bx, bx

main_loop:
    MOV [LOOPS_1], cx       ;take the loopvar to the logical sector number

    MOV [LOGICAL], al
    CALL logical_to_chs     ;convert the LSN to CHS

fail:
    ;read the sector
    ADD bx, 512
    MOV ah, 2
    MOV al, 1
    MOV cl, [SECTORZ]
    MOV ch, [CYLINDER]
    MOV dh, [HEADS]
    MOV dl, 0
    INT 0x13
    JC  fail
   
    MOV cx, [LOOPS_1]
    MOV al, 1  
    ADD [LOGICAL], al

    LOOP main_loop;

JMP KERNEL_SEGMENT:0x0000

logical_to_chs:
MOV ax, [LOGICAL] ;Cylinder
MOV bx, 36
MOV dx, 0
DIV bx
MOV [CYLINDER], ax

MOV ax, dx ;Head
PUSH ax
MOV bx, 18
MOV dx, 0
DIV bx
MOV [HEADS], ax

POP ax  ;Sektor
MOV dx, 0
DIV bx
MOV ax, dx
ADD ax, 1

MOV [SECTORZ], ax
RET


leider kommt auch hier wieder die meldung

Device: [CPU0]
Message: prefetch: RIP > CS.limit


ich hab euren rat befolgt immer nur einen sektor einzulesen aber BITTE BITTE bessert meinen code aus... DANKE waenn das funkt bin ich so froh sach ich euch...

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 26. April 2006, 13:23 »
hm... ich erzähl dir einfach mal was beimir die Probleme waren:

MOV ax, 0x9000
MOV ss, ax
MOV sp, sp


erstmal solltest du das Stacksegment nicht an 0x9000 machen,
ich weis nicht warum, aber mein altes A.M.I. Bios wollte das nicht
ich hab dann 0x0000 genommen und den Stackpointer auf 0x7c00 gesetzt
das hat problemlos funktioniert

was du mit mov sp, sp bezwecken willst versteh ich nicht,
auch solltest du sp nicht auf 0 setzen, auch wenn du beim Segment Ende anfangen willst
das mochte mein A.M.I. Bios auch nicht
(das erledigt sich dann auch mit dem oben beschriebenen)


wo initalisierst du eigentlich DS?
muss man zwar glaub ich nicht, machs aber mal besser
kannste einfach bei der Stack initalisierung mit reinmachen


also im Endeffekt würde ich das so machen:

XOR ax, ax
MOV ss, ax
MOV sp, 0x7c00
MOV ds, ax


bei mir steht zur Sicherheit auch ES mit drin,
aber das kann man sich denke ich echt sparen
FS und GS muss man aufjedenfall nicht,
die gibt es bei älteren Prozessoren nicht


Zitat
prefetch: RIP > CS.limit


das bedeutet meistens, dass er an eine falsche Adresse gesprungen ist,
dort ist noch alles voller 0en,
wodurch der Code dann durchläuft bis das Limit von CS erreicht ist
und das ganze nicht mehr weiterlaufen kann, ohne ins nächste Segment zu spingen

 

Einloggen