Page 2 of 2

Re: Can somebody tell me if this ASM is ok ?

Posted: Fri Nov 08, 2013 1:46 pm
by Luca91
Good evening Mike!
Still many thanks for the help :)
So:

- No error or warning during compilation
- Since today I'm using bochs
- Here is my budilding script (full/written by me):

Code: Select all

#!/bin/sh

build=Build
compiler=i586-elf-gcc
linker=i586-elf-ld
opt="-Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./Include -c -fno-strict-aliasing -fno-common -fno-stack-protector"
isodir=A_isodir
isoname=OS.iso

echo "Setting Path..."
echo "==========="
export PATH="/opt/cross/bin:$PATH"

echo "Removing Old Files..."
echo "==========="
rm -r ./Build/*
rm kernel.bin
rm $isoname
rm ./A_isodir/boot/kernel.bin

echo "Building..."
echo "==========="
# Build C files

$compiler $opt -o $build/main.o ./Kernel/main.c 
$compiler $opt -o $build/string.o ./Lib/string.c 
$compiler $opt -o $build/stdio.o ./Lib/stdio.c 
$compiler $opt -o $build/DebugDisplay.o ./Kernel/DebugDisplay.c
$compiler $opt -o $build/stdint.o ./Include/stdint.c 
$compiler $opt -o $build/Hal.o ./Hal/Hal.c
$compiler $opt -o $build/cpu.o ./Hal/cpu.c
$compiler $opt -o $build/gdt.o ./Hal/gdt.c
$compiler $opt -o $build/idt.o ./Hal/idt.c
$compiler $opt -o $build/pic.o ./Hal/pic.c
$compiler $opt -o $build/pit.o ./Hal/pit.c
$compiler $opt -o $build/exception.o ./Kernel/exception.c
$compiler $opt -o $build/panic.o ./Kernel/panic.c


# Build ASM files
nasm -f elf ./Kernel/bootstrap.asm -o $build/bootstrap.o
nasm -f elf ./Hal/i86_pit_irq.asm -o $build/i86_pit_irq.o

# Link 
$linker -T linker.ld $build/*.o


# Copy the kernel to iso building dir and create our ISO file
cp kernel.bin $isodir/boot
grub-mkrescue -o $isoname $isodir

# Launch our OS on qemu or bochs
#qemu-system-i386 -cdrom $isoname
bochs
- Here is the asm file I'm using:

Code: Select all

global i86_pit_irq
align 4

extern   i86_pit_irq_c

i86_pit_irq:
    pusha
    call      i86_pit_irq_c
    popa
    iret
- C associated function:

Code: Select all

void i86_pit_irq_c(void){
	
	_pit_ticks++;
	interruptdone(0);
}
- Pit initializer C function

Code: Select all

void i86_pit_initialize(){

	setvect(32,i86_pit_irq);
	_pit_isinit = 1;

}
- BOCHS GIVE ME THIS ERROR:

Code: Select all

00017845491i[BIOS ] Booting from 07c0:0000
00025688379i[PIT81] Changing GATE 2 to: 0
00025688390i[PIT81] Changing GATE 2 to: 1
00025908095i[PIT81] Changing GATE 2 to: 0
00083333320e[CPU0 ] check_cs(0x0010): not a valid code segment !

Sorry for the so long post, but I'm tring to give as much informations as I can so you can try to help me.
In case, I can upload the full source on github ;)

EDIT: oh I forgot to say that I've to remove those underscore from asm because I can't compile the source with them !
EDIT2: Oh, also bochs instead of giving me default handler error, it give me kernel panic stop 13 (general protection fault)

Re: Can somebody tell me if this ASM is ok ?

Posted: Fri Nov 08, 2013 2:09 pm
by jnc100
Luca91 wrote:

Code: Select all

00083333320e[CPU0 ] check_cs(0x0010): not a valid code segment !
During an interrupt there are only two places where CS is changed: 1) when loading the new CS fron the particular IDT entry and 2) when performing an IRET (unless you explicitly change it yourself of course). I would look for errors in these two. Particularly, ensure that the segment selector in your IDT is appropriate and that the stack is in a coherent state prior to iret.

Both of these can be confirmed with the bochs debugger. You need to set a breakpoint at the appropriate points and use 'info idt' to examine the idt and 'print-stack' to print the stack.

Regards,
John.

Re: Can somebody tell me if this ASM is ok ?

Posted: Fri Nov 08, 2013 3:05 pm
by neon
Hello,

The labels in the ASM should be the C symbolic names of their respective functions in order for proper linking. I am intrigued how it can link without error without those underscores (assuming standard C name mangling.)

Unfortunately I cannot see if the current error is in the provided code. check_cs(0x0010) tells me that CS=DS which should never happen unless there is a stack problem or CS gets improperly loaded by the CPU due to improper system setup.

It might be helpful to post what you currently have and we can take a closer look at the IDT setup and initialization and make sure everything looks alright. I am not entirely convinced the error is in the provided code (absent of first note above.)

Oh, and Good evening. Hopefully we will get this one sorted out soon. :)

Re: Can somebody tell me if this ASM is ok ?

Posted: Fri Nov 08, 2013 3:17 pm
by Luca91
Okay, I've just sent you the source in pm. I'll upload the full source on github when this interrupt problem will be fixed.

uhm, also is possible that I've to add something to esp even if I used asm handler ? (James Molloy use to add 8 to esp in his tutorial, and he wrote interrupt handlers in asm)

EDIT: why codesel is 0x8 ? (is this because 0x8 is the exec code seg ?? I was able to undestood this some days ago, but now I forgot it)

EDIT2: Yep, it is the code selector in GDT :)

Re: Can somebody tell me if this ASM is ok ?

Posted: Fri Nov 08, 2013 3:47 pm
by neon
Am looking over it. :) You shouldn't need to directly modify esp. James articles appears to push additional data to the calling function (these are operands to that calling function) which would require cleanup. Your current code does not pass operands and so does not.

The code selector does not have to be 0x8. The only requirement as per the CPU manual is that entry 0 is always the null descriptor. We just selected entry 1 in the GDT as a "kernel mode 32 bit read-only executable" selector and entry 2 as "kernel mode read/write data" segment.

Re: Can somebody tell me if this ASM is ok ?

Posted: Mon Nov 11, 2013 1:43 pm
by Luca91
I'm still trying to figure this out... mmm ... It looks like that the cause is the iret......
Neon, any news from your side ? Still many thanks

Re: Can somebody tell me if this ASM is ok ?

Posted: Mon Nov 11, 2013 3:14 pm
by neon
Hello,

Unfortunately not yet. We were running the provided image file in the debugger and have found that the return CS for the interrupt call on the stack was indeed 0x10 which would cause the fault due to it being an invalid code segment. (This would cause it to crash on IRET.) As this was the return CS, we concluded that this value was erroneously set prior to the interrupt call which was triggered within some loop (can't give a function name since we don't have a linker map. If you would like to provide one however we can provide more information on our end.)

We should mention however that the IDT and GDT are both indeed correct and IDT[32] points to the correct assembly routine that which correctly calls your C function. This means the cause of the error is elsewhere and that everything was setup correctly here. If interested, the IDT[32].selector = 8 which is valid and would explain why the error only occurs on IRET.

We won't be able to continue the debugging session possibly until tomorrow. Please note that we are debugging the provided disk image rather then rebuilding the source thus no modifications have been made.

Re: Can somebody tell me if this ASM is ok ?

Posted: Mon Nov 11, 2013 3:24 pm
by Luca91
neon wrote:Hello,

Unfortunately not yet. We were running the provided image file in the debugger and have found that the return CS for the interrupt call on the stack was indeed 0x10 which would cause the fault due to it being an invalid code segment. (This would cause it to crash on IRET.) As this was the return CS, we concluded that this value was erroneously set prior to the interrupt call which was triggered within some loop (can't give a function name since we don't have a linker map. If you would like to provide one however we can provide more information on our end.)

We should mention however that the IDT and GDT are both indeed correct and IDT[32] points to the correct assembly routine that which correctly calls your C function. This means the cause of the error is elsewhere and that everything was setup correctly here.

We won't be able to continue the debugging session possibly until tomorrow. Please note that we are debugging the provided disk image rather then rebuilding the source thus no modifications have been made.

Thanks mike! Just one thing: I realized that in the asm file the last istruction is IRETD in the source that I've sent to you! Maybe you should change it to IRET.. ok ?

Re: Can somebody tell me if this ASM is ok ?

Posted: Mon Nov 11, 2013 3:34 pm
by neon
Hello,

Unfortunately, we can't modify the source and rebuild it due to a lack of compatible tool chain on our end. (Perhaps when the build system finally gets GCC support.) Its one of the reasons we encouraged providing the source for others on this forum as well that might have compatible build systems that might provide further help.

IRET is just expanded to either IRETW (if bits 16) or IRETD (if bits 32). If built in 32 bit mode, it should just expand to IRETD. Both forms pop CS, (E)IP, and (E)flags - only the amount of bytes popped are different. Thus changing it to IRET shouldn't make any difference. If it does then we may have found the problem.

Re: Can somebody tell me if this ASM is ok ?

Posted: Mon Nov 11, 2013 4:01 pm
by Luca91
Thus changing it to IRET shouldn't make any difference. If it does then we may have found the problem.
Sadly it doesn't make any difference :/

Re: Can somebody tell me if this ASM is ok ?

Posted: Thu Nov 14, 2013 4:19 pm
by Luca91
Good evening,
In the past 48h me and one of my tutors have spent a lot of hours debugging with bochs. I've also setup bochs to use the 0xE9 hack in order to print debug messages,
I can confirm that the interrupt is working, and that the C function is successfully called.
The system crash when IRET is executed.

Any news from your side Mike ?

Special thanks.


EDIT: NEON THIS IS IMPORTANT: can this problem be caused due to the fact that I'm using i586-elf-gcc (the version found on the wiki x86_64) to compile ??

Re: Can somebody tell me if this ASM is ok ?

Posted: Thu Nov 14, 2013 4:58 pm
by neon
Hello,

Apologies for the latness of this reply; we were not able to look into it until about two hours ago. Most of our time debugging was locating the entry point through stack back tracing on the image file. In doing so, we get this:

Code: Select all

00083278640i[CPU0 ] | RAX=000000002badb002  RBX=0000000000010000
00083278640i[CPU0 ] | RCX=0000000000000000  RDX=0000000000000000
00083278640i[CPU0 ] | RSP=000000000007fef8  RBP=0000000000000000
00083278640i[CPU0 ] | RSI=0000000000000000  RDI=0000000000000000
00083278640i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00083278640i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00083278640i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00083278640i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00083278640i[CPU0 ] | IOPL=0 ID vip vif ac vm rf nt of df if tf sf ZF af PF cf
00083278640i[CPU0 ] | SEG selector     base    limit G D
00083278640i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00083278640i[CPU0 ] |  CS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00083278640i[CPU0 ] |  DS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00083278640i[CPU0 ] |  SS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00083278640i[CPU0 ] |  ES:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00083278640i[CPU0 ] |  FS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00083278640i[CPU0 ] |  GS:0018( 0003| 0|  0) 00000000 ffffffff 1 1
00083278640i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00083278640i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00083278640i[CPU0 ] | RIP=0000000000100898 (0000000000100898)
00083278640i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00083278640i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
Although you install a new GDT using LGDT, the selector registers are never changed. That is, you need something like this after reloading a different GDT,

Code: Select all

   mov ax, 0x10
   mov ds, ax
   mov es, ax
   mov ss, ax
   mov fs, ax
   mov gs, ax
   jmp 8:flush_cpu
flush_cpu:
This step is important as all modern IA32 CPU's use a segment descriptor cache in order to avoid fetching GDT information from the in-memory table.

Please let us know if it works or causes more problems. We suspect it would also resolve the IRET error on interrupt return.

i586-elf-gcc is fine. IIRC its the version we used a long time ago.

Re: Can somebody tell me if this ASM is ok ?

Posted: Thu Nov 14, 2013 5:17 pm
by Luca91
IT WORKS !!!
Thank you mikeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee =D>

I've to admit, some days ago while re-reading one of your boot-stage tutorial I was thinking about that far jump, but since this is not explained in the kernel series I totally ignored this !

Well mate, you really rescued me :D

If I can suggest, please add that note to your tutorials, this can save a lot of headache to future os developers :)

Stil many many thanks ... Tomorrow I'll upload the kernel on github and I'll start to implement memory :)

Re: Can somebody tell me if this ASM is ok ?

Posted: Thu Nov 14, 2013 5:24 pm
by neon
Great to hear that it works! :D Sorry it took so long, just been so busy lately.

We plan an update to the articles soon so will be sure to add additional details on the segment descriptor caches. Thank you for the suggestion and the best of luck with your project! :)