Beiträge anzeigen

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.


Themen - rizor

Seiten: 1 2 [3] 4
41
Offtopic / Anzahl der Prozessoren unter Linux bestimmten
« am: 01. March 2010, 21:14 »
Nabend zusammen,

ich versuche gerade herauszufinden, wie man unter Linux die Anzahl der Prozessoren bestimmen kann.
Unter cpuinfo findet man ja nur die Anzahl der CPUs.

Gibt es da eine einfache Möglichkeit, die ich vllt sogar ganz einfach durch ein eigenes Modul?

Danke.

Gruß
Sven
42
Offtopic / CPU-Cache
« am: 24. February 2010, 17:59 »
Nabend zusammen,

ich habe mal eine Frage zu den Level-Caches der x86-Architektur.
Es gibt ja verschiedene Arten von Caches.
Einmal die Art von Cache, die virtuelle Adressen speichern und dann einmal die, die die physikalischen Adressen speichern.
Was wird bei der x86-Architektur benutzt?
Das müsste an sich die physikalischen Adressen sein, da es ansonsten zu unnötigen Cache-Misses kommen würde, wenn auf einem Dual-Core zwei Prozesse auf gleichen virtuellen Adressen aber auf unterschiedlichen physikalischen Adressen arbeiten, oder?

Gruß,
rizor
43
Lowlevel-Coding / QEmu greift auf falschen Speicher zu
« am: 22. February 2010, 08:51 »
Hallo zusammen,

ich habe ein Problem mit QEmu.
Wenn der Emulator startet, stürzt er mitfolgendem Status ab:
qemu: fatal: Trying to execute code outside RAM or ROM at 0x000a0000

EAX=00004500 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00009fe0
EIP=0000fdfb EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =9000 00090000 0000ffff 00009300
CS =9020 00090200 0000ffff 00009b0f
SS =9000 00090000 0000ffff 00009300
DS =9000 00090000 ffffffff 00cf9300
FS =9000 00090000 0000ffff 00009300
GS =9000 00090000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT=     000c9a50 00000017
IDT=     00000000 000003ff
CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00004500 CCD=00004546 CCO=ADDB   
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Aborted

Ich vermute mal, dass es am Linker-Script liegt, da es vorher funktioniert hat.
Hier ist auch mal mein Linker-Script.
LD meldet allerdings keine Fehler oder Warnungen.
ENTRY(boot) /* the entry-method for the kernel */
OUTPUT_FORMAT(elf32-i386) /* the linked code is x86-code */

ALIGNMENT = 0x1000; /* the alignment for the linker-parts */
LINK_ADDRESS = 0x100000; /* the link-address of the kernel */

SECTIONS
{
. = LINK_ADDRESS; /* load the kernel at LINK_ADDRESS */

/* elemental symbols for correct mapping */
__kernel_start = .; /* the method for the loaded entry */
__ro_data_start = .; /* the start of the read-only-data */

/* code-section from the c-code*/
.text : AT(ADDR(.text))
{
__text_start = .; /* the start of the text-section */
__mb_start = .;
*(.multiboot)
__mb_end = .;
*(.text)
__text_end = .; /* the end of the text-section */
}


/* read-only data */
.rodata : AT(ADDR(.rodata))
{
__ro_start = .; /* the start of the read-only-section */
*(.rodata)
__ro_end = .; /* the end of the read-only-section */
}

/* symbols for other kernel-modules */
.symbols : AT(ADDR(.symbols))
{
__symbols_start = .; /* the start of the symbols-section */
*(.symbols)
__symbols_end = .; /* the end of the symbols-section */
}


. = ALIGN(ALIGNMENT); /* align the code at the alignment-address */
__ro_data_end = .; /* the end of the read-only-data*/
__rw_data_start = .; /* the start of read-write-data */


/* initialized data */
.data : AT(ADDR(.data))
{
__data_start = .; /* the start of the data-section */
*(.data)
__data_end = .; /* the end of the data-section */
}

/* uninitialized data */
.bss : AT(ADDR(.bss))
{
__bss_start = .; /* the start of the bss-section */
*(.bss)
__bss_end = .; /* the end of the bss-section */
}

. = ALIGN(ALIGNMENT); /* expand the kernel to a new ALIGNED address */

__rw_data_end = .; /* the end of read-write-data */
__kernel_end = .; /* the method for the loaded end*/
}

