Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: berlinermauer am 03. May 2009, 00:20
-
Hallo Leute,
Wenn ich Bochs benutze, dann kommt da entweder dauernd
read_virtual_word_32(): segment limit violation
oder dass er das BootMedium nicht gefunden hat.
VMWare zeigt auch nur noch nen schwarzen bildschirm statt ein bisschen text.
Egal ob ich versuche den ProtMode reinzuhauen oder nicht...
http://uploaded.to/file/zrj4vl
Edit:
Mit dieser Config gehts :
http://lowlevel.brainsware.org/wiki/index.php/Eigener_Boot_Record
trotzdem seh ich nur nen Schwarzen bildschirm?!
lst :
1 ; Compile with nasm -o boot.bin -f bin boot.asm
2 org 0x7C00
3
4 start:
5 00000000 FA cli ; Keine Interrupts verwenden!
6 00000001 B80090 mov ax, 0x9000 ; Adresse des Stack speichern
7 00000004 8ED0 mov ss, ax ; Stackadresse festlegen
8 00000006 BC0000 mov sp, 0 ; Stackpointer auf 0 setzen
9 00000009 FB sti ; Jetzt lassen wir wieder Interrupts zu
10
11 0000000A 8816[0101] mov [bootdriv], dl
12
13 ; Include Works
14 %include "lang.asm"
15 <1> ; Compile with nasm -o boot.bin -f bin boot.asm
16 <1>
17 <1> ;BOOT
18 0000000E 4C616465205475786D- <1> loadmsg db "Lade Tuxmaniac...",13,10,0 ;Loading up Tuxmaniac
19 00000017 616E6961632E2E2E0D- <1>
20 00000020 0A00 <1>
21 00000022 507265737320616E79- <1> reboot_message db "Press any key to reboot",13,10,0 ; System_PAKT_REBOOT
22 0000002B 206B657920746F2072- <1>
23 00000034 65626F6F740D0A00 <1>
24 0000003C 57656C636F6D652074- <1> welcome_message db "Welcome to Tuxmaniac...",13,10,0 ; WelcomeMessage
25 00000045 6F205475786D616E69- <1>
26 0000004E 61632E2E2E0D0A00 <1>
27 00000056 4D616465206279204D- <1> copyright_message db "Made by Berlinermauer... Have Fun :)",13,10,0 ; Dont change or DELETE!!
28 0000005F 617263205374726563- <1>
29 00000068 6B667573732E2E2E20- <1>
30 00000071 486176652046756E20- <1>
31 0000007A 3A290D0A00 <1>
32 0000007F 546869732053797374- <1> sys_goingdown_reboot db "This System is going down for a Reset NOW!",13,10,0 ; Warning/message that the system is about to shutdown
33 00000088 656D20697320676F69- <1>
34 00000091 6E6720646F776E2066- <1>
35 0000009A 6F7220612052657365- <1>
36 000000A3 74204E4F57210D0A00 <1>
37 %include "prot.asm"
38 <1> protmode_on:
39 <1> ;;; Ein kleines Beispiel, wie man in den 32-Bit Protected Mode wechselt
40 <1> ;;; Bei Fragen kann man sich einfach an die ICQ-Nummer 338-417-614 wenden.
41 <1>
42 <1> [BITS 16]
43 <1> ; org 0x0000 ; Addiert zu allen Offsetes die Start-Adresse dieses Codes
44 <1>
45 000000AC FA <1> cli ; Interrupts ausschalten
46 000000AD 0F0116[CC00] <1> lgdt [gdtr] ; GDT Pointer laden
47 <1>
48 000000B2 0F20C0 <1> mov eax,cr0 ; In PMode wechseln, indem das niedrigste
49 000000B5 0C01 <1> or al,1 ; Steuerungsbit von cr0 geändert wird
50 000000B7 0F22C0 <1> mov cr0,eax ; muss über Umweg über ein anderes Register gemacht werden
51 <1>
52 000000BA EA[BF00]0800 <1> jmp codesel:PMode ; FarJump zu einer 32-Bit PMode Funktion
53 <1>
54 <1> [BITS 32]
55 <1> PMode:
56 000000BF 66B81000 <1> mov ax,datasel ; Segmentregister laden
57 000000C3 8ED8 <1> mov ds,ax
58 000000C5 8ED0 <1> mov ss,ax
59 000000C7 BC00000900 <1> mov esp,0x90000 ; Stack aufsetzen
60 <1>
61 <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; == GDT == ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
63 <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
64 <1>
65 <1> gdtr: ; Desktiptortabelle
66 000000CC 1700 <1> dw gdt_end-gdt-1 ; Limit
67 000000CE [D2000000] <1> dd gdt ; Basisadresse
68 <1> gdt:
69 000000D2 0000000000000000 <1> dd 0,0 ; Null-Deskriptor
70 <1> codesel equ $-gdt
71 000000DA FFFF <1> dw 0xFFFF ; Segmentgrösse 0..15
72 000000DC 0000 <1> dw 0x0000 ; Segmentadresse 0..15
73 000000DE 00 <1> db 0x00 ; Segmentadresse 16..23
74 000000DF 9A <1> db 0x9A ; Zugriffsberechtigung und Typ
75 000000E0 CF <1> db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
76 000000E1 00 <1> db 0x00 ; Segmentadresse 24..31
77 <1> datasel equ $-gdt
78 000000E2 FFFF <1> dw 0xFFFF ; Segmentgrösse 0..15
79 000000E4 0000 <1> dw 0x0000 ; Segmentadresse 0..15
80 000000E6 00 <1> db 0x00 ; Segmentadresse 16..23
81 000000E7 92 <1> db 0x92 ; Zugriffsberechtigung und Typ
82 000000E8 CF <1> db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
83 000000E9 00 <1> db 0x00 ; Segmentadresse 24..31
84 <1> gdt_end:
85 000000EA C3 <1> retn
86
87 000000EB E825000000 call load
88 000000F0 66B80010 mov ax, 0x1000 ; 0x1000 ist die Speicheradresse unserer Shell
89 000000F4 8EC0 mov es, ax
90 000000F6 8ED8 mov ds, ax
91 000000F8 6650 push ax
92 000000FA 66B80000 mov ax, 0
93 000000FE 6650 push ax
94 00000100 CB retf
95
96 00000101 00 bootdriv db 0 ; Das Bootlaufwerk
97 ;loadmsg db "Lade Tuxmaniac...",13,10,0
98
99 ; Mit dieser Funktion geben wir einen String aus
100 putstr:
101 00000102 AC lodsb
102 00000103 08C0 or al,al
103 00000105 740D jz short putstrd
104 00000107 B40E mov ah,0x0E
105 00000109 66BB0700 mov bx,0x0007
106 0000010D CD10 int 0x10
107 0000010F E9EEFFFFFF jmp putstr
108 putstrd:
109 00000114 C3 retn
110
111 ; Mit dieser Funktion laden wir unsere Shell vom Bootlaufwerk
112 load:
113 00000115 1E push ds
114 00000116 66B80000 mov ax, 0
115 0000011A 8A15[01010000] mov dl, [bootdriv]
116 00000120 CD13 int 13h
117 00000122 1F pop ds
118 00000123 72F0 jc load
119
120 load1:
121 00000125 66B80010 mov ax,0x1000
122 00000129 8EC0 mov es,ax
123 0000012B 66BB0000 mov bx, 0
124 0000012F B402 mov ah, 2
125 00000131 B005 mov al, 5
126 00000133 66B90200 mov cx, 2
127 00000137 66BA0000 mov dx, 0
128 0000013B CD13 int 13h
129 0000013D 72E6 jc load1
130 0000013F 66BE[0E00] mov si,loadmsg
131 00000143 E8BAFFFFFF call putstr
132 00000148 E95FFFFFFF jmp protmode_on
133
134 ;Bis zu 512 Byte füllen
135 0000014D 00<rept> times 512-($-$$)-2 db 0
136 000001FE 55AA dw 0AA55h
137
oder kann es was hiermit : ROM: System BIOS must end at 0xfffff
zu tun haben?
-
nimm mal als bochs config file:
# small bochsrc.txt
# by muuh
### Hier den Pfad anpassen für dein disk-image
floppya: 1_44=C:\NASM\HelloWorld.img, status=inserted
####
romimage: file=$BXSHARE/BIOS-bochs-latest
cpu: count=1, ips=10000000, reset_on_triple_fault=1
megs: 32
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
vga: extension=vbe
boot: floppy
floppy_bootsig_check: disabled=0
log: bochsout.txt
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
debugger_log: -
parport1: enabled=1, file="parport.out"
vga_update_interval: 300000
keyboard_serial_delay: 250
keyboard_paste_delay: 100000
private_colormap: enabled=0
keyboard_mapping: enabled=0, map=
i440fxsupport: enabled=1
is eig genau deine war aber, wie ich woanders las, ein fehler drin ;)
-
An Bochs liegt es nicht. Du kannst die Includes nicht einfach mitten im Code platzieren.
-
Ok wohin dann?
ich habe die includes mal rausgelassen,
aber wie kann ich das machen, das dann in meinem Kernel/bootloader zB die lang.asm verfügbar ist?
Ohne Includes klappt es, das heißt ich muss die irgendwie anderst includen, ich hab es nunmal an den Anfang gepackt, da ich die Strings brauche.
noch was mein prot-mode code benötigt ein anderes origin (org),
wie bekomme ich das hin, ich kann das ja nicht mehr einfach ändern oder?
und kann ich die Adressen irgendwie umrechnen?!
-
Ok wohin dann?
Der Programmablauf in Assembler ist von oben nach unten. Da bekanntermaßen eine 1:1 Abbildung zwischen Assemblercode und Maschinencode besteht, und die CPU den Speicher (abzüglich Sprungbefehle) von vorne nach hinten ausführt, heißt das, dass diese versucht jedes Byte auf das sie trifft als Befehl zu interpretieren. Also kannst du nicht ohne weiteres Daten in den Code einfügen.
Eine gute Stelle wäre zum Beispiel vor dem "times 512..."
noch was mein prot-mode code benötigt ein anderes origin (org),
wie bekomme ich das hin, ich kann das ja nicht mehr einfach ändern oder?
Du kannst entweder Real Mode und Protected Mode Code in zwei verschiedenen Dateien (sowohl Quelltext als auch Binärdateien) legen, dann kannst du beiden unterschiedliche org-Anweisungen geben. Oder du organisierst deinen Code so, dass beide das selbe org benutzen können. Mit einem org 0x7c00 im Bootloader (sofern du da in den Protected Mode schaltest) sollte das gehen.
und kann ich die Adressen irgendwie umrechnen?!
Ja, zwischen den Adressierungsarten besteht die Beziehung
Lineare Adresse = Segment * 16 + Offset
Es ist häufig von Vorteil, sich so zu organisieren, dass das Segment 0 ist.
-
warum hinter times? da ist doch der boot vorgang schon rum, weil er füllt ja den rest oder?
2. Hab ich versucht, dann sagt NASM "origin redefined", als Fehler
3. Das wäre dann Adresse = -0x7C00 *16 + Irgendwas?
Kannst du mich mal im ICQ adden? 983-023
Ty
-
warum hinter times? da ist doch der boot vorgang schon rum, weil er füllt ja den rest oder?
Er sagte vor dem times.
-
ja sorry, da hab ich mich vertippt, aber trotzdem, davor ist ja schon "gebootet" es wird nur noch das "Erkennungssignal" eingegeben oder?
immer noch das problem dass ich nicht weiß wie ich dann mehr oder weniger -0x7C00 * 16 berechne
-
davor ist ja schon "gebootet" es wird nur noch das "Erkennungssignal" eingegeben oder?
Ich versteh kein Wort. Was verstehst du unter "gebootet" und von welchem "Erkennungssignal" redest du?
immer noch das problem dass ich nicht weiß wie ich dann mehr oder weniger -0x7C00 * 16 berechne
Wieso brauchst du die Adresse überhaupt? Die Protected-Mode adressen sollten m.E. stimmen. Du hast als Segmentadresse der Deskriptoren ja 0 gewählt und auf deine Labels wird 0x7C00 addiert, aber der Code liegt ja auch an 0x7C00, insofern sollte das doch passen.
-
naja weil der ProtMode rechnet ja ab 0x0000 los, aber ich ab 0x7C00
Und ich meinte mit dem ersten satz, dass er da ja nur noch die "BootSignatur" schreibt, und das davor schon rum ist.
aber egal, es "klappt" jetzt,
In Bochs seh ich den String kurz und das flackert dann immer.
Nun hab ich mal in VmWare geguckt, da steht kernel stack fault (Hardware reset),
was kann ich dagegen tun, und vorallem wo tritt er auf?
-
naja weil der ProtMode rechnet ja ab 0x0000 los, aber ich ab 0x7C00
Das org 0x7C00 sagt dem Assembler, dass er auf jedes Label (also Jedes "bla:") 0x7C00 draufaddieren soll. Deshalb sind die Label im Protected-Mode solange du 0 als Basisadresse deiner Deskriptoren verwendest schon richtig.
Und ich meinte mit dem ersten satz, dass er da ja nur noch die "BootSignatur" schreibt, und das davor schon rum ist.
Das du deine Sachen richtig anordnen musst ist irgendwie klar :wink:
Dir sollte übrigens bewusst sein, dass
loadmsg db "Lade Tuxmaniac...",13,10,0 ;Loading up Tuxmaniac
nichts ausgibt, dass legt nur einen Bereich mit dem String an. Bei deinem Code von oben wären die Daten die dort liegen aber einfach als Code interpretiert worden, wobei natürlich nur Mist rauskommen kann.
In Bochs seh ich den String kurz und das flackert dann immer.
Nun hab ich mal in VmWare geguckt, da steht kernel stack fault (Hardware reset),
was kann ich dagegen tun, und vorallem wo tritt er auf?
Es ist jetzt deine Aufgabe herauszufinden wo es crasht, dafür bietet qemu und bochs einiges an nützlicher Funktionalität. Informieren sie sich. :wink:
Wenn du damit garnichts zurecht kommst, dann stell ein Image zur Verfügung, falls ich Zeit habe schau ich mir das mal an.
-
ok das erste hab ich nicht so wirklich verstanden : kann es sein dass im Protect mode dann das org eh nicht mehr zählt?
ja das mit loadmsg, das ist da falsch, das wir von der kernel.asm ausgegeben, was später aber ins boot_up kommt.
Aber was heißen eigentlich die Zahlen dannach (13,10,0)
Und WIE genau, kann ich etwas debuggen?
http://www.google.de/search?q=bochs+debug+deutsch
hilft mir nicht wirklich
-
ok das erste hab ich nicht so wirklich verstanden : kann es sein dass im Protect mode dann das org eh nicht mehr zählt?
ok, fangen wir mit folgendem Code an (test1.asm):
[bits 16]
jmp 0x08:test
test:
Man beachte, dass das ein far-jump ist, wenn man das assembliert (nasm test1.asm -o blub1 -f bin) und anschließend wieder disassembliert (ndisasm blub1), dann ergibt sich folgendes:
00000000 EA05000800 jmp word 0x8:0x5
Machen wir nun das gleiche für diesen Code
[bits 16]
[org 0x7C00]
jmp 0x08:test
test:
ergibt sich hingegen
00000000 EA057C0800 jmp word 0x8:0x7c05
So, nun sieht man, dass im ersten Fall die Adresse des Labels 0x05 war im zweiten aber 0x7C00 + 0x05, d.h. genau das mehr was wir mit org angegeben haben. Das bedeutet also, dass der Assembler durch die org-Angabe weiß wie er die Adressen der Labels zu berechnen hat.
Jetzt sollte es hoffentlich offensichtlich sein, dass der Assembler - unter der Voraussetzung, dass deine Segmentdeskriptoren Basis 0 haben - auch im Protected-Mode die richtigen Adressen erzeugt, was natürlich optimal ist. :wink:
Aber was heißen eigentlich die Zahlen dannach (13,10,0)
13 = Carriage Return, an Position 0 der momentanen Zeile zurücklaufen
10 = Line feed, gleiche Position eine Zeile weiter unten
0 = Ende der Zeichenkette (für deine Ausgabefunktion relevant)
Und WIE genau, kann ich etwas debuggen?
Wenn du bochs mit Debugger startest (unter Windows dürfte das über bochsdbg oder bochs_dbg oder so gehen) dann kann man Breakpoints setzen, den Code bis dahin ausführen lassen, den Registerinhalt anschauen, Singlesteppen, d.h. Instruktionsweise den Code ausführen lassen und nach jeder Instruktion kann man wieder Register etc... anschauen.
Generell sollte bochs aber auch den Grund einer Exception ins Log/Bildschirm schreiben, falls man das "log level" (siehe bochs Konsolenmenü) bei "[CPU]" überall auf "report" stellt.
Unter qemu kann sich erstmal die Exceptions mittels "-d int" (als Kommandozeilenparameter) ins Log schreiben lassen. Dann kannst du bei deinen Assemblercode mal disassemblieren und schauen was an der Stelle so passiert.
Das wiki hat auch einen Eintrag zum Debuggen, nämlich hier (http://lowlevel.brainsware.org/wiki/index.php/Debugging#bochs).
-
tausend dank.
Das heißt aber nun, dass ich doch wenn ich den Protected Mode Code nutzen will, am besten vor alle meine Adressen ein 0x7C setzen sollte.
also sie manuell eingeben..
ah stimmt das das die ASCII zeichen 13+10 sind wusst ich nicht (in Delphi nutzt man das ja auch um Zeilenumbrüche zu machen, und null das das ende heißt,
interessant.
Debug :
(0) [0xfffffff0] f000:fff0 (unk.ctxt): jmp far f000:e05b ; ea5be000f0
<bochs:2>c (mein Befehl das es weiter geht)
(0).[361774051] [0x00007c78] 008:00000000000007c78 <unk.ctxt>: pop ss ;17
Next at t=361774052
// Hier kommt der Reset?!
-
ok durch verändern, hat es nun irgendwie wieder funktioniert...
Doch Folgendes Problem :
mov si, welcome_message ; Schreibe in Variable
call schreiben
mov si, copyright_message
call schreiben
mov si, reboot_message ; Wir zeigen einfach nur einen String an
call schreiben ; "schreiben" gibt den String am Bildschirm aus
call lesen ; "lesen" wartet bis eine Taste gedrückt wurde
jmp reset ; Danach wird die Funktion "reset" aufgerufen
Nun, das erste macht er (mov + call), und dann ist ende gelände?!
-
Nun, das erste macht er (mov + call), und dann ist ende gelände?!
dann scheinst du in 'schreiben' nen fehler zu haben. dazu fällt mir folgendes ein:
1. du solltest sicherstellen das der stack aufgeräumt ist bevor du die procedur mit 'retn' wieder verlässt, d.h. genau soviel vom stack holen(pop) wie du drauf schiebst(push)
2. hast du möglicher weise eine Endlosschleife in deinem code
3. du hast überhaupt kein 'retn'