I/O Problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Ben Hsu

I/O Problem

Post by Ben Hsu »

Hello,
I've posted a problem with my printf() and
haven't heard any response so I skipped printf()
and begin initializing the system by enabling A20,
implementing other input functions like getch().
My initializer is jump by doing the following:

; transfer control to kernel setup program
mov ax,0x4000
mov es,ax
mov ds,ax
cli
mov ss,ax
mov sp,0x0000
sti
push ax
mov ax,0
push ax
retf

The targeted code is then written with DJGPP gcc using
-ffreestanding and linked with other assembly and
gcc pieces compiles as coff.
I've implemented some simple I/O function as cli(),sti(),
iret(),putc(),puts(), and getc(). But for some reason
all output is ok and all input gives me forever loops
when booting. I tried the codes on Bochs, and it gave
me an error message of trying to output to port 0x00000083
with a value of 0x02. Sometimes it gave me an error
code with CS.limit>(a number, which I think is 64k or something like that).

After skipping most of the keyboard input stuff, I then
begin thinking of trying to get my memory design started
with A20, but then I discoveed that all outputs with
outb or inb is not really working and they all give
an error message of output to port 0x00000082 (somewhere close to this port)
and with the value 0x02. Is there anything that have
to be done before the c code can come in and take over?
Because it seemed to me that I need to setup something before
the C code function properly.

There is a CVS and download copy of the codes mentioned above at
http://zoftos.sf.net/ , the CVS is the newest with
the printf() and several new I/O I've just implemented.
The download version is a booting version that does not
have all the I/O implemented. I've written the compilation
procedures in DOS batch files, and nasm, gcc, and partcopy is
required to do compilation. Meanwhile, I'll be trying
out going into pmode and intializes A20 with assembly
before jumping into the C code and see what happens.

Any comment or help is appreciated, Thanks!

Ben Hsu
Guest

RE:I/O Problem

Post by Guest »

>On 2001-12-30 20:30:40, Ben Hsu wrote:
>Meanwhile, I'll be trying
>out going into pmode and intializes A20 with assembly
>before jumping into the C code and see what happens.
Yes, you'll need to do this. Any binary produced
by gcc is 32-bit and requires your operating
system be in 32 bit protected mode.
PS - About the CS limit problem: your code
is greater than 64k! You'll either need to slim
down your code, or (assuming you're writing this
in asm) break your code up and make sure that any
code beyond the 64k (this is the maximum segment size
in 16 bit real mode) is only accessed with a far
branch (jmp [seg:offset]). Hope this helps!
Ben Hsu

RE:I/O Problem

Post by Ben Hsu »

>Yes, you'll need to do this. Any binary produced
>by gcc is 32-bit and requires your operating
>system be in 32 bit protected mode.

Does that applies even if I compiled the kernel using:

gcc -c --ffreestanding -o kinit.o kinit.c

And then the object files from the assembly codes and this
kernel piece is linked using:

ld --oformat=binary -o kernel.bin kinit.o putc.o ...

And the since the target file is in binary format,
and I can load this without going into pmode...

But the problem is that whenever any input from anything
or specifically outputing to a port the code doesn't
run, but just do a foverloop from the very top of the
module. Does that relates to the 32-bit coding problem?

Thanks.

Ben Hsu
J. Weeks

RE:I/O Problem

Post by J. Weeks »

>On 2001-12-31 15:45:43, Ben Hsu wrote:
>>Yes, you'll need to do this. Any binary produced
>>by gcc is 32-bit and requires your operating
>>system be in 32 bit protected mode.
>
>Does that applies even if I compiled the kernel using:
>
>gcc -c --ffreestanding -o kinit.o kinit.c

Yes. DJGPP _will not_ produce 16-bit real mode
code. Due to the nature of intel assembly, the
instruction "mov ax, stuff" in real mode, is a
16 bit instruction, unless prefixed with 0x66 (?).
The reverse is true for pmode. A compiler _has_
to be built assuming one of these is true...
djgpp assumes the latter (ie, default to 32 bit code
unless segment/register size prefix is used).

If this code were to be run in 16-bit real mode, it
wouldn't work properly.

>And the since the target file is in binary format,
>and I can load this without going into pmode...

Nope. You _could_ LOAD it in real mode, but you
couldn't execute it from real mode (UNLESS your
assembly language stub enters pmode...)

>But the problem is that whenever any input from anything
>or specifically outputing to a port the code doesn't
>run, but just do a foverloop from the very top of the
>module. Does that relates to the 32-bit coding problem?

I have no idea what you're talking about... :)

Jeff
Ben Hsu

RE:I/O Problem

Post by Ben Hsu »

>On 2001-12-31 16:39:01, J. Weeks wrote:
>I have no idea what you're talking about... :)

I don't recognize that either, but thanks.

Ben Hsu
Schol-R-LEA

RE:I/O

Post by Schol-R-LEA »

>On 2001-12-31 15:45:43, Ben Hsu wrote:

You might want to look at the printf() thread again. I tried to answer your questionas best as possible.

>And the since the target file is in binary format,
>and I can load this without going into pmode...
>
>But the problem is that whenever any input from anything
>or specifically outputing to a port the code doesn't
>run, but just do a foverloop from the very top of the
>module. Does that relates to the 32-bit coding problem?

I am assuming that you meant 'forever loop'.

OK, first things first:

1) Are you using gcc inline assembly to code the
functions?

2) Are using BIOS interrupts to implement the functions?

3) Are you in real mode when the calls are made, or have you switched to p-mode already? (side question: did you set A20 on *before* starting p-mode, or *after*? This is crucial, as the memory management hardware will go berserk if high memory isn't opened before p-mode is set).

4) Are you setting up the GDT and IDT for the task correctly, with all the interrupt vectors handled?

From the sounds of it, you're I/O functions are GCC inlines, but call one of the int 0x10 BIOS vectors to do the actual work. This is No Good, no matter how you handle it. If you're in real mode, and the 32-bit gas code will cause the CPU to gag, while if your in p-mode, and the interrupt call will go into never-never land because the vectors weren't set - or else, it somehow did call the BIOS routine, which, being non-reentrant 16-bit real mode code, will cause a GPF. Either way, your SOL.

The solution is to a) use NASM for your assembly code, and explicitly [set bits 16] and [set bits 32] as appropriate; b) don't use *any* C/C++ code until you are safely in p-mode; c) write your own 32-bit I/O code; and d) don't *ever* call the BIOS routines from anything that runs after you've set p-mode.
Ben Hsu

RE:I/O

Post by Ben Hsu »

>On 2002-01-09 17:17:40, Schol-R-LEA wrote:
>>On 2001-12-31 15:45:43, Ben Hsu wrote:
>
>You might want to look at the printf() thread again. I tried to answer your questionas best as possible.
>
>>And the since the target file is in binary format,
>>and I can load this without going into pmode...
>>
>>But the problem is that whenever any input from anything
>>or specifically outputing to a port the code doesn't
>>run, but just do a foverloop from the very top of the
>>module. Does that relates to the 32-bit coding problem?
>
>I am assuming that you meant 'forever loop'.
>
>OK, first things first:
>
>1) Are you using gcc inline assembly to code the
>functions?
no, i've tried that last year...doesn't work

>2) Are using BIOS interrupts to implement the functions?
no, i don't use BIOS funtions...i write the I/O functions with NASM and link them with ld to my
kernel setup program

>3) Are you in real mode when the calls are made, or have you switched to p-mode already? (side question: did you set A20 on *before* starting p-mode, or *after*? This is crucial, as the memory management hardware will go berserk if high memory isn't opened before p-mode is set).
i'm in real mode with A20 enabled at this point,
but i'm writing my pmode code now...

>4) Are you setting up the GDT and IDT for the task correctly, with all the interrupt vectors handled?
from #3, not yet...

>From the sounds of it, you're I/O functions are GCC inlines, but call one of the int 0x10 BIOS vectors to do the actual work. This is No Good, no matter how you handle it. If you're in real mode, and the 32-bit gas code will cause the CPU to gag, while if your in p-mode, and the interrupt call will go into never-never land because the vectors weren't set - or else, it somehow did call the BIOS routine, which, being non-reentrant 16-bit real mode code, will cause a GPF. Either way, your SOL.
hm... sounds interesting...that may be the problem
i'm going to write the pmode initialization code
and see what happens with the same code.

>The solution is to a) use NASM for your assembly code, and explicitly [set bits 16] and [set bits 32] as appropriate; b) don't use *any* C/C++ code until you are safely in p-mode; c) write your own 32-bit I/O code; and d) don't *ever* call the BIOS routines from anything that runs after you've set p-mode.

I did use NASM
and I'll be careful not to use C/C++ at this level.

Thanks
Post Reply