Woran kann es denn liegen?

Gruß,
rizor
44
Lowlevel-Coding / Page-Fault trotz richtiger Tabelle
« am: 11. February 2010, 23:49 »
Nabend zusammen,

habe gerade ein Problem mit der MMU.
Ich habe mir eine VMM geschrieben, die sich der MMU anpasst und verscuhe das System gerade an der i386-MMU.
Leider fliegt mir der Code, sobald ich Paging aktiviere (genau nach dem Befehl).
Habe mir alle Einträge angeschaut.
Die sehen gut aus.
Die Tabellen sind mit den Flags 0x3 gemappt und die Pages mit 0x103.
Müssten so ja stimmen für den Kernel-Space.

Hier mal der Code, der die Tabellen aufbaut:
index = kernel_space / level_info[1].managed_mem;
entries = 1;

//count the number of L1-table-entries to map the L1-table as a table
while((entries * level_info[1].level_entries) < level_info[0].level_entries)
entries++;

//map the L1-table as a table
for(i = 0; i < entries; i++){
l1_table[index - entries + i] =
((uint32_t)l1_table + i * level_info[1].managed_mem) | level_info[0].masks[FLAG_KRN_RW];
}

level_info[1].mapped_level_start = (void*)((index - entries) * level_info[1].managed_mem);

index -= entries + 1;

//create the table to map the L1-table
phys = (uint32_t)pmm_alloc((level_info[1].level_entries * sizeof(vmm_table_t)) / page_size , &errno);

//could not find enough memory for the table
if(errno == ERR_PMM_NO_FREE_MEM){
kprintf("PANIC: Could not find %#x, bytes for the L2-table to map the L1-table" , level_info[1].level_entries * sizeof(vmm_table_t));
while(1);
}

//FIXME: write code which supports unaligned memory
if((phys != 0) && ((phys % level_info[1].alignment) != 0)){
kprintf("PANIC: The VMM does not support wrong aligned memory\n");
kprintf("Tried to create the L2-table to map the L1-table\n");
kprintf("address: %p    alignment: %#x" , phys , level_info[1].alignment);
while(1);
}

memset((void*)phys , EMPTY , level_info[1].level_entries * sizeof(vmm_table_t));
l1_table[index] = phys | level_info[0].masks[FLAG_KRN_RW];
entries = 1;

while((entries * page_size) < (level_info[0].level_entries * sizeof(vmm_table_t)))
entries++;

for(i = 0; i < entries; i++){
((vmm_table_p)phys)[level_info[1].level_entries - entries + i] =
((uint32_t)l1_table + i * page_size) | level_info[1].masks[FLAG_KRN_RW];
}

level_info[0].mapped_level_start = (void*)((level_info[1].level_entries - entries) * page_size + (index * level_info[1].managed_mem));

#ifdef CONFIG_MAX_BOOT_STATUS
kprintf("\tmapped the L1-table at %p\n" , level_info[0].mapped_level_start);
kprintf("\tmapped the L2-table at %p\n" , level_info[1].mapped_level_start);
#endif /* CONFIG_MAX_BOOT_STATUS */

