Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: noob 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
-
äähm schreibt man [ORG 0x7C00] schon immer in eckigen klammern? ich bin zwar selber total-noob aba laut ausgabe 1 sieht das anders aus....
-
nein, das ist nicht der Fehler org kann man auch in eckigen Klammern schreiben
-
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
-
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!! :-(
-
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
-
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!
-
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.
-
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...
-
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
-
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
-
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.
-
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.
-
ok hab nun gesplittet und es funkt!!!! danke!!
-
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
-
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!!!
-
jmp start
KERNEL_SIZE equ 70
KERNEL_SEGMENT equ 0x1000
KERNEL_START equ 1
start:
hehehe *g*
-
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
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 -.-
-
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...
-
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
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
-
@scales of justice koenntest du mir bidde bidde mal deinen asm code schicken damit ich mir das mal angucken kann??? meine mail add: badhazelnoot at gmail dot com
-
hi!
hab nun den code etwas abgeaendert... nun kommt vom bochs her kein fehler mehr auch die aufloesung der logischen sektor nummer musste nun 100% funktionieren nur mit dem hineinspringen in den kernel hats noch was dass funkt nicht bochs bleibt einfach stehen...
der code
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
CLI
XOR ax, ax
MOV ss, ax
MOV sp, 0x7c00
MOV ds, ax
STI
MOV ax, KERNEL_SEGMENT
MOV es, ax
XOR bx, bx
MOV cx, KERNEL_SIZE
MOV [LOOPS_1], cx
MOV ax, 1 ;start at sector2
MOV [LOGICAL], ax
MOV [SECTORZ], ax
main_loop:
MOV [LOOPS_1], cx ;take the loopvar to the logical sector number
MOV ax, [LOGICAL] ;Cylinder
MOV bx, 36
MOV dx, 0
DIV bx
MOV [CYLINDER], ax
MOV dx, 18 ;set TRACK 0 if TRACK is 18 is null
CMP dx, [SECTORZ]
JE set_null
fail:
;read the sector
MOV ax, KERNEL_SEGMENT
ADD bx, 512
MOV ah, 2
MOV al, 1
MOV ch, [CYLINDER]
MOV cl, [SECTORZ]
MOV dx, 0
INT 0x13
JC fail
MOV cx, [LOOPS_1]
MOV al, 1
ADD [LOGICAL], al
ADD [SECTORZ], al
LOOP main_loop;
JMP KERNEL_SEGMENT:0x0000
set_null
MOV ah, 0x0e
MOV al, '.'
MOV bx, 0x0004
INT 0x10
MOV dx, 1
MOV [SECTORZ], dx
JMP fail
aber warum springt er mir nicht in den kernel? ps head wird bei meinem os sowieso nie auf 1 kommen...(da sonst kein platz mehr fuer mein fs waere!!!)
ps: waenn ich mir bochsout.txt ansehe dann kommt sicher einige hundertmale:
00010167905e[CPU0 ] CALL_Ad: offset outside of CS limits
an dem wirds wohl liegen... aber wie krieg ich das raus?
-
hi! ich habs nun so hingebracht dass mir der bochs keine einzige fehlermeldung mer wirft!
das eine problem is nur dass nichts ausgefuehrt wird...(der fehler war der dass bei mir der offset gleich bei 512 angefangen hat dass hab ich nun geaendert nun gibt es eben keine fehler mehr aber booten tut die kacke auch noch immer nich :-((()
[BITS 16]
[ORG 0x7C00]
KERNEL_SIZE equ 76
KERNEL_SEGMENT equ 0x1000
KERNEL_START equ 1
%define LOOPS_1 bp-2
%define CYLINDER bp-4
%define offs bp-6
%define SECTORZ bp-8
%define LOGICAL bp-10
%define seg bp-12
SUB sp, 12
CLI
XOR ax, ax
MOV ss, ax
MOV sp, 0x7C00
MOV ds, ax
STI
MOV ax, KERNEL_SEGMENT
MOV es, ax
MOV [seg], ax
MOV bx, 0
MOV [offs], bx
MOV cx, KERNEL_SIZE
MOV [LOOPS_1], cx
MOV ax, 1 ;start at sector2
MOV [LOGICAL], ax
MOV [SECTORZ], ax
main_loop:
MOV [LOOPS_1], cx ;take the loopvar to the logical sector number
MOV ax, [LOGICAL] ;Cylinder
MOV bx, 36
MOV dx, 0
DIV bx
MOV [CYLINDER], ax
MOV dx, 18 ;set TRACK 0 if TRACK is 18 is null
CMP dx, [SECTORZ]
JE set_null
fail:
;read the sector
MOV ax, [seg] ;<--- hier addiere ich nun immer 32 dazu!!(waenn ich das nicht tue veraendert sich auch nichts)
MOV bx, [offs] ;<--- hier war der fehler
MOV ah, 2
MOV al, 1
MOV ch, [CYLINDER]
MOV cl, [SECTORZ]
MOV dx, 0
INT 0x13
JC fail
MOV cx, [LOOPS_1]
MOV al, 1
ADD [LOGICAL], al
ADD [SECTORZ], al
MOV al, 32
;ADD [seg], al
MOV ax, 512
ADD [offs], al
LOOP main_loop;
JMP KERNEL_SEGMENT:0x0000
set_null
mov ah, 0x0e
mov al, '.'
mov bx, 0x0004
int 0x10
MOV dx, 1
MOV [SECTORZ], dx
JMP fail