Page 2 of 5
Posted: Tue Mar 20, 2007 6:27 pm
by neon
I tried your suggestions, still no go though
Heres the new _putch:
Code: Select all
void _putch (char c) {
unsigned char* vmem = (unsigned char*)VIDMEM;
//watch for newline
if (c=='\n' || c=='\r') {
_xPos=0;
_yPos++;
if (_yPos>LINES)
_yPos=0;
return;
}
// write the character
//*(vmem + (_xPos + _yPos * COLS) *2) = c & 0xFF;
//*(vmem + (_xPos + _yPos * COLS) *2+1) = ATTRIB;
vmem[((_xPos + _yPos * COLS) *2)] = c;
vmem[((_xPos + _yPos * COLS) *2+1)] = ATTRIB;
// watch for end of line
if (_xPos++ >COLS)
_putch ('\n');
}
It was worth a shot
For a small test, I modified _printf to look like this:
Code: Select all
void _printf (char* format) {
_putch ('A'); // works
_putch (*format); //prints null
_putch ('B'); // works
}
Heres a screenshot of the output:
http://img485.imageshack.us/my.php?image=textll1.jpg
As you can see from the image, There is a space between "A" and "B",
so I know a character *is* being printed--Its just an invisable character
though.
I dont see why this is though...
Posted: Tue Mar 20, 2007 6:49 pm
by frank
Have you tried checking what format points too?
Posted: Tue Mar 20, 2007 7:50 pm
by neon
Boschs debugger says it points to 0(null).
Please keep in mind, I am using the same _printf as before:
Because I am unable to select within the debugger, Ill
see if I can tell you the most important part (where _putch is called)
This is inside printf:
Code: Select all
; Here we push 0x41 (The first char that displays, ASCII 'A')
(0) [0x0000114d] 0008:0000114d (unk. ctxt): push 0x00000041 ; 6a41
; call _putch
(0) [0x0000114f] 0008:0000114f (unk. ctxt): call .+0xffffff4a (0x0000109e) ;e84affffff
; Right after code executes, "A" is displayed correctly.
; Now for the string from *format:
(0) [0x00001154] 0008:00001154 (unk. ctxt): add esp, 0x00000010 ;83c410
(0) [0x00001157] 0008:00001157 (unk. ctxt): sub esp, 0x0000000c ;83ec0c
; Push the pointer on the stack...
(0) [0x0000115a] 0008:0000115a (unk. ctxt): mov eax, dword ptr ss:[ebp+0x8] ;8b4508
(0) [0x0000115d] 0008:0000115d (unk. ctxt): movsx eax, byte ptr ds:[eax] ;0fbe00
(0) [0x0000115d] 0008:0000115d (unk. ctxt): movsx eax, byte ptr ds:[eax] ;0fbe00
; Actually push the pointer
(0) [0x00001160] 0008:00001160 (unk. ctxt): push eax;50
; call _putch (prints 0(null) because eax=0
(0) [0x00001161] 0008:00001161 (unk. ctxt): call .+0xffffff38 (0x0000109e) ;e838ffffff
Heres the reigisters *Right* before the second call to putch
(When we try to print from the ptr):
Code: Select all
eax: 0x0 < The character that is pushed and printed
ecx: 0x0
edx: 0x0
ebx: 0x1000
esp: 0x8ffc4
ebp: 0x8ffd8
esi: 0x7cc1
edi: 0xffde
eip: 0x1160
eflags: 0x12
cs: 0x8
ss: 0x10
ds: 0x10
es: 0x0
fs: 0x0
gs: 0x0
...Dont know why, but the seg registers dont look right to me..
(What do you think?)
Other then that, it looks right to me... Anyone notice anything
strange with the code?
...Mabey the ptr is getting
pushed incorrectly?
Or a stack problem?
Posted: Wed Mar 21, 2007 2:37 am
by Combuster
Code: Select all
(0) [0x0000115d] 0008:0000115d (unk. ctxt): movsx eax, byte ptr ds:[eax] ;0fbe00
(0) [0x0000115d] 0008:0000115d (unk. ctxt): movsx eax, byte ptr ds:[eax] ;0fbe00
huh?
You might have problems because ES != DS, but its not likely
also, a stack dump would be most welcome. (using print-stack)
Posted: Wed Mar 21, 2007 9:58 am
by frank
Are you sure that the function that calls printf is pushing the right pointer value on the stack? If format is null then somehow something not passing the correct pointer. Now keep in mind that I am not talking about the value of *format, I am just talking the value of format.
Posted: Wed Mar 21, 2007 10:58 am
by mystran
Ok, let's have some more questions:
How are you loading your kernel? It's binary, and at rather low address, so I guess you have a custom loader? And I assume you also somehow make sure your kernel entry get's called as the first thing (because obviously "ENTRY"-directive in linker script is pretty useless for binary format files)? If you are using a custom loader, are you sure it loads the whole kernel?
Posted: Wed Mar 21, 2007 5:40 pm
by neon
Heres the stack right before the call to _putch (within printf):
Code: Select all
0x0008ffc4 [0x00000000]
0x0008ffc8 [0x00000000]
0x0008ffcc [0x00000f00]
0x0008ffd0 [0x000b8000]
0x0008ffd4 [0x1f000000]
0x0008ffd8 [0x00008fffc]
0x0008ffdc [0x00001032]
0x0008ffe0 [0x00002008]
0x0008ffe4 through 0x0008fffc [0x0] (Always)
I have written a custom bootloader. I know its a low address,
I soon plan to enabe A20 (Its not enabled yet), and load it above
the bootloader (for alot of reasons)
As for loading the entire kernel...nope. atm, it only loads one sector.
I dont think this the problem tough, because I can make calls
to _putch inside of printf(), and it works just fine.. I can also add
additional code, and still works.
Unless Im missing something?
Heres the code that loads the kernel (Part of my bootloader)...
Code: Select all
; load second stage to 0:1000h ----------------
LoadStage2:
mov ax, 0
mov es, ax
mov bx, 1000h ; load stage2 at offset es:1000h (0:1000h)
;;; mov ax, 1 ; start reading from head 1 sector 0
mov ah, 02h
mov al, 02h
mov ch, 0
mov cl, 02h
mov dh, 0
int 13h
or ah, ah
jnz LoadStage2
;;; mov cx, 50 ; read 50 sectors
;;; call LoadSectors
At the moment, it only reads sector 1 (I was getting triple faults
when loading previosuly, so commented it out and tested with one
sector)
Here is where I jump to the stage 2 loader (I get a warning from
the linker reguarding not finding _Stage--Please see my other post for
details):
Code: Select all
;------------------------------------------ Enter: Protected Mode ---------
[BITS 32]
EnterStage2:
; setup 32bit registers
mov ax, 10h
mov ds, ax
mov ss, ax
mov esp, 90000h ; stack begins from 90000h
; stop floppy drive controller
xor al, al
mov dx, 03f2h ; port number
out dx, al
; jump to second stage bootloader (0:01000h)
jmp 08h:1000h
The bootloader isnt linked at all. Only the second stage (Which
*supposed* to be loaded at 08h:1000h). I only link
my stage2 with my C kernel.
(I am getting a warning from the linker not finding _Stage2 though
(Yet my OS executes fine). Please see my other post reguarding this...
Posted: Wed Mar 21, 2007 8:57 pm
by mystran
Ok, after basicly tracing the stack use, manually decoding the stranger instructions, tracing Bochs code to figure out if it parses it correctly, and generally banging my head, it seems there is indeed something strange going on...
Would you care to throw us an image off the kernel? Or even better, a floppy image that boots (and fails)? Would make it easier to try to see what could be wrong..
Posted: Wed Mar 21, 2007 9:07 pm
by mystran
One more stupid question, btw....
Your linker script says your target is 'binary' but your objdump is able to give you symbols? This sounds kinda strange to me... or are you using some other output format to get sane output from objdump?
Posted: Wed Mar 21, 2007 9:08 pm
by neon
We fixed one of my problems (My 2nd stage is being executed,
and I can define routines before main now)
Pointers still are not working though.
I attached the floppy image for my kernel, if you want to try it.
Posted: Wed Mar 21, 2007 9:09 pm
by mystran
attached where
Posted: Wed Mar 21, 2007 9:11 pm
by neon
I see--It wasnt accepting it because its a *.img file. I am going to compress it (*.zip), and try to upload it again.
Posted: Wed Mar 21, 2007 9:13 pm
by neon
Here it is
Posted: Wed Mar 21, 2007 9:16 pm
by neon
Your linker script says your target is 'binary' but your objdump is able to give you symbols? This sounds kinda strange to me... or are you using some other output format to get sane output from objdump?
I used objdump on my KERNEL.o object file, not the complete
image itself (It gives me "unsupported file format")
Posted: Wed Mar 21, 2007 9:31 pm
by mystran
Wait a second... you said your loader loads the first sector only? Your linker script on the other hand aligns all seconds 4096 bytes away from each other..... and isn't floppy sector quite small?
In a binary format file, the only way to get alignment would be to throw zeroes for padding, which means....
that if your pointer points to .data segment, and that segment is aligned to 4096 bytes, and your .text is aligned to 4096 bytes (or whatever) and you load the first 512 (or what a sector is) of your kernel, then your .text segment in the beginning of the file will all get loaded, while none of the .data fill..... and Bochs is kind enough to give you mostly zero-filled memory when you start it, which explains the "null"...