//create all tables
for(i = 0; i < index; i++){
phys = (uint32_t)pmm_alloc((level_info[1].level_entries * sizeof(vmm_table_t)) / page_size , &errno);

//could not find enough memory for the table
if(errno == ERR_PMM_NO_FREE_MEM){
kprintf("PANIC: Could not find %#x, bytes for the L2-table.\n" , level_info[1].level_entries * sizeof(vmm_table_t));
kprintf("Tried to map address %p -> %p" , level_info[1].managed_mem * i , level_info[1].managed_mem * i + level_info[1].managed_mem);
while(1);
}

//FIXME: write code which supports unaligned memory
if((phys != 0) && ((phys % level_info[1].alignment) != 0)){
kprintf("PANIC: The VMM does not support wrong aligned memory\n");
kprintf("Tried to create the L2-table to map the L1-table\n");
kprintf("address: %p    alignment: %#x" , phys , level_info[1].alignment);
while(1);
}

memset((void*)phys , EMPTY , level_info[1].level_entries * sizeof(vmm_table_t));

l1_table[i] = phys | level_info[0].masks[FLAG_KRN_RW];

Der Code mappt die L1- und L2-Tabellen und erstellt die Tabellen für den Kernel-Space.

Der folgende Code mappt einzelne Seiten:
//get the index of the L1-table
index = mmu_table_index((void*)((uint32_t)virt + i * page_size) , L1_TABLE , &errno);
//the L1-table is not supported
if(errno == ERR_MMU_UNSUPPORTED_TABLE){
kprintf("PANIC: the MMU does not support the L1-table");
while(1);
}

//it is not inside of the kernel space
if(l1_table[index] == EMPTY){
kprintf("PANIC: tried to map memory outside of the kernel-space\n");
kprintf("address: %p" , index * level_info[1].managed_mem + mmu_table_index((void*)((uint32_t)virt + i * page_size) , L2_TABLE , &errno) * page_size);
while(1);
}

l2_table = (vmm_table_p)(l1_table[index] & level_info[0].masks[FLAG_PHYS_ADDR]);

//get the index of the L2-table
index = mmu_table_index((void*)((uint32_t)virt + i * page_size) , L2_TABLE , &errno);
//the L2-table is not supported
if(errno == ERR_MMU_UNSUPPORTED_TABLE){
kprintf("PANIC: the MMU does not support the L2-table");
while(1);
}
l2_table[index] = ((uint32_t)phys + i * page_size) | level_info[1].masks[FLAG_KRN_RW];

Die index-Variable ist immer richtig gesetzt.

Woran kann es noch liegen, dass der Code fliegt?

Danke.

Gruß,
rizor
45
OS-Design / Mapping verschiedener Tabellen
« am: 25. January 2010, 11:02 »
Morgen zusammen,

ich bin gerade dabei mir eine variable virtuelle Speicherverwaltung zu schreiben.
Dabei muss ich mir ein paar Gedanken machen, wie man am besten die Tabellen mappt.
Wie man L1- und L2-Tabellen mappt ist ja kein Thema.
Aber wie macht man das am besten L3- und L4-Tabellen.
Ich erstelle mir erst einmal für 1 GB Kernel-Space die Tabellen, damit ich mich nicht um die Aktualisierung der Prozesse kümmern muss.
Wie kann ich jetzt die Tabellen selber mappen?

An sich könnte ich ja temporär einen Eintrag der L1-Tabelle immer freihalten, damit ich an die Tabellen rankomme.
Wie praktikabel ist das?
Gibt es vielleicht auch bessere Realisierungen?

Danke.

Gruß
rizor
46
Morgen zusammen,

ich habe ein Problem mit meinen Structs.
Ich möchte ein globales Struct schon vor der Laufzeit initialisieren.
Elemente dieses Teils sind auch zwei arrays, von denen ich nicht die Länge fest bestimmen kann.
Gibt es eine Möglichkeit, dass ich das Teil ohne Warnung und Fehler initialisieren kann?

Momentan sieht es wie folgt aus:
typedef struct{
mmu_table_type_t* table_type;
mmu_flag_t* single_flags[];
mmu_flag_t* combined_flags[];
uint32_t         single_flags_no;
uint32_t         combined_flags_no;
}mmu_features_t;

Und der Fehler:
Fehler: flexibles Feld-Element nicht am Ende von struct

Wenn ich aus dem Array einen einfachen Pointer mache, geht es aber mit der Warnung, dass es eine Elementüberschreitung bei einer Skalarinitialisieren gibt.

Was kann ich machen damit das alles nicht mehr existiert?
47
OS-Design / APIC-Konfiguration
« am: 18. January 2010, 13:17 »
Hallo zusammen,

ich habe mal eine kurze Frage.
Kann man die APIC so konfigurieren, dass bestimmte IRQs nur an bestimmte CPUs geschickt werden?
Wie sieht das eigentlich aus wenn man mehrere identische Hardware hat?

Zum Beispiel.
Ein System hat mehr als eine Netzwerkkarte, bekommte jede Karte dann ihren eigenen IRQ oder teilen die sich einen?

Danke.

Gruß
rizor
48
Softwareentwicklung / Speicherkonflikte durch LD
« am: 06. January 2010, 22:05 »
Nabend zusammen,

ich habe ein Linker-Script bei dem ich am Ende den Speicher auf ein MB linke und ein Symbol für das Ende des Kernels erhalte.
Direkt danach lege ich meine Speicherverwaltung.
Nun ist mir aufgefallen, dass ein char* mit 1024 Einträgen über das Symbol des Kernels hinausreicht.
Woran kann das liegen?
Also das Symbol liegt auch wirklich am Ende des Scripts.
Ich bin momentan echt überfragt.
Der Linker legt das char* immer üer die grenze hinaus.
Egal ob ich den Kernel auf 4k aligne oder auf 1 MB.

Danke für eure Hilfe.

gruß
rizor
49
Lowlevel-Coding / linker findet libgcc-methoden nicht
« am: 23. October 2009, 18:01 »
Nabend zusammen,

ich habe mal wieder ein Problem mit der libgcc.
LD meldet folgende Fehler:
/home/rizor/Desktop/projects/os-development/trunk/libc/libc.lib(printf.c.o): In function `printf_value':
/home/rizor/Desktop/projects/os-development/trunk/libc/src/printf.c:213: undefined reference to `__umoddi3'
/home/rizor/Desktop/projects/os-development/trunk/libc/src/printf.c:214: undefined reference to `__udivdi3'
/home/rizor/Desktop/projects/os-development/trunk/libc/src/printf.c:312: undefined reference to `__stack_chk_fail'

Ich binde die libgcc mit ein.
Der Code, der diese Fehler wirft sieht wie folgt aus:
div64(val , args->base , &rest);
div64:
__asm__("div %%ecx\n\t"
"xchg %%ebx, %%eax\n\t"
"div %%ecx\n\t"
"xchg %%edx, %%ebx"
: "=A"(quot), "=b"(r)
: "a"(high), "b"(low), "c"(y), "d"(0)
);

if (rest)
*rest = r;

Der Stack_chk_fail wird einfach durch ein return retval ausgelöst.
retval ist ein int, der immer wieder hochgezählt wird

Den Fehler finde ich leider nicht
50
Lowlevel-Coding / circular dependency
« am: 21. October 2009, 10:56 »
Hi zusammen,

ich habe mit mingw ein kleines Problem.
Beim Kompilieren meldet mingw32-gcc, dass eine Ring-Abhängigkeit bei einer einzigen Datei gibt.
mingw32-make[1]: Circular _start.S <- _start.S.o dependency dropped.
Die Datei ist wie folgt aufgebaut:
#ifdef ARCH_X86
#ifdef MB_YES
.section multiboot
#define MB_MAGIC 0x1badb002
#define MB_FLAGS 0x0
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)

