1
Softwareentwicklung / Re: fprintf Funktioniert nicht
« am: 31. March 2013, 23:39 »
Das kann ich bestätigen, builtin funktioniert am Besten.
09. October 2024, 19:07
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
Du hast übersehen, dass im Long Mode ein anderes ABI zu beachten ist. Der Parameter fürWas man nicht alles in den paar Wochen ohne os-dev vergisst. Wird gefixt.Code: [Auswählen]handle_interrupt
kann nicht über den Stack übergeben werden, sondern muss inCode: [Auswählen]rdi
übergeben werden. Siehe auch: System V Application Binary Interface AMD64 Architecture Processor Supplement.
0x0d ist ein #GP fault und kein #PF, der Auftritt weil etwas mit deinem datensegment 0x10 (e = 0x10) nicht stimmt.Gab vorher einige Probleme mit #PF, deshalb hab ich das wohl verwechselt, wie auch immer.
Es sieht auch merkwürdig aus, das sich die Beschreibungen trotz gleicher Selektoren unterscheiden:ZitatSS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
FS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
GS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
Außerdem gibt es im LongMode noch ein paar mehr Register (r8-r15), die du evtl. sichern solltest. Ein paar werden zwar sind laut abi zwar für den caller reserviert, aber ich glaube das sind nicht alles r8-r15.
%macro handler 1
int_stub_%1:
push qword 0x0
push qword %1
jmp handler_common
%endmacro
%macro handler_errorcode 1
int_stub_%1:
push qword %1
jmp handler_common
%endmacro
handler_common:
push rbp
push rdi
push rsi
push rdx
push rcx
push rbx
push rax
push rsp
call handle_interrupt
add rsp, 0x8
pop rax
pop rbx
pop rcx
pop rdx
pop rsi
pop rdi
pop rbp
add rsp, 0x10
iretq
----------------
IN:
0x000000000010a07b: lidt 0x10ac33
0x000000000010a083: sti
----------------
IN:
0x000000000010a084: hlt
Servicing hardware INT=0x20
0: v=20 e=0000 i=0 cpl=0 IP=0008:000000000010a085 pc=000000000010a085 SP=0010:0000000000107454 EAX=0000000000000000
RAX=0000000000000000 RBX=deadbeefc0debeef RCX=0000000000000000 RDX=0000000000000000
RSI=0000000000000000 RDI=0000000000103454 RBP=0000000000000000 RSP=0000000000107454
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000010a085 RFL=00200202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
FS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
GS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 000000000010ac11 00000017
IDT= 0000000000103144 0000030f
CR0=80000011 CR2=0000000000000000 CR3=0000000000001000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=0000000000103454 CCO=EFLAGS
EFER=0000000000000500
----------------
IN:
0x000000000010ab5f: pushq $0x0
0x000000000010ab61: pushq $0x20
0x000000000010ab63: jmp 0x10abc5
----------------
IN:
0x000000000010abc5: push %rbp
0x000000000010abc6: push %rdi
0x000000000010abc7: push %rsi
0x000000000010abc8: push %rdx
0x000000000010abc9: push %rcx
0x000000000010abca: push %rbx
0x000000000010abcb: push %rax
0x000000000010abcc: push %rsp
0x000000000010abcd: callq 0x10ad04
----------------
IN:
0x000000000010ad04: sub $0x8,%rsp
0x000000000010ad08: mov %rdi,(%rsp)
0x000000000010ad0c: add $0x8,%rsp
0x000000000010ad10: retq
----------------
IN:
0x000000000010abd2: add $0x8,%rsp
0x000000000010abd6: pop %rax
0x000000000010abd7: pop %rbx
0x000000000010abd8: pop %rcx
0x000000000010abd9: pop %rdx
0x000000000010abda: pop %rsi
0x000000000010abdb: pop %rdi
0x000000000010abdc: pop %rbp
0x000000000010abdd: add $0x10,%rsp
0x000000000010abe1: iretq
check_exception old: 0xffffffff new 0xd
1: v=0d e=0010 i=0 cpl=0 IP=0008:000000000010abe1 pc=000000000010abe1 SP=0010:0000000000107428 EAX=0000000000000000
RAX=0000000000000000 RBX=deadbeefc0debeef RCX=0000000000000000 RDX=0000000000000000
RSI=0000000000000000 RDI=0000000000103454 RBP=0000000000000000 RSP=0000000000107428
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=000000000010abe1 RFL=00200002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
CS =0008 0000000000000000 00000000 00209800 DPL=0 CS64 [---]
SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
FS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
GS =0010 0000000000000000 00000000 00009100 DPL=0 DS16 [--A]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 000000000010ac11 00000017
IDT= 0000000000103144 0000030f
CR0=80000011 CR2=0000000000000000 CR3=0000000000001000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000010 CCD=0000000000107428 CCO=ADDQ
EFER=0000000000000500
Bei mir läuft rEFInd einwandfrei - wenn er den Eintrag überschreibt würde ich da ne komische EFI-Firmware vermuten.
Was auszuprobieren wäre wäre der Workaround für andere Kaputtheiten (kann keine Einträge anlegen) -> den Win-Bootloader in der EFI-Bootpartition umbenennen und stattdessen rEFInd da hinsetzen (hängt nur am Dateinamen, wenn der ganze Crypto-krams erstmal aus ist) - den umbenannten Winloader kann rEFInd dann angeblich booten ohne dass da was zurückersetzt wird. Details im Arch-Wiki
Wohl eher 4096 statt 1024. Jup, voraussgesetzt context->page_directory ist auch wirklick ein DWORD.Zum Codingstil ein paar Vorschläge meinerseits:Von dieser Art Optimierung rate ich genau dann ab, wenn sie nicht korrekt ist. Es muss hier 1024 sein nicht 4096. Wie lange hättest du gebraucht, um diesen Bug zu finden?Code: [Auswählen]int i;
for(i = 0; i < 1024; i++)
{
context->page_directory[i] = 0;
}
// ersetzen durch
memset(context->page_directory, 0, (size_t)1024);
int i;
for(i = 0; i < 1024; i++)
{
context->page_directory[i] = 0;
}
// ersetzen durch
memset(context->page_directory, 0, (size_t)1024);
// solltest du memset und Konsorten noch nicht wirklich implentiert haben, empfehle ich die osdevlibc (bietet genau solche Standardfunktionalität, aber ohne erweiterte OS-spezifische Dinge wie Dateien etc. - du kannst sie einfach mitlinken, bis du eine "richtige" libc wie newlib oder glibc hast.
return 0x0;
// ersetzen durch
return NULL;
Das ist keine zum Thema wirklich beitragende Antwort, aber ich habe hier auch ein Z77-MB mit 16 GB RAM (was auch immer der zur Sache tut)Falls sich jemand fragt, wozu ich 20GB Swap habe!
und ich habe mich offenbar richtigerweise für BIOS-Emulation und GRUB (Legacy) entschieden. :3Ich dachte, dass nach mehr als 2 Jahren UEFI-Entwicklung im Desktopbereich das Ganze einigermaßen klappen würde, aber das ist ja jetzt doch nicht der Fall...
Übrigens auch Arch, aber Windows 7.
Also, gibt es einen speziellen Grund, warum du UEFI willst? Außer, weil es geht?
Habe ich auch schon gedacht und 10x gecheckt, ist aber nicht der Fall.Okay, anscheinend ist der tyndur-Trick doch nicht so genial:Sieht für mich danach aus, als würdest du init.o zweimal an ld übergeben.
(ld-Output)
x86/init.o:0000000000000380 T find_contingous_free_pages_32
x86/init.o:00000000000002d0 T find_free_page_32
x86/init.o:0000000000000000 T init_32
x86/init.o:00000000000000fb T init_pmm_32
x86/init.o:000000000000009a T init_vmm_32
x86/init.o:000000000000066d T map_page_32
x86/init.o:0000000000000a89 T map_page_range_32
x86/init.o:0000000000000011 T memset_32
x86/init.o:0000000000000436 T pmm_alloc_32
x86/loader.o: U handler_32
x86/loader.o: U init_32
CC =gcc
AS =nasm
LD =ld
EMU =qemu-system-i386 -no-kvm -monitor stdio -s -S -cdrom $(ISO)
#WFLAGS =-Wall -Wextra -Wshadow -Wconversion -Wunreachable-code -Werror-implicit-function-declaration -Wuninitialized
WFLAGS =-Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes
CFLAGS =-nostdinc -nostdlib -nostartfiles -nodefaultlibs -ffreestanding -fno-stack-protector -fno-leading-underscore -fno-strict-aliasing -fno-builtin -fomit-frame-pointer -m64 -g3 -O0 -c -Iinclude -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
ASFLAGS =-f elf64
LDFLAGS =-m elf_x86_64 -T linker.ld -nostdlib -nodefaultlibs -Bstatic
STDLIB =lib/std/string.o lib/std/ctype.o lib/std/errno.o lib/std/stdio.o lib/std/stdlib.o lib/std/uchar.o lib/std/wchar.o #lib/std/math_exp.o lib/std/math_misc.o lib/std/math_pow.o lib/std/math_trigo.o
MEMLIB =#lib/ptmalloc3/malloc.o lib/ptmalloc3/ptmalloc3.c
KERNEL =arch/x86/loader.o arch/amd64/kernel.o arch/amd64/handler.o arch/amd64/mm.o arch/amd64/pmm.o arch/amd64/vmm.o arch/amd64/console.o arch/x86/init.o
OBJ =$(STDLIB) $(MEMLIB) $(KERNEL)
KERNELF =kernel.sys
.PHONY: all run
all: image
image: kernel stdlib memlib
$(LD) $(LDFLAGS) $(OBJ)
-objcopy --only-keep-debug $(KERNELF) kernel.sym
-objcopy --strip-debug $(KERNELF)
kernel: $(KERNEL)
memlib: $(MEMLIB)
stdlib: $(STDLIB)
arch/x86/init.o: arch/x86/init.c
$(CC) -nostdinc -nostdlib -nostartfiles -nodefaultlibs -ffreestanding -fno-builtin -fomit-frame-pointer -m32 -g3 -O0 -c -Iinclude -o arch/x86/init32.o $^
objcopy -O elf64-x86-64 arch/x86/init32.o $@
-@rm arch/x86/init32.o
%.o: %.S
$(AS) $(ASFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -o $@ $^
mkimage: all
@cp $(KERNELF) $(BOOTDIR)
grub-mkrescue -o "$(ISO)" $(ISODIR)
-@wait
run: mkimage
$(EMU)
Ich will eigentlich erstmal meinen Long Mode Code testen. Ich musste ja sehr viel "blind" schreiben.objcopy hat also mal eben 37 Symbole unter den Tisch fallen lassen. Hmm.Das ist auch die Idee in tyndur. Um mal zu erläutern wie tyndur das macht:
Der Loader ist ein 32-Bit "Kernel". In den Loader wird der 64-Bit Kernel eingebettet. Dazu wird der Kernel (der eigentlich im ELF-Format ist) von objdump genommen und als binary interpretiert. objdump erzeugt daraus eine neue ELF-Objektdatei, die nur die start/end-Symbole enthält, und darin eingebettet ist der Kernel. Diese neue Objekt-Datei wird zum Loader dazugelinkt, der nun auch die start/end-Symbole kennt. Der Loader hat einen kleinen ELF-Parser eingebaut, der den Kernel an seine korrekte Adresse kopiert. Anschließend springt der Loader an die Startadresse der Kernels. Die Startadresse steht im ELF-Header.
Wenn du hingegen den 32-Bit-Teil in den 64-Bit-Kernel einbetten willst, kannst du mal ausprobieren, ob du init32.o in eine 64-Bit-ELF umwandeln kannst. objcopy -O elf64-x86-64 init32.o oder so. (Ungetestet.)
arch/x86/init.o: In function `_binary_arch_x86_init32_o_start':
(.data+0x0): multiple definition of `_binary_arch_x86_init32_o_start'
./arch/x86/init.o:(.data+0x0): first defined here
arch/x86/init.o: In function `_binary_arch_x86_init32_o_end':
(.data+0x5cd0): multiple definition of `_binary_arch_x86_init32_o_end'
./arch/x86/init.o:(.data+0x5cd0): first defined here
arch/x86/loader.o: In function `loader':
arch/x86/loader.S:(.text+0x0): multiple definition of `loader'
./arch/x86/loader.o:arch/x86/loader.S:(.text+0x0): first defined here
arch/x86/loader.o: In function `multiboot':
arch/x86/loader.S:(.bss+0x188): multiple definition of `multiboot'
./arch/x86/loader.o:arch/x86/loader.S:(.bss+0x188): first defined here
./arch/x86/loader.o: In function `shortjmp':
arch/x86/loader.S:(.text+0x9b): undefined reference to `init_32'
arch/x86/loader.o: In function `shortjmp':
arch/x86/loader.S:(.text+0x9b): undefined reference to `init_32'
make: *** [image] Fehler 1
$ readelf -s arch/x86/init32.o
Symboltabelle ‚.symtab‛ enthält 42 Einträge:
Num: Wert Size Typ Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS init.c
2: 00000000 0 SECTION LOCAL DEFAULT 5
3: 00000000 0 SECTION LOCAL DEFAULT 7
4: 00000000 0 SECTION LOCAL DEFAULT 8
5: 00000000 0 SECTION LOCAL DEFAULT 9
6: 00000000 0 SECTION LOCAL DEFAULT 11
7: 00000000 0 SECTION LOCAL DEFAULT 12
8: 00000000 0 SECTION LOCAL DEFAULT 13
9: 00000000 0 SECTION LOCAL DEFAULT 15
10: 00000000 0 SECTION LOCAL DEFAULT 25
11: 00000000 0 SECTION LOCAL DEFAULT 27
12: 00000000 0 SECTION LOCAL DEFAULT 29
13: 00000000 0 SECTION LOCAL DEFAULT 17
14: 00000000 0 SECTION LOCAL DEFAULT 19
15: 00000000 0 SECTION LOCAL DEFAULT 21
16: 00000000 0 SECTION LOCAL DEFAULT 23
17: 00000000 0 SECTION LOCAL DEFAULT 30
18: 00000000 0 NOTYPE LOCAL DEFAULT 1 wm4.1.e9f73b8cd07e2ddf8d0
19: 00000000 0 NOTYPE LOCAL DEFAULT 2 wm4.paging.h.6.4b576cfed7
20: 00000000 0 NOTYPE LOCAL DEFAULT 3 wm4.stddef.h.2.6ea241740e
21: 00000000 0 NOTYPE LOCAL DEFAULT 4 wm4.stdbool.h.2.2f4031346
22: 00000000 0 SECTION LOCAL DEFAULT 28
23: 00000000 0 SECTION LOCAL DEFAULT 1
24: 00000000 0 SECTION LOCAL DEFAULT 2
25: 00000000 0 SECTION LOCAL DEFAULT 3
26: 00000000 0 SECTION LOCAL DEFAULT 4
27: 00000000 17 FUNC GLOBAL DEFAULT 5 init_32
28: 000000fb 469 FUNC GLOBAL DEFAULT 5 init_pmm_32
29: 0000009a 97 FUNC GLOBAL DEFAULT 5 init_vmm_32
30: 00000011 137 FUNC GLOBAL DEFAULT 5 memset_32
31: 00000436 567 FUNC GLOBAL DEFAULT 5 pmm_alloc_32
32: 00000000 0 NOTYPE GLOBAL DEFAULT UND pml4
33: 00000a4d 82 FUNC GLOBAL DEFAULT 5 map_page_range_32
34: 00000000 0 NOTYPE GLOBAL DEFAULT UND mmap_count
35: 00000000 0 NOTYPE GLOBAL DEFAULT UND mmap
36: 00000000 0 NOTYPE GLOBAL DEFAULT UND multiboot
37: 000002d0 176 FUNC GLOBAL DEFAULT 5 find_free_page_32
38: 00000380 182 FUNC GLOBAL DEFAULT 5 find_contingous_free_page
39: 00000000 0 NOTYPE GLOBAL DEFAULT UND malloc
40: 0000066d 992 FUNC GLOBAL DEFAULT 5 map_page_32
41: 00000000 0 NOTYPE GLOBAL DEFAULT UND pmm_alloc
tobias@MD5320:~/os-dev$ readelf arch/x86/init.o -s
Symboltabelle ‚.symtab‛ enthält 5 Einträge:
Num: Wert Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 SECTION LOCAL DEFAULT 1
2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 _binary_arch_x86_init32_o
3: 0000000000005cd0 0 NOTYPE GLOBAL DEFAULT 1 _binary_arch_x86_init32_o
4: 0000000000005cd0 0 NOTYPE GLOBAL DEFAULT ABS _binary_arch_x86_init32_o
Libraries werden übrigens mit ar erstellt, nicht mit ld.Wieder was gelernt.