OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Sep 16, 2019 10:21 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 33 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sat Jul 27, 2019 8:05 pm 
Online
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 478
This doesn't look right either:
Code:
gdt_entries[num].granularity |= granularity & 0x0F;
Maybe you meant:
Code:
gdt_entries[num].granularity |= granularity & 0xF0;


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sun Jul 28, 2019 5:25 am 
Offline

Joined: Mon Jul 01, 2019 10:46 am
Posts: 18
I've changed my code but still get trouble
Code:
#include <stdint.h>

struct gdt_entry {
    uint16_t limit_low;
    uint16_t base_low;
    uint8_t base_middle;
    uint8_t access;
    uint8_t granularity;
    uint8_t base_high;
};

struct gdt_ptr {
    uint16_t limit;
    uint32_t base;
};

void init_gdt();

extern void gdt_flush(uint32_t);
static void gdt_set_gate(int32_t,uint32_t,uint32_t,uint8_t,uint8_t);

struct gdt_entry gdt_entries[5];
struct gdt_ptr gdt_ptr;

void init_gdt() {
    gdt_ptr.limit = (sizeof(struct gdt_entry) * 5) - 1;
    gdt_ptr.base = (uint32_t)&gdt_entries;
    gdt_set_gate(0,0,0,0,0);
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
    gdt_flush((uint32_t)&gdt_ptr);
}

static void gdt_set_gate(int32_t num,uint32_t base,uint32_t limit,
uint8_t access,uint8_t granularity) {
    gdt_entries[num].base_low = (base & 0xFFFF);
    gdt_entries[num].base_middle = (base >> 16) & 0xFF;
    gdt_entries[num].base_high = (base >> 24) & 0xFF;

    gdt_entries[num].limit_low = (limit & 0xFFFF);
    gdt_entries[num].granularity = (limit >> 16) & 0x0F;

    gdt_entries[num].granularity |= granularity & 0xF0;
    gdt_entries[num].access = access;
}


i hope you can look my source code: https://github.com/Ananta98/OSdev. I hope you know this trouble.


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sun Jul 28, 2019 6:42 am 
Online
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 478
Now that you have a project it is much easier to help. Your final issue is this:
Code:
struct gdt_ptr {
    uint16_t limit;
    uint32_t base;
};
Because GCC is by default using natural alignment for placing data in structures. It has added padding between limit and base to align base (a 32-bit value) on a 32-bit (4 byte) boundary. To change that behavior you will need to tell GCC to pack the structure:
Code:
struct gdt_ptr {
    uint16_t limit;
    uint32_t base;
} __attribute__((packed));


Last edited by MichaelPetch on Sun Jul 28, 2019 8:00 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sun Jul 28, 2019 6:58 am 
Offline

Joined: Mon Jul 01, 2019 10:46 am
Posts: 18
Thank you Petch it works


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Mon Jul 29, 2019 7:22 am 
Offline

Joined: Mon Jul 01, 2019 10:46 am
Posts: 18
I want to ask there is interrupt no 65536. If there is no interrupt 65536 what's wrong with mycode ???

idt.c
Code:
#include <stdint.h>
#include "../../include/string.h"
struct idt_entry {
    uint16_t base_low;
    uint16_t selector;
    uint8_t always_zero;
    uint8_t flags;
    uint16_t base_high;
}__attribute__((packed));

struct idt_ptr {
    uint16_t limit;
    uint32_t base;
}__attribute__((packed));

struct idt_ptr idt_ptr;
struct idt_entry idt_entries[256];
extern void idt_flush(uint32_t);
static void idt_set_gate(uint8_t,uint32_t,uint16_t,uint8_t);
void init_idt();

extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();