// the multiboot-header
.align 4
.int    MB_MAGIC
.int    MB_FLAGS
.int    MB_CHECKSUM
#endif /* MB_YES */

.section .text
.extern kernel

.global _start
_start:
mov $krn_stack , %esp
//cover the stack (wrong ret-jmps)
push 0
push 0
mov %esp , %ebp

#ifdef MB_YES
//prepare the multiboot-informations to use them as parameters
push %ebx
push %eax
#endif /* MB_YES */

call kernel
cli
hlt

.section .bss
.space 8192
krn_stack:

#endif /* ARCH_X86 */

Und so wird der GCC aufgerufen:
gcc -m32 -march=i386 -DARCH_X86 -DCPU_NR_1 -DMB_YES -I$(KERNEL)\include -I$(LIBC)\include -I$(LIBRIZOR)\include -LE:\MinGW\lib\gcc\mingw32\4.4.0\libgcc.a -L$(LIBC)\libc.lib -L$(LIBRIZOR)\librizor.lib -c -o $(KRN_TMP)\_start.S.o _start.S
Ich sehe keine Abhängigkeiten.

Woran kann das liegen, dass er den Fehler meldet?

Gruß
rizor
51
Offtopic / Visual Studio 2008
« am: 14. October 2009, 19:36 »
Nabend zusammen,

ich habe mir mal auf meinem Rechner das Visual Studio 2008 Professional installiert.
Nun wollte ich es für die LowLevel-Entwicklung verwenden, habe aber leider festgestellt, dass der Compiler keine Möglichkeit bietet einfache ELF-Files zu erstellen.
Gibt es Flags oder Add-Ons, die es möglich machen, dass man VS08 auch OS-Dev fähig bekommt?

Gruß
rizor
52
Lowlevel-Coding / GRUB sagt Error 13
« am: 01. October 2009, 20:22 »
Nabend zusammen,

ich habe mal alles ein wenig umgeschrieben und schon meckert GRUB.
Kann den Fehler beim besten Willen aber nicht finden.

