Lowlevel
Lowlevel => Softwareentwicklung => Thema gestartet von: Buschpilot am 17. December 2011, 21:47
-
Hallo!
ich bin am verzweifeln. ich wage mich daran ein kleines eigenes os zu programmieren.
das problem ist dass ich überhaupt nicht weiss wie ich den code compilen soll.
ich würde gerne mit der intel-syntax arbeiten. habe GCC versucht aber der gibt mir ständig fehler aus zum beispiel bei kommentaren und anderen sachen weshalb ich echt nicht weiss wie das gehen soll.
echt schade wenn es an solchen sachen scheitern würde!
im vorraus danke für die hilfe :)
mfg buschpilot
-
Hallo Buschpilot
ohne genaue Frage, keine Antwort möglich!
Ein paar Fakten sind schon nötig.
Auf welcher Plattform programmierst Du? Linux -Windows
Gruß
Relbmessa
-
Hallo,
gcc ist kein Assembler, sondern ein (C-)Compiler. C hat nur eine Syntax, also geht es dir vermutlich um die Assemblersyntax. Dazu gibt es im Wiki ein paar Anleitungen, wie man da auf Intelsyntax umstellen kann. (Bei ganzen Dateien mit Parameter "-masm=intel", bei Inline-Assembler mit zwei Direktiven, deren Namen ich aus dem Kopf nicht weiß.) In jedem Fall solltest du die AT&T-Syntax wenigstens lesen können.
Kommentare sind auch in Assemblerdateien im C-Style, also: /* Kommentar */.
Im Übrigen schließe ich mich Relbmessa an: Mehr Informationen, bitte.
Gruß,
Svenska
-
Tut mir Leid meinte natürlich den GAS.
Ich habe Windows und Linux also beides.
Ich bräuchte eben einfach einen Assembler der die Intel-syntax kompiliert. Hab die Option -masm=intel schon ausprobiert allerdings zeigt gas dann für mich unerklärliche fehler auf. habe auch gelesen, dass die intel syntax trotzdem minimal anders ist bei gas. wüsste jemand inwiefern?
-
Gib uns Beispielcode und Fehler, dann können wir vielleicht auch was dazu sagen. "Geht nicht" ist viel zu oft eine unzureichende Fehlerbeschreibung...
Alternativ kannst du auch NASM benutzen, der macht Intelsyntax.
-
Alternativ kannst du auch NASM benutzen, der macht Intelsyntax.
NASM kann ich auch empfehlen,dazu KWrite als Editor.
Gruß
Relbmessa
-
;*********bootloader***********
extern kernel
org 0
jmp 0x07c0h:start
start:
mov ax, 7c0h
mov ds, ax
mov es, ax
call kernel
DB 510-$ dup(0)
DW 0AA55h
Fehlermeldung:
bootloader.S: Assembler messages:
bootloader.S:3: Error: no such instruction: 'extern kernel'
bootloader.S:5: Error: no such instruction: 'org 0'
bootloader.S:6: Error: junk 'h:start' after expression
bootloader.S:10: Error: too many memory references for 'mov'
bootloader.S:11: Error: too many memory references for 'mov'
bootloader.S:12: Error: too many memory references for 'mov'
bootloader.S:16: Error: no such instruction: 'db 510-$ dup(0)'
bootloader.S:17: Error: no such instruction: 'dw 0AA55h'
Ich will nicht sagen das der Coder richtig ist, bin momentan nämlich ziemlich verwirrt mit all den syntax rund um assembler aber dennoch kommen mir einige fehlermeldung gar skurril vor.
den NASM hab ich auch auf dem PC. Aber wie bei den anderen auch weiss ich die syntax nicht. unterscheidet sich ja minimal nur weiss ich nicht wie.
schonmal danke für die tolle hilfe!
-
Hallo Buschpilot
Ein paar mehr Grundlagen sind schon nötig!
ohne Fleiß usw.
Es gibt viele schöne Beispiele die man erst mal studieren sollte.
naja:
Und ein Laufwerk wird ja auch noch benötigt.
Hier ein kleines Beispiel mit NASM.
;NASM -> nasm -f bin -o boot.bin boot.asm
org 0x7C00 ; set up start address of bootloader
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; setup a stack and segment regs ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
xor ax, ax ;null
mov ds, ax
mov es, ax
mov ss, ax
mov sp, ax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; read kernel from floppy disk ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov [bootdrive], dl ; boot drive stored by BIOS in DL.
; we save it to [bootdrive] to play for safety.
load_kernel:
xor ax, ax ; mov ax, 0 => function "reset"
int 0x13
jc load_kernel ; trouble? try again
mov bx, 0x8000 ; set up start address of kernel
; set parameters for reading function
; 8-bit-wise for better overview
mov dl,[bootdrive] ; select boot drive
mov al,1 ; read 1 sectors >anzahl<
mov ch, 0 ; cylinder = 0
mov cl, 2 ; sector = 2 (erster Sector Bootsector)
mov dh, 0 ; head = 0
mov ah, 2 ; function "read"
int 0x13
;;;;;;;;;;;;;;;;;;
; jump to kernel ;
;;;;;;;;;;;;;;;;;;
jmp 0x0000:0x8000 ; address of kernel. "jmp bx" might also work.
;;;;;;;;
; data ;
;;;;;;;;
bootdrive db 0 ; boot drive
times 510-($-$$) hlt
dw 0xAA55
Viel Spaß beim Üben
Gruß
Relbmessa
-
Danke! Werde ich machen :)
Nur noch die frage mit der syntax wie genau unterscheidet sich die bei nasm vom masm?
Finde dazu im internet nichts. Ist mein letztes problem soweit
-
Hallo Buschpilot
Ich verstehe deine Frage nicht!
-Ich glaube nicht, dass sich Einer hinsetzt und die Unterschiede rausarbeitet.
-Für Dich wird es keine relevanten Unterschiede geben.
-Was sich unterscheidet sind die vielen kleinen Zusatzhilfen .(Pseudobefehle)
-Die Lizens unterscheidet sie auch!!!! :-o
Gruß
Relbmessa
-
Dann ist ja gut wenn es keine wichtigen unterschiede für mich gibt.
Die Frage hat sich dann geklärt :)
Vielen Dank an alle!
-
Hallo,
um noch kurz ein paar Dinge zu nennen, die mir gerade einfallen:
Pseudobefehle wie extern kriegen beim GAS einen Punkt vorangestellt. Hexadezimalzahlen werden als 0xZAHL dargestellt, MASM/NASM sollten auch ZAHLh verstehen. Beides zusammen ist aber definitiv falsch.
Zum Code: Der Bootsektor sollte eigentlich keine externen Funktionen einbinden, da er den Code dafür ja erst vom Speichermedium laden und an die richtige Stelle im RAM setzen muss. Außerdem solltest du dir nochmal wirklich überlegen, ob du dir den ganzen Boot-Ärger überhaupt antun möchtest. Alles, was vor dem Kernel liegt (also der Bootcode) ist viel Aufwand und Technik von vor ewigen Zeiten mit allen Quirks und seltsamer Hardware. Die allgemeine Empfehlung hier ist, das komplett wegzulassen und einen der vorhandenen gut funktionierenden Bootloader zu benutzen (z.B. Grub, Syslinux). Wenn du ein Betriebssystem (und keinen Bootloader) schreiben möchtest, ersparst du dir eine Menge nutzlosen Aufwand.
Denke bitte drüber nach.
Gruß,
Svenska
-
Hatte ich auch schon überlegt allerdings habe ich keine ahnung wie ich den Multiboot-header da genau einbaue um zum beispiel mit grub zu booten.
-
Also die Dokumentation deines Assembler solltest du kennen, wenn du mit Assembler arbeiten möchtest.
Davon abgesehen: Wenn du die Multibootsignatur im Binary nicht an die richtige Stelle bekommst, wirst du höchstwahrscheinlich auch keinen funktionierenden Bootloader hinkriegen.
Im Wiki gibt es ein Tutorial, was du mal durchspielen kannst, das ist aber mit C und nur wenig Assembler.
-
Hier wird Ihnen geholfen - billig, günstig und ohne Nebenwirkungen (http://www.lowlevel.eu/wiki/OS-Dev_f%C3%BCr_Einsteiger)
-
@DerHarmut
Sicher das es keine Nebenwirkungen gibt? OsDev macht süchtig :evil:
SCNR
Dieser Post ist eigentlich komplett überflüssig, macht sich aber gut in der Statistik :wink:
Grüße,
LittleFox
-
MB_MAGIC dd equ 0x1badb002
MB_FLAGS dd equ 0x0
MB_CHECKSUM dd -(MB_MAGIC + MB_FLAGS)
würde das so funktionieren? (NASM)
-
Hi,
bei mir sieht es so aus:
section multiboot
align 4
FLAGS equ 0x6
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC + FLAGS) ; Checksum
MultiBootHeader:
dd MAGIC ; Magic number
dd FLAGS ; Flags
dd CHECKSUM ; Checksum
die Sektion ist wichtig, wenn dein Kernel mal Größer als 8KB wird (und das wird er ziemlich schnell ;)). Durch die eigene Sektionen kannst du im Linkerscript festlegen, dass der Multiboot-Header an erster Stelle in der Datei ist.
Align 4 ist wichtig, müsste aber Standard sein
Die Flags kannst du erstmal ignorieren, ich arbeite mit VESA :)
Der Rest ist wie bei dir, nur anders geschrieben :)
Grüße,
LittleFox
-
Dann ist ja gut wenn es keine wichtigen unterschiede für mich gibt.
Die Frage hat sich dann geklärt :)
Vielen Dank an alle!
Es gibt ein paar Unterschiede beim Syntax der Befehle:
MASM:
mov BYTE PTR[EAX], 1
NASM:
mov BYTE[EAX], 1
MASM:
mov esi, OFFSET SPEICHER
NASM:
mov esi, SPEICHER
MASM:
mov eax, DWORD PTR[di+0Ch]
NASM:
mov eax, [di+0Ch]
Dirk
-
Es gibt ein paar Unterschiede beim Syntax der Befehle:
MASM:
mov BYTE PTR[EAX], 1
NASM:
mov BYTE[EAX], 1
NASM akzeptiert aber auch die Schreibung mit "PTR"
MASM:
mov esi, OFFSET SPEICHER
NASM:
mov esi, SPEICHER
Nasm kennt nur eine Sorte von Symbolen, das Label. Dahinter wird immer die Referenz auf ein Objekt verstanden. Für den Speicherzugriff müssen also immer eckige Klammern verwendet werden.
-
Hallo,
so habe jetzt GRUB als bootmanager und auch als .iso mit meinem kernel drauf. beim booten kann ich auch mein os auswählen aber dann kommt die meldung: "error: no loaded kernel"
dachte es liegt daran dass ich den multiboot header falsch erstellt habe aber mit der version von littlefox funktioniert es auch nicht.
woran kann es liegen?
EDIT:
am multibootheader liegt es nicht
die fehlermeldung lautet jetzt: "unknown ELF class"
habe mit nasm anstatt bin eine elf datei zu erzeugen "nasm -f elf -o kernel.elf kernel.asm" bzw "nasm -f elf32 -o kernel.elf kernel.asm"
habe die grub.cfg entsprechend geändert.
dann taucht die fehlermeldung auf: "invalid ELF file type"
-
Du hast eine Objektdatei erstellt (relocatable), die musst die jetzt zu einer ausführbaren ELF-Datei (executable) linken.
-
und wie mache ich das? hat nasm da einen integriert? habe nichts gefunden und mir ALINK geladen aber da kann ich nur zu .COM .EXE und .PE dateien linken
-
Mit ld, so wie du es mit einem C-Kernel auch machen würdest.
-
stimmt gibts ja auch noch hab ich gar nicht dran gedacht da ich ja mit nasm und nicht mehr mit gcc arbeite.
ich verstehe allerdings nicht diese linkerscripts. habe schon das manual dazu gelesen aber verstehe es trotzdem nicht.
-
Bei NASM kannst du entweder das BIN-Format (-f bin) und die ORG-Direktive verwenden, oder das ELF-Format (-f elf) und mit ld linken. Wenn du deinen ASM-Code mit C kombinieren willst, musst du in jedem Fall linken. Beim Linken werden die Objektdateien an eine feste Adresse ausgerichtet und alle Labels durch feste Adressen ersetzt. btw: ELF gibt es sowohl als relocatable als auch als executable. Images kannst du mit dd zusammensetzen.
Im Linker-Script (einbinden mit -T) stehen sowohl Ausgabeformat, Startadressen der einzelnen Sections, als auch das Label des Einstiegspunkts.
Tutorial im Wiki: http://www.lowlevel.eu/wiki/C-Kernel_mit_GRUB
-
ja aber wenn ich mit grub .bin laden will erscheint "unknown ELF class"
-
Wenn du eine flache Binary mit GRUB laden willst, musst du den a.out-Kludge benutzen, d.h. Bit 16 in den Flags setzen und die entsprechenden zusätzlichen Felder im Multibootheader angeben.
Aber über kurz oder lang willst du sowieso einen Linker benutzen.
-
wie genau sieht das aus? tut mir leid wenn ich so viel frage :)
-
Das Tutorial hat bei mir funktioniert. Du kannst dir ja erstmal alles kopieren und das zum Laufen bringen.
-
Ich hab mich ebenfalls für die Intel-Syntax entschieden:
section multiboot
MB_MODULEALIGN equ 0x0 ;not used
MB_MEMINFO equ 0x0 ;not used
MB_FLAGS equ MB_MODULEALIGN | MB_MEMINFO
MB_MAGIC equ 0x1BADB002
MB_CHECKSUM equ -(MB_MAGIC + MB_FLAGS)
align 4
dd MB_MAGIC
dd MB_FLAGS
dd MB_CHECKSUM
section .text
extern init
global _start
_start:
mov esp, kernel_stack
call init
_stop:
cli
hlt
jmp _stop
section .bss
resb 8192 ; 8kB stack
kernel_stack:
Und das dafür vorgesehene Makefile entsprechend geändert:
# Main Makefile
SRCS = $(shell find -name '*.[cS]')
OBJS = $(addsuffix .o,$(basename $(SRCS)))
CC = gcc
AS = nasm
LD = ld
ASFLAGS = -f elf
CFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -melf_i386 -Ttext=0x100000
nnOS: $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^
%.o: %.S
$(AS) $^ $(ASFLAGS) -f elf -o $@
clean:
rm $(OBJS)
qemu:
qemu -kernel nnOS
.PHONY: clean