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