Mein Linker-Skript sieht wie folgt aus;
ENTRY(_start) /* the entry-method for the kernel */
OUTPUT_FORMAT(elf32-i386) /* the linked code is x86-code */

ALIGNMENT = 0x1000; /* the alignment for the linker-parts */
KERNEL_LMA = 0x100000; /* the loaded memory-address */
KERNEL_MMA = 0x100000; /* the mapped memory-address */
KERNEL_OFFSET = KERNEL_MMA - KERNEL_LMA; /* the offset between the mapped and the loaded address */

SECTIONS
{
. = KERNEL_MMA; /* load the kernel at KERNEL_MMA */
kernel_entry = .; /* the method for the loaded entry*/
kernel_virt_entry = . - KERNEL_OFFSET; /* the method for the virtual entry */

/* code-section and the read-only data from the c-code*/
.text : AT(ADDR(.text) - KERNEL_OFFSET)
{
*(.text)
*(.rodata)
}

/* initialized data */
.data ALIGN(ALIGNMENT) : AT(ADDR(.data) - KERNEL_OFFSET)
{
*(.data)
}

/* uninitialized data */
.bss : AT(ADDR(.bss) - KERNEL_OFFSET)
{
_sbss = .;
*(.bss)
*(COMMON)
_ebss = .;
}

. = ALIGN(ALIGNMENT); /* expand the kernel to a new ALIGNED address */

kernel_virt_end = . - KERNEL_OFFSET; /* the method for the virtual end */
kernel_end = .; /* the method for the loaded end*/

kernel_size = kernel_end - kernel_entry;/* the method for the size of the kernel */
}

Meine GCC-Flags so:
gcc -O0 -g -m32 -march=i386 -maccumulate-outgoing-args -fstrength-reduce -fomit-frame-pointer -finline-functions -fno-stack-protector -nostdinc -fno-builtin -I$(INC) -I$(ROOT)/rizor-libraries/libc/include -I$(ROOT)/rizor-libraries/librizor/include -L/usr/lib/gcc/i486-linux-gnu/4.3.3/libgcc.a -L$(BUILD)/libc.lib -L$(BUILD)/librizor.lib
Meine Linker-Flags so:
ld -I$(INC) -I$(ROOT)/rizor-libraries/libc/include -I$(ROOT)/rizor-libraries/librizor/include -T$(KERNEL)/config/linker_x86.ld -melf_i386

Ich kann den Fehler nicht finden.

Gruß
rizor
53
Offtopic / Ergebnisse von find in einer Variablen speichern
« am: 30. September 2009, 22:28 »
Nabend zusammen,

ich bin gerade dabei ein kleines Shell-Skript zu schreiben.
Ich lasse mit Hilfe von find eine Datei suchen.
Nun möchte ich die gefundene Datei in einer Variablen speichern.

Wie geht das?

Habe es einfach so gemacht:
variable=find....
Dann bekomme ich ein Permission denied

danke.

Gruß
rizor

EDIT:
Habe eine Möglichkeit gefunden.
Dabei ist mir aufgefallen, dass find den gesamten Pfad ausgibt.
Kann ich mir auch nur den gefundenen Dateinamen ausgeben lassen?
54
OS-Design / Booten ohne Multiboot-header
« am: 29. September 2009, 20:11 »
Nabend zusammen,

ich habe mir überlegt, dass ich den Kernel nicht nur auf Multiboot-Bootloader optimieren möchte.
Habe mir dafür mal überlegt, was ich da alles beachten muss.
1. Speicher für die Hardware beachten
2. Speicher durch geladenen Kernel beachten
3. Wichtige Module mit in den Kernel linken. z.B. FS-Treiber

Auf was muss ich sonst noch so achten?
Gibt es eine Liste, die angibt welche Speicherbereiche reserviert werden müssen?

Danke.

Gruß
rizor
55
Softwareentwicklung / Makefile mit Parametern
« am: 18. September 2009, 10:30 »
Hallo zusammen,

ich bin gerade dabei meine Makefiles zu erweitern, um bedingtes Compiling hinzubekommen.
Wie kann ich die eingaben verarbeiten?
Mein Aufruf sieht wie folgt aus:
make ARCH_I386=1 all
Nun sollen in dem Makefile die Compiler-Flags angepasst werden.
Das habe ich mit ifdef gemacht.

ifdef ARCH_I386
      KRN_GCC += -march=i386 -m32
      KRN_LD += -melf_i386
   else
      echo "No architecture-flag found. Using ARCH_I386"
      KRN_GCC += -march=i386 -m32
      KRN_LD += -melf_i386
   endif

Leider sagt make, dass es das nicht gibt.
Wie sieht der Befehl denn genau aus?

Gruß
rizor
56
Lowlevel-Coding / bibliotheken mitlinken
« am: 04. September 2009, 21:07 »
Nabend zusammen,

ich habe mir für meinen Kernel drei Bibliotheken geschrieben.
Einmal die normale stdlibc, dann noch eine bibliothek mit listen und eine bibliothek für mein OS.
Wenn ich mit der stdlibc arbeite, funktioniert alles.
Nun wollte ich meine Liste verwenden und sobald ich versuche eine Liste zu initialisieren,  wird ein GPF geworfen.
Habe mir das qemu-log angeschaut. der GPF wird als einzige Exception geworfen.
Die Liste arbeitet auch mit der stdlibc.
Muss ich die irgendwie beim linken der Listen-Bibliothek (AR-Befehl) die stdlibc mit einbauen?

Gruß
rizor

EDIT:
Mir fällt grad auf, dass es eher Offtopic ist.
Also bitte einmal verschieben.
Danke und Sorry ;)
57
Offtopic / Binäruhr
« am: 13. August 2009, 18:17 »
Hallo zusammen,

hat einer von ecuh schon einmal eine Binäruhr gebaut?
Ich habe im Inet ein paar Schaltpläne gefunden, die mit PICs und Schiebergister arbeiten.
Am liebsten würde ich eine mit einem ARM-Prozessor bauen.
Habe aber leider keine Ahnung wie ich mit dem ARM LEDs ansteuern kann.

Hat einer von euch sowas in der Art schon mal gemacht?

Habe zwar schon mal LEDs angesteuert, da stand aber schon das eingebettete System.

Gruß
rizor
58
Lowlevel-Coding / malloc und free
« am: 13. August 2009, 12:37 »
Hallo zusammen,

ich bin gerade dabei meine Speicherverwaltung umzuschreiben.
Habe bisher ein malloc und ein kmalloc.
Das ist mir aber zu kompliziert.
Am liebsten hätte ich einfach ein malloc aus der stdlibc, leider habe ich jetzt nur ein Problem.
Ich muss dann ja zwischen Kernel und Userspace unterscheiden.
Wie kann ich das am besten machen?
Ich möchte malloc nicht immer erst einen syscall ausführen lassen um zu wissen in welchem Adressraum man ist.
Eine zusammenhängende Freispeicherliste zwischen Kernel und Userspace ist genau so bescheiden...

Habt ihr da eine Idee?

gruß
rizor
59
Nabend zusammen,

mir ist aufgefallen, dass mein GDT nicht richtig war, wodurch das mit dem TSS nicht richtig geklappt hat.
Nun habe ich den GDT ein wenig umgeschrieben, allerdings bekomme ich erst eine DPF und dann einen GPF.
Das Problem tritt auf, wenn ich den GDT update.

Der Code sieht wie folgt aus:
//memset(&GDT , 0 , GDT_SIZE * sizeof(struct gd_table));
gdt_set_gate(1, 0, 0xFFFFF, GDT_SEGMENT | GDT_PRESENT | GDT_CODE , GDT_RING_0);        // Kernel code
gdt_set_gate(2, 0, 0xFFFFF, GDT_SEGMENT | GDT_PRESENT | GDT_DATA , GDT_RING_0);        // Kernel data
gdt_set_gate(3, 0, 0xFFFFF, GDT_SEGMENT | GDT_PRESENT | GDT_CODE , GDT_RING_3);        // User code
gdt_set_gate(4, 0, 0xFFFFF, GDT_SEGMENT | GDT_PRESENT | GDT_DATA , GDT_RING_3);        // User data
puts("set up gates");

gdt_set_gran_bit(5 , (uint32_t)&krn_tss , sizeof(krn_tss) - 1 , GDT_PRESENT | GDT_TSS, GDT_RING_3);
puts("\nset up granularity");

gdt_update();

gdt_update sieht wie folgt aus:
/* Defines the Pointer to a GDT entry */
struct gdt_ptr{
uint16_t limit;
    uint32_t base;
} __attribute__((packed)) gp = {
.limit  = sizeof(struct gd_table)*GDT_SIZE - 1,
.base  = (uint32_t)&GDT,
};

  __asm__("lgdtl %0\n\t"
  "ljmpl $0x08, $1f\n\t"
  "1:\n\t"
  "mov $0x10, %%eax\n\t"
  "mov %%eax, %%ds\n\t"
  "mov %%eax, %%es\n\t"
  "mov %%eax, %%fs\n\t"
  "mov %%eax, %%gs\n\t"
  "mov %%eax, %%ss\n\t" : : "m" (gp) : "eax");

gdt_set_gate und gdt_set_gran_bit sehen wie folgt aus:
void gdt_set_gate(uint8_t num , uint32_t base , uint32_t limit , uint8_t access , uint8_t priv){
if(num < GDT_SIZE){
GDT[num].limit_low = (limit & 0xFFFF);
GDT[num].flags = ((limit >> 16) & 0x0F);
GDT[num].base_low = (base & 0xFFFF);
GDT[num].base_middle = (base >> 16) & 0xFF;
GDT[num].base_high = (base >> 24) & 0xFF;
GDT[num].access = access | ((priv & 3) << 5);
}
else
panic("Tried to set a wrong GDT-Gate.");
}

void gdt_set_gran_bit(uint8_t num , uint32_t base , uint32_t limit , uint8_t access , uint8_t priv){
gdt_set_gate(num , base , limit , access , priv);
GDT[num].flags = ((limit >> 16) & 0x0F) | 0x40;
}

Mein GDT sieht wie folgt aus:
struct gd_table{
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t access;
uint8_t flags;
uint8_t base_high;
};

seht ihr den fehler?
Die Definitionen bei gdt_set_gate und gdt_set_gran_bit sind richtig.
Die habe ich kontrolliert.

Danke für eure Hilfe.
60
Lowlevel-Coding / Division by Zero fällt Qemu nicht auf
« am: 17. April 2009, 23:20 »
Nabend zusammen,

ich habe ein für mich unerklärliches Problem.
Nachdem ich nun Multitasking implementiert habe, wollte ich das ganze mal testen.
Nach der erfolgreichen Initialisierung wird eine Division by Zero Exception von meinem System gefunden.
Wenn ich allerdings die Interrupts abschalte, dann passiert nichts.
Müsste dann nicht Qemu ein Problem finden?
Habe in meinem Code auch keinen Fehler gefunden.

Die Excpetion wird auch erst nach dem Bootvorgang geworfen, wenn der Kernel in einer Endlosschleife läuft.

Woran kann das liegen?

PS:
Könnte es sein, dass TSS falsch gesetzt wurde?
Hier mal der Code:
gdt_set_gate(3, (uint32_t)&krn_tss, (uint32_t)(&krn_tss + sizeof(tss_t)), 0x89, 0xCF);
gdt_update();

// create the kernel-interrupt-stack
uint32_ptr krn_stack = (uint32_ptr)((uint32_t)alloc_kernel(1) + 4096);
*--krn_stack = 0x0202; //EFLAGS
*--krn_stack = 0x08;   //CS
*--krn_stack = (uint32_t)int_dispatcher; //EIP
*--krn_stack = 0; //EDI
*--krn_stack = 0; //ESI
*--krn_stack = 0; //EBP
*--krn_stack = 0; //Just an offset, no value
*--krn_stack = 0; //EBX
*--krn_stack = 0; //EDX
*--krn_stack = 0; //ECX
*--krn_stack = 0; //EAX
// data segments pushed by IRQ handler
*--krn_stack = 0x10; //DS
*--krn_stack = 0x10; //ES
*--krn_stack = 0x10; //FS
*--krn_stack = 0x10; //GS

krn_tss.ss0 = SYSTEM_DATA_SELECTOR;
krn_tss.esp0 = (uint32_t)krn_stack;
Stimmt daran was nicht?
int_dispatcher ist eine Funktion, die direkt nach der Int-No-Feststellung und der Erstellung des CPU-Image aufgerufen wird und dann entscheided, ob es ein ISR/IRQ/Syscall ist und den dementsprechenden Handler aufruft.
Seiten: 1 2 [3] 4

Einloggen