Archiv verlassen und diese Seite im Standarddesign anzeigen : CS Limit
hi leute
ich hab ein programm geschrieben, dass direkt beim booten gestartet wird..
den oot loader hatte ich vor langer zeit schon aus`m netz der funktioniert einandfrei
allerdings habe ich seit einiger zeit (evtl. ist es zu gross?? => ist mit bootloader zusammen im bin format ca. 37,6 kb gross) das problem, dass das prog. einfach hängen bleiebt
habe es mal mit dem "bochs" simulater gebootet und der sagt :" CS Limit "
liegt das an der programmgrösse??
und vor allem wie löse ich das problem???
soweit ich weis kann doch ein einzelnes segmant bis zu 64 kb gross sein...
und das CS steht ja wohl im ASM für CodeSegment..
vielen dank schon mal im vorraus...
Felix Kaiser
04.04.2005, 16:17
Müsstest du jetzt mal deinen Bootlader beschreiben. Was macht der genau? Hast du das gesamte Image an Sektor 1 beginnend abgelegt oder liegt dort nur der Bootlader und der Rest in einem Dateisystem? Lädt der Bootlader das gesamte Image? Oder lädt er nur den ersten Block, z.B. den ersten Sektor, das erste Cluster oder was auch immer?
also hier ist mal der boot loader so wie ich ihn ausm netz habe..
und ehrlich gesagt weiss ich nicht genau was er tut, desshalb kann ich auch nur vermuten dass es an ihm liegt... bin mir aber nicht sicher
also bis jetzt hab ich es immer so gemacht, dass ich ben boot loader und mein prog im .bin format assembliert, und dann beide dateien einfach zusammen gefügt und mit rawwrite auf eine diskette geschrieben habe, bzw. es mit bochs simuliert habe.
ging auch immer einwandfrei bis irgendwann das programm immer größer wurde und das dieser fehler auftauchte..
vieleicht könnte mir auch mal jemand den boot loader erklären, oder noch besser ein par gute tutorials über boot loader empfehlen
hier der quellcode :
org 0x7C00
start:
cli ; Keine Interrupts verwenden!
mov ax, 0x1000 ; Adresse des Stack speichern
mov ss, ax ; Stackadresse festlegen
mov sp, 0 ; Stackpointer auf 0 setzen
sti ; Jetzt lassen wir wieder Interrupts zu
mov [bootdriv], dl
call load
mov ax, 0x1000 ; 0x1000 ist die Speicheradresse unserer Shell
mov es, ax
mov ds, ax
push ax
mov ax, 0
push ax
retf
bootdriv db 0 ; Das Bootlaufwerk
loadmsg db "Lade GHOSTS-alpha-HAMMER..",13,10,0
; Mit dieser Funktion geben wir einen String aus
putstr:
lodsb
or al,al
jz short putstrd
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp putstr
putstrd:
retn
; Mit dieser Funktion laden wir unsere Shell vom Bootlaufwerk
load:
push ds
mov ax, 0
mov dl, [bootdriv]
int 13h
pop ds
jc load
load1:
mov ax,0x1000
mov es,ax
mov bx, 0
mov ah, 2
mov al, 5
mov cx, 2
mov dx, 0
int 13h
jc load1
mov si,loadmsg
call putstr
retn
times 512-($-$$)-2 db 0
dw 0AA55h
Hi,
ein spezielles Tutorial über Bootloader kenn ich jetzt nicht. Aber ein paar gute Anlaufstellen sind:
http://lowlevel.brainsware.org (deutsch!)
http://www.osdever.net
http://www.mega-tokyo.com/osfaq2
ich hab mal die wichtigsten stellen kommentiert (mit ;;;;;)
org 0x7C00
start:
cli ; Keine Interrupts verwenden!
mov ax, 0x1000 ; Adresse des Stack speichern
mov ss, ax ; Stackadresse festlegen
mov sp, 0 ; Stackpointer auf 0 setzen
sti ; Jetzt lassen wir wieder Interrupts zu
;;;;; in bootdriv speichern von welchem laufwerk wir gebootet haben (0 = floppy 1 (= A:), 1 = floppy 2 (= B:), 0x80 = hard disk 1 (= C:), 0x81 = hard disk 2 (= D:, ...)
mov [bootdriv], dl
call load
mov ax, 0x1000 ; 0x1000 ist die Speicheradresse unserer Shell
mov es, ax
mov ds, ax
;;;;; diese zeilen sind blödsinn, ich weiss nicht warum manche leute glauben es so schreiben zu müssen
;;;;; das ist das gleiche wie ein sprung nach segment 0x1000, offset 0
;;;;;push ax
;;;;;mov ax, 0
;;;;;push ax
;;;;;retf
;;;;; das hier ist besser:
jmp 0x1000:0x0000
bootdriv db 0 ; Das Bootlaufwerk
loadmsg db "Lade GHOSTS-alpha-HAMMER..",13,10,0
; Mit dieser Funktion geben wir einen String aus
putstr:
lodsb
or al,al
jz short putstrd
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp putstr
putstrd:
retn
; Mit dieser Funktion laden wir unsere Shell vom Bootlaufwerk
load:
push ds
mov ax, 0 ;;;;; int 0x13, funktion 0x00, laufwerk resetten (damit es bereit ist benutzt zu werden)
mov dl, [bootdriv]
int 13h
pop ds
jc load
load1:
mov ax,0x1000
mov es,ax
mov bx, 0
mov ah, 2 ;;;;; int 0x13, funktion 0x02 - "read sector(s) into memory"
mov al, 5 ;;;;; anzahl der zu lesenden sektoren
mov cx, 2
mov dx, 0
int 13h ; lesen
jc load1 ;;;;; wenn das carry flag gesetzt ist, ist ein fehler aufgetreten -> nochmal lesen
mov si,loadmsg
call putstr
retn
times 512-($-$$)-2 db 0
dw 0AA55h
die genaue funktion des interrupts 13 (http://www.ctyme.com/intr/int-13.htm) gibt es in ralf browns interrupt list (http://www.ctyme.com/rbrown.htm)
also zu dem problem: in dem code werden nur 5 sektoren gelesen (mov al, 5), dass sind 5 * 512Byte, also 2,5 KByte. Wahrscheinlich ist dein Kernel größer und wird deswegen nicht vollständig in den speicher geladen. der prozessor führt dann lustig irgendwelchen code (der wahrscheinlich garkeiner ist) irgendwo im speicher aus, bis er am ende angekommen ist, und sagt dann "CS > Limit" ...
Also musst du mehr Sektoren von der Diskette lesen. Die Sektorzahl kannst du wahrscheinlich noch bis 18 erhöhen. Das erlaubt dir einen Kernel bis 9 KByte größe zu nutzen. Darüber wirds kompliziert, weil dann Spurgrenzen auf der Diskette überschritten werden. Nicht jedes BIOS kann gut damit umgehen. Deswegen solltest du dann einen anderen Bootloader verwenden, der garantiert mehr Sektoren lesen kann. Vielleicht gibt es bei den Links einen, sonst nutz z.B.diesen (http://www.softgames.de/forum/viewtopic.php?t=111326#621810) , den ich nicht selbst geschrieben hab. (Der funktioniert genauso wie deiner, also lädt auch einfach ein paar sektoren hinter dem bootsektor an die adresse 0x1000:0x0000, springt dann aber in den protected mode, was du dann entfernen müsstest, wenn du ein realmode os schreibst. das was der PorkChicken da wegen dem FAT12 verzapft stimmt nicht so ganz, vergiss es einfach)
ich schreib hier viel blabla, aber die kurzfristige lösung sollte sein, das mov al, 5 in mov al, 18 zu ändern.
:D
oh man ihr seid einfach alle spitze
VIELEN DANK AN EUCH!!!!!!!!!!!!
also ich hab mir mal noch ein,zwei sachen angesehen und etwas gelesen...
also ich hab jetzt einfach mal mehrere read vorgänge hinter einander gestellet und dabei immer den offset erhöht, so oft, dass ich etwas mehr von der diskette in den speicher gelesen habe als mein prog gross ist....
aber ohne eure hilfe (speziellen dank an JIDDER) wäre ich nicht so schnell (wahrscheinlich nie) darauf gekommen...
naja ich denke jetzt gehts erstmal weiter...
also dann bis zum nächsten problem ;)
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.