void init_idt() {
    idt_ptr.limit = sizeof(struct idt_entry) * 256 - 1;
    idt_ptr.base = (uint32_t)&idt_entries;
    memset(&idt_entries,0,sizeof(struct idt_entry) * 256);
    idt_set_gate(1,(uint32_t)isr0,0x08,0x8E);
    idt_set_gate(2,(uint32_t)isr2,0x08,0x8E);
    idt_set_gate(3,(uint32_t)isr3,0x08,0x8E);
    idt_set_gate(4,(uint32_t)isr4,0x08,0x8E);
    idt_set_gate(5,(uint32_t)isr5,0x08,0x8E);
    idt_set_gate(6,(uint32_t)isr6,0x08,0x8E);
    idt_set_gate(7,(uint32_t)isr7,0x08,0x8E);
    idt_set_gate(8,(uint32_t)isr8,0x08,0x8E);
    idt_set_gate(9,(uint32_t)isr9,0x08,0x8E);
    idt_set_gate(10,(uint32_t)isr10,0x08,0x8E);
    idt_set_gate(11,(uint32_t)isr11,0x08,0x8E);
    idt_set_gate(12,(uint32_t)isr12,0x08,0x8E);
    idt_set_gate(13,(uint32_t)isr13,0x08,0x8E);
    idt_set_gate(14,(uint32_t)isr14,0x08,0x8E);
    idt_set_gate(15,(uint32_t)isr15,0x08,0x8E);
    idt_set_gate(16,(uint32_t)isr16,0x08,0x8E);
    idt_set_gate(17,(uint32_t)isr17,0x08,0x8E);
    idt_set_gate(18,(uint32_t)isr18,0x08,0x8E);
    idt_set_gate(19,(uint32_t)isr19,0x08,0x8E);
    idt_set_gate(20,(uint32_t)isr20,0x08,0x8E);
    idt_set_gate(21,(uint32_t)isr21,0x08,0x8E);
    idt_set_gate(22,(uint32_t)isr22,0x08,0x8E);
    idt_set_gate(23,(uint32_t)isr23,0x08,0x8E);
    idt_set_gate(24,(uint32_t)isr24,0x08,0x8E);
    idt_set_gate(25,(uint32_t)isr25,0x08,0x8E);
    idt_set_gate(26,(uint32_t)isr26,0x08,0x8E);
    idt_set_gate(27,(uint32_t)isr27,0x08,0x8E);
    idt_set_gate(28,(uint32_t)isr28,0x08,0x8E);
    idt_set_gate(29,(uint32_t)isr29,0x08,0x8E);
    idt_set_gate(30,(uint32_t)isr30,0x08,0x8E);
    idt_set_gate(31,(uint32_t)isr31,0x08,0x8E);
    idt_flush((uint32_t)&idt_ptr);
}

static void idt_set_gate(uint8_t num,uint32_t base,uint16_t selector,uint8_t flags) {
    idt_entries[num].base_low = base & 0xFFFF;
    idt_entries[num].base_high = (base >> 16) & 0xFFFF;
    idt_entries[num].selector = selector;
    idt_entries[num].always_zero = 0;
    idt_entries[num].flags = flags | 0x60;
}


idt.s
Code:
.section .text
.align 4

.global idt_flush
.type idt_flush, @function

idt_flush:
    mov 4(%esp),%eax
    lidt (%eax)
    ret


interrupt.s
Code:
.section .text
.align 4

.macro ISR_NOERR index
    .global isr\index
    isr\index:
        cli
        push $0
        push $\index
        jmp isr_common
.endm

.macro ISR_ERR index
    .global isr\index
    isr\index:
        cli
        push $\index
        jmp isr_common
.endm

ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR   8
ISR_NOERR 9
ISR_ERR   10
ISR_ERR   11
ISR_ERR   12
ISR_ERR   13
ISR_ERR   14
ISR_NOERR 15
ISR_NOERR 16
ISR_NOERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_NOERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31
ISR_NOERR 127

.extern isr_handler
.type isr_handler, @function


isr_common:
    pusha

    /* Save segment registers */
    push %ds
    push %es
    push %fs
    push %gs
    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    cld


    push %esp
    call isr_handler
    add $4, %esp


    pop %gs
    pop %fs
    pop %es
    pop %ds


    popa

    add $8, %esp
    iret


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Mon Jul 29, 2019 8:10 am 
Online
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 478
I'm not sure what you are asking. The maximum number of interrupts supported in 32-bit protected mode is 8192. Each entry is 8 bytes so 65536/8=8192. You don't have to fill them all up. If your code is failing in some way you should update your github project. The one thing I do see is this:
Code:
    idt_set_gate(1,(uint32_t)isr0,0x08,0x8E);
    idt_set_gate(2,(uint32_t)isr2,0x08,0x8E);
    idt_set_gate(3,(uint32_t)isr3,0x08,0x8E);
    idt_set_gate(4,(uint32_t)isr4,0x08,0x8E);
    ...
    idt_set_gate(31,(uint32_t)isr31,0x08,0x8E);
