Page 3 of 5
Posted: Wed Mar 21, 2007 9:49 pm
by neon
That just might be it (Hope so..
)
I took the alignment out (Made my image 2kb), and am going to
try loading 50 sectors of my kernel. and post the results..
Posted: Wed Mar 21, 2007 10:11 pm
by neon
Still same problem (Ugh)
Heres my current linker script:
Code: Select all
ENTRY("0x00000000")
OUTPUT_FORMAT("binary")
SECTIONS
{
.text 0x1000 :
{
code = .; _code = .; __code = .;
*(.text)
}
.data :
{
data = .; _data = .; __data = .;
*(.data)
}
.rodata :
{
rodata = .; _rodata = .; __rodata = .;
*(.rodata)
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
}
end = .; _end = .; __end = .;
}
Im thinking its the way I load the kernel...
Code: Select all
;*******************************************************
; Read sectors from floppy into memory
; (ES:BX=>Buffer)
; CX=>Number of sectors to read
; AH=>Sector Number to begin reading from
; AL=>Head Number to begin reading from
;*******************************************************
LoadSectors:
pusha ; store registers...
mov dl, 12h
div dl
inc ah ; move to next sector (CL=sector number 1-63)
mov cl, ah
mov dh, al ; DH=head number
and dh, 01h
shr al, 1
mov ch, al
mov dl, 00h ; drive number (00h=floppy)
ReadSector:
mov ah, 02h
mov al, 01h ; number of sectors to read
int 13h
jc ReadSector ; CF is set if error by INT 13h
popa ; restore registers
add bx, 0200h
inc ax
loop LoadSectors ; loop until CX = 0
ret
;...This is in the main kernel code:
; 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 cx, 50 ; read 50 sectors
call LoadSectors
Posted: Thu Mar 22, 2007 2:46 pm
by frank
One floppy sector is always going to be 512 bytes. You should modify your bootsector to load more than one sector if possible. Maybe that will fix things.
Posted: Thu Mar 22, 2007 4:27 pm
by neon
The bootloader I posted loads 50 sectors. The pointer is still
null though..
Posted: Thu Mar 22, 2007 4:54 pm
by mystran
You could write (either in your bootloader or in you kernel) some sort of a checksummin routine to make sure you actually get what you expect..
If you don't feel like it, then you could at least dump the contents of the memory for the whole area of kernel, and see what parts of it contain what you expect, and what parts do not..
Can't say much about your bootloader I fear, since my ability to read assembler basicly would require me to keep notes of the whole state on paper and consult manuals a lot so I'll skip that (I can read assembler generated by typical compilers quite easy, and output the same from my own code, but that's about it)
Posted: Thu Mar 22, 2007 5:37 pm
by Combuster
check your registers:
AH = sector
AL = head
and what you do:
*Load a sector*
INC AX - goes to next head, not sector (!)
loop
essentially, you're loading bogus data.
Posted: Thu Mar 22, 2007 5:55 pm
by neon
I do increment oly AH to increase the sector number...
Code: Select all
LoadSectors:
pusha ; store registers...
mov dl, 12h
div dl
; Increment next sector --------------------------
inc ah ; move to next sector (CL=sector number 1-63)
mov cl, ah
mov dh, al ; DH=head number
and dh, 01h
shr al, 1
mov ch, al
mov dl, 00h ; drive number (00h=floppy)
ReadSector:
mov ah, 02h
mov al, 01h ; number of sectors to read
int 13h
jc ReadSector ; CF is set if error by INT 13h
popa ; restore registers
add bx, 0200h
;----- Here I increment AX (AL) for next headnumber -------------
inc ax
; If I only inc ah here, I recieve panic message from Bosch
loop LoadSectors ; loop until CX = 0
ret
Unless Im missing something..?
Posted: Thu Mar 22, 2007 6:14 pm
by Combuster
two things:
1: that message probably tells you HOW you screwed up
2: I bet you never tried debugging your code (bochs is your friend there)
Posted: Thu Mar 22, 2007 6:19 pm
by neon
I have been debugging my code alot actually. atm I am seeing if
I could trace the value pushed on the stack when printf() executes.
Im not finding nothing unusual yet..
I am going to check the code some more, and see if I find anything.
Posted: Thu Mar 22, 2007 6:49 pm
by mystran
Combuster wrote:two things:
1: that message probably tells you HOW you screwed up
2: I bet you never tried debugging your code (bochs is your friend there)
Combuster you should drop the attitude and show some respect. If you bother to re-read the whole thread, it's obvious neon DOES have a clue about what he's doing, at least in the sense of "debugging 101", after several days of nothing but fruitless debugging, would you feel nice to be told to "try actually debugging your code"?
In any case, neon, please consider: you save registers, increase sector, read sector (several times if it fails), restore registers, increase head, and loop.
In other words, you are both increasing sector and head within the loop, yet you replace registers in a way which reverts the sectors back..
Posted: Thu Mar 22, 2007 7:15 pm
by neon
I think I see what you mean..
I am pushing the registers at the start of LoadSectors, and,
after reading the sector, I used popa to revert the registers back
to their beginning state, hence it reads the first sector 50 times.
Posted: Thu Mar 22, 2007 11:25 pm
by kernel64
To test your sector reading, I would debug the living daylights out of that first, if I were you.
For example, just get together a plain text file of a certain number of sectors, say, 10 sectors. Fill the text file with printable ASCII text.
Write another bootloader or modify your existing one and put a putch() or printf() routine into the bootloader, and print the sectors you read to see if everything seems to be okay. You could do a quick and dirty rep stosb with less than 10 sectors instead of writing putch() and printf() routines though, just to see if you get what you expect when reading sectors, then stop with an endless loop so you can see the ASCII text on the screen.
Then when reading the sectors seems to be fine, you can gradually pinpoint the problem by working your way from there.
Posted: Fri Mar 23, 2007 4:08 am
by Combuster
mystran wrote:Combuster you should drop the attitude and show some respect. If you bother to re-read the whole thread, it's obvious neon DOES have a clue about what he's doing, at least in the sense of "debugging 101", after several days of nothing but fruitless debugging, would you feel nice to be told to "try actually debugging your code"?
If i had no respect i'd have flamed him for his stupidity instead of urging him to debug properly.
I dont think i can call "change things randomly and see if i still get the null pointer" real debugging. That's the trial and error approach. If one would just run the bootloader and afterwards check what is loaded and what not, i would at least have gotten some directed questions instead of the 'help me im lost' attitude. If the person actually bothered to check the inputs to int 0x13 the whole second half of this thread was not necessary. However i can see no trace of any serious debugging investment in anything except a print-stack at the call, and the author just looks like he's asking us to solve his problem for him.
Not being
able to debug is just one thing, but claiming you do is just wrong. I hope for neon that he learns how to find his own bugs.
@neon: Verification is knowledge
Posted: Fri Mar 23, 2007 6:49 am
by mystran
I still think changing random things to see if something changes a valid strategy for debugging. Once you find something that causes some change (whatever that is), you can apply that knowledge (and the knowledge of what did NOT change anything) backwards to figure out where the problem came from.
During the 15 or so years I've written code for computers, I've countless times been stuck without any idea whatsoever where the problem could be.. leaving me no choice but to change random things...
One of the funnies examples was this:
Code: Select all
for(int i; i < foo; i++)
for(int j; j < bar; j++)
do_something(i,j);
That didn't work, and for some reason do_something only executed once. Changing things randomly:
Code: Select all
for(int i; i < foo; i++) {
for(int j; j < bar; j++) {
do_something(i,j);
}
}
That did work. So where was the problem?
Turns out GCC used to have a bug that would cause incorrect code to be generated in C++ mode for two nested for-loops (not always, but in some cases), but only if you left the {} out...
I didn't even have internet connection back then... not that I've been able to read GCC source back then even if I'd had it..
Posted: Fri Mar 23, 2007 11:51 pm
by neon
I think I found the problem.
The pointer IS valid. The pointer is also pushed/poped on the stack
correctly as well.
I am suspecting the problem is an INITIALIZATION problem,
This is the code:
Code: Select all
void main () {
_clrscr (WINCOL);
unsigned char* p="HELLO WORLDHELLO WORLDHELLO WORLDHELLO WORLDHELLO WORLD";
// *** ASSIGN FIRST 10 CHARS TO LETTER "H"
int i=0;
for (i=0; i<10; i++)
p[i]='H';
// *** PRINTS OUT "H" CHARACTER.
// Without the assignment (the above loop), it prints null
_printf (p);
__asm ("hlt");
}
Here is my current printf, in case you would like to see it:
Code: Select all
void _printf (char* format) {
_putch ('A'); // works
_putch (*format);
}
The "A" is always printed. The string in *format is only valid when
assigned during runtime. If I initialize it, the data pointed by the
pointer (not the pointer itself) is null.
So, basically initializing fails, while assignment works.
(btw, I did fix my loadsectors routine in my bootloader)
I never seen this before... I suspect it has to do with rodata
(Although, I do have it).
I am going to do more research and see if I find anything...