Interrupt numbers start with 0 but you started with 1 (first parameter). Then for some reason you started with isr0 and skipped isr1. I'd expect it to look something like:
Code:
    idt_set_gate(0,(uint32_t)isr0,0x08,0x8E);
    idt_set_gate(1,(uint32_t)isr1,0x08,0x8E);
    idt_set_gate(2,(uint32_t)isr2,0x08,0x8E);
    idt_set_gate(3,(uint32_t)isr3,0x08,0x8E);
    ...
    idt_set_gate(31,(uint32_t)isr31,0x08,0x8E);


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Wed Jul 31, 2019 9:16 am 
Offline

Joined: Mon Jul 01, 2019 10:46 am
Posts: 18
I've got trouble especially pit.c (PIT doesn't work),paging.c and kheap.c what's wrong in my source code. If you can, you can also check all source code for idt and gdt. I hope you can help me. website github https://github.com/Ananta98/OSdev


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Fri Aug 02, 2019 10:56 am 
Offline
Member
Member

Joined: Thu Aug 13, 2015 4:57 pm
Posts: 369
MichaelPetch wrote:
The maximum number of interrupts supported in 32-bit protected mode is 8192. Each entry is 8 bytes so 65536/8=8192.


I thought there's only 256 interrupts?


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Fri Aug 02, 2019 10:59 am 
Offline
Member
Member

Joined: Thu Aug 13, 2015 4:57 pm
Posts: 369
Ananta96 wrote:
I want to ask there is interrupt no 65536. If there is no interrupt 65536 what's wrong with mycode ???

What does interrupt #65536 have to do with anything? And of course, if there's 65536 of something, since 0 is the first one, then the last is 65535, note the last digit. But beyond that, I don't really understand what you are talking about.

Also, it would be useful to explain what your problem is, instead of a "what's wrong"...

Ananta96 wrote:
I've got trouble especially pit.c (PIT doesn't work),paging.c and kheap.c what's wrong in my source code. If you can, you can also check all source code for idt and gdt. I hope you can help me. website github https://github.com/Ananta98/OSdev

What does "doesn't work" mean exactly? You should provide more specific details, explain what the problem is.

And try to do troubleshooting/debugging and tell what you found. If you haven't done debugging:
https://wiki.osdev.org/Kernel_Debugging
https://wiki.osdev.org/GDB


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sat Aug 03, 2019 1:59 am 
Offline

Joined: Mon Jul 01, 2019 10:46 am
Posts: 18
Now i want to debug assembly how because the code combination c and assembly? I've got trouble, when breakpoint set pc 0x0? how to solve it ?


Attachments:
Capture.PNG
Capture.PNG [ 31.13 KiB | Viewed 257 times ]
Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sat Aug 03, 2019 2:35 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3465
Location: Chichester, UK
You can't debug an individual object file like that. You have to load the linked executable and then the breakpoints will be set at the correct relocated addresses.


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sat Aug 03, 2019 2:57 am 
Offline

Joined: Mon Jul 01, 2019 10:46 am
Posts: 18
i want to know nasm command for debugging ?
And what's wrong my code in my gdt nasm version, I've got trouble guru meditation again

gdt.asm
Code:
section .text
align 4
global gdt_flush
gdt_flush:
    mov eax, [esp + 4]
    lgdt [eax]
    mov ax,0x10
    mov ds,ax
    mov es,ax
    mov fs,ax
    mov ss,ax
    mov gs,ax
    jmp 0x08:.flush
.flush:
    ret


gdtuser.h
Code:
#include <stdint.h>
struct gdt_entry {
    uint16_t base_low;
    uint16_t limit_low;
    uint8_t base_middle;
    uint8_t access;
    uint8_t granularity;
    uint8_t base_high;
} __attribute__((packed));

struct gdt_ptr {
    uint16_t limit;
    uint32_t base;
} __attribute__((packed));

void install_gdt();

extern void gdt_flush(uint32_t);
static void gdt_set_gate(int32_t,uint32_t,uint32_t,uint8_t,uint8_t);

struct gdt_entry gdt_entries[5];
struct gdt_ptr gdt_ptr;


gdt_user.c
Code:
#include "gdt_user.h"

void install_gdt() {
    gdt_ptr.limit = (sizeof(struct gdt_entry) * 5) - 1;
    gdt_ptr.base = (uint32_t)&gdt_entries;
    gdt_set_gate(0, 0, 0, 0, 0); 
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
    gdt_flush((uint32_t)&gdt_ptr);
}

static void gdt_set_gate(int32_t num,uint32_t base,
uint32_t limit,uint8_t access,uint8_t granularity) {
    gdt_entries[num].base_low = (base & 0xFFFF);
    gdt_entries[num].base_middle = (base >> 16) & 0xFF;
    gdt_entries[num].base_high = (base >> 24) & 0xFF;

    gdt_entries[num].limit_low = (limit & 0xFFFF);
    gdt_entries[num].granularity = (limit >> 16) & 0x0F;

    gdt_entries[num].granularity |= granularity & 0xF0;
    gdt_entries[num].access = access;
}


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Sat Aug 03, 2019 6:53 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3465
Location: Chichester, UK
It's clear from your previous post that you know that the command to debug an executable is "gdb".


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Thu Aug 08, 2019 12:21 am 
Offline

Joined: Mon Jul 01, 2019 10:46 am
Posts: 18
Sorry for inconvinient. I want to ask what's the problem of my code for paging. I've started from zero again because osdev in my github still alot got trouble. I've decided to learn osdev only in one directory in my laptop.

kheap.h
Code:
#include <stdint.h>
#include <stddef.h>

size_t kmalloc_int(size_t size,int align, size_t *phys);
size_t kmalloc_a(size_t size);
size_t kmalloc_p(size_t size,size_t *phys);
size_t kmalloc_ap(size_t size,size_t *phys);
size_t kmalloc(size_t size);


kheap.c
Code:
#include "kheap.h"
extern uint32_t end;
uint32_t placement_address = (uint32_t)&end;

size_t kmalloc_int(size_t size,int align, size_t *phys) {
    if (align == 1 && (placement_address & 0xFFFFF000)) {
        placement_address &= 0xFFFFF000;
        placement_address += 0x1000;
    }
    if (phys)
        *phys = placement_address;
    size_t tmp = placement_address;
    placement_address += size;
    return tmp;
}

size_t kmalloc_a(size_t size) {
    return kmalloc_int(size,1,0);
}

size_t kmalloc_p(size_t size,size_t *phys) {
    return kmalloc_int(size,0,phys);
}

size_t kmalloc_ap(size_t size,size_t *phys) {
    return kmalloc_int(size,1,phys);
}

size_t kmalloc(size_t size) {
    return kmalloc_int(size,0,0);
}




paging.h
Code:
#include <stdint.h>
#include "register.h"

struct page {
    uint32_t present : 1;
    uint32_t rw : 1;
    uint32_t user : 1;
    uint32_t accessed : 1;
    uint32_t dirty : 1;
    uint32_t unused : 7;
    uint32_t frame : 20;
};

struct page_table {
    struct page pages[1024];
};

struct page_directory {
    struct page_table *tables[1024];
    uint32_t tablesPhysical[1024];
    uint32_t physicalAddr;
};

void initialise_paging();
void switch_page_directory(struct page_directory *new);
struct page *get_page(uint32_t address,int make,struct page_directory *dir);
void page_fault(struct regs *regs);


paging.c
Code:
#include "paging.h"
#include "stdio.h"
#include "kheap.h"
#include "irq_user.h"

uint32_t *frames;
uint32_t nframes;

struct page_directory *kernel_directory = 0;
struct page_directory *current_directory = 0;

extern uint32_t placement_address;

#define INDEX_FROM_BIT(a) (a/(8*4))
#define OFFSET_FROM_BIT(a) (a%(8*4))

static void set_frame(uint32_t frame_addr) {
    uint32_t frame = frame_addr / 0x1000;
    uint32_t idx = INDEX_FROM_BIT(frame);
    uint32_t off = OFFSET_FROM_BIT(frame);
    frames[idx] |= (0x1 << off);
}

static void clear_frame(uint32_t frame_addr) {
    uint32_t frame = frame_addr / 0x1000;
    uint32_t idx = INDEX_FROM_BIT(frame);
    uint32_t off = OFFSET_FROM_BIT(frame);
    frames[idx] &= ~(0x1 << off);
}

static uint32_t test_frame(uint32_t frame_addr) {
    uint32_t frame = frame_addr / 0x1000;
    uint32_t idx = INDEX_FROM_BIT(frame);
    uint32_t off = OFFSET_FROM_BIT(frame);
    return (frames[idx] & (0x1 << off));
}

static uint32_t fist_frame() {
    int i , j;
    for (i = 0; i < INDEX_FROM_BIT(nframes); i++) {
        if (frames[i] != 0xFFFFFFFF) {
            for (j = 0; j < 32; j++) {
                uint32_t test = 0x1 << j;
                if (!(frames[i] & test))
                    return i*4*8+j;
            }
        }
    }
}

void alloc_frame(struct page *page,int is_kernel,int is_writeable) {
    if (page->frame != 0)
        return;
    else {
        uint32_t idx = fist_frame();
        if (idx == (uint32_t)-1) {
           kprintf("No free frames\n");
           return;
        }
        set_frame(idx * 0x1000);
        page->present = 1;
        page->rw = (is_writeable) ? 1 : 0;
        page->user = (is_kernel) ? 0 : 1;
        page->frame = idx;
    }
}

void free_frame(struct page *page) {
    uint32_t frame;
    if (!(frame=page->frame))
        return;
    else {
        clear_frame(frame);
        page->frame = 0x0;
    }
}

void switch_page_directory(struct page_directory *dir) {
    current_directory = dir;
    asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
    uint32_t cr0;
    asm volatile("mov %%cr0, %0" : "=r"(cr0));
    cr0 |= 0x80000000;
    asm volatile("mov %0, %%cr0" :: "r"(cr0));
}

struct page *get_page(uint32_t address,int make,struct page_directory *dir) {
    address /= 0x1000;
    uint32_t table_idx = address / 1024;
    if (dir->tables[table_idx])
        return &dir->tables[table_idx]->pages[address % 1024];
    else if (make) {
        uint32_t tmp;
        dir->tables[table_idx] = (struct page_table*)kmalloc_ap(sizeof(struct page_table),&tmp);
        dir->tablesPhysical[table_idx] = tmp | 0x7;
        return &dir->tables[table_idx]->pages[address%1024];
    } else {
        return 0;
    }
}

void page_fault(struct regs *regs) {
    uint32_t faulting_address;
    asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
    int present = !(regs->err_code & 0x01);
    int rw = regs->err_code & 0x02;
    int us = regs->err_code & 0x04;
    int reserved = regs->err_code & 0x08;
    int id = regs->err_code & 0x10;
    kprintf("Page fault\n");
    if (rw) kprintf("Present\n");
    if (us) kprintf("User mode\n");
    if (reserved) kprintf("Reserved\n");
    kprintf("Address : %x\n",faulting_address);
}

void initialise_paging() {
    uint32_t mem_end_page = 0x1000000;
    nframes = mem_end_page / 0x1000;
    frames = (uint32_t*) kmalloc_a(INDEX_FROM_BIT(nframes));
    memset(frames,0,INDEX_FROM_BIT(nframes));
    kernel_directory = (struct page_directory*)kmalloc_a(sizeof(struct page_directory));
    memset(kernel_directory,0,sizeof(struct page_directory));
    current_directory = kernel_directory;
    int i = 0;
    while (i < placement_address) {
        alloc_frame(get_page(i,1,kernel_directory),0,0);
        i += 0x1000;
    }
    irq_install_handler(14,page_fault);
    switch_page_directory(kernel_directory);
}


Top
 Profile  
 
 Post subject: Re: Error compile GDT and Interrupt
PostPosted: Thu Aug 08, 2019 7:46 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3465
Location: Chichester, UK
"still alot got trouble" is not really a very clear description of your problem.

What are you expecting to happen?
What is actually happening?
What steps have you taken to solving the problem?
Have you run the code under a debugger, inspecting registers and memory structures to see if they fit with what you expect?

Juat posting a lot of code and saying "it doesn't work" is unlikely to elicit useful responses.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 33 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], MichaelPetch, proxy and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group