Page 1 of 1
Compiling/linking kernel [solved]
Posted: Sun May 28, 2006 12:17 pm
by Tyrel
I've done this before, but I lost everything (wasn't much) and I'm starting over... but I'm having trouble.
I have an assembly file and a C file. I want to link them together and output a 16-bit binary designed to run from 0000:7E00.
This is what I'm
currently doing which doesn't work. I'm using GCC 3.4.4 (a cross-compiler I built).
Code: Select all
$ nasm -o bios.o -f elf bios.asm
$ gcc -o stage2.o -c stage2.c
$ ld -o stage2.bin --oformat binary -Ttext 0x00007E00 -Tdata 0x00007E00 bios.o stage2.o
By how it runs (my instructions are executing, but looking at the wrong data), I'm guessing that the -Tdata thing isn't doing what I expect it to do. I also tried -Tdata 0x00000000 and that didn't work either.
Also, it looks like part of it (the .c file?) might be 32-bit code and the other part (asm) might be 16-bit code, based on disassembly.
Please provide assistance.
Thanks in advance,
Tyrel
Re:Compiling/linking kernel
Posted: Sun May 28, 2006 1:39 pm
by Tyrel
By the way, I fixed the 16-bit problem. I forgot to have BITS 16 in the asm file, and I had to add __asm(".code16gcc") to the C file to tell it all to be 16-bit.
I'm now actually not sure the C file has anything to do with this though... I put code to execute in the ASM file right away. Some of it executes, but the stuff that accesses the data segment doesn't work. The disassembly looks fine to me, but it doesn't run. So that's what I'm looking at now.
Re:Compiling/linking kernel
Posted: Sun May 28, 2006 2:03 pm
by Tyrel
Okay, here's some of the disassembly of what isn't working, maybe it'll help.
It starts at 0x200 in the file, and is executed at 0000:7E00. I stripped the instructions that ndisasm output in the data area, since they're meaningless, and compressed the hex to one line.
Code: Select all
0000022F BE6A7E mov si,0x7e6a
00000232 8A04 mov al,[si]
00000234 46 inc si
00000235 08C0 or al,al
00000237 7406 jz 0x23f
00000239 B40E mov ah,0xe
0000023B CD10 int 0x10
0000023D EBF3 jmp short 0x232
...
0000026A 53 65 63 6F 6E 64 20 73 74 61 67 65 20 68 61 73 20 63 6F 6D 6D 65 6E 63 65 64 21 0D 0A 00
So the instruction at the top there loads the address 7E6A (which, as far as I can tell, is correct for 26A in this file) into SI and then tries to print out the string there. But it's jumping out of the loop right away (al == 0) and executes the stuff after this (which I have printing an immediate # sign using the same interrupt to verify this).
My first thought was that maybe DS wasn't set correctly (to 0000), so I added code at the beginning to set DS to 0, but it still does the same thing.
Ideas?
Re:Compiling/linking kernel
Posted: Sun May 28, 2006 2:23 pm
by earlz
That is very, very weird
what about trying to use only C
like this
Code: Select all
void main(){
unsigned char *video_memory;
__asm(".intel_syntax noprefix\n"
"push ds\n" //preserve ds
"mov ds,0xB800\n" //sets ds to video memory
"mov [ds:0],'h'\n" //that might cause an error but you know what i mean
"mov [ds:1],0x0F\n" //just incase color was 00
"pop ds\n"
".att_syntax\n" //needed because gcc makes att asm code
)
for(;;){} //infinite loop, after all what does main() return to
}
if that works and prints h on the screen then it is something with your assembler
Re:Compiling/linking kernel
Posted: Sun May 28, 2006 4:13 pm
by Tyrel
Jordan3 wrote:
what about trying to use only C
Well, I have code in the assembly before the stuff I pasted which does output stuff to the screen, and stuff after it which outputs stuff to the screen... but those two places use immediate values instead of memory values for printing characters out.
Sample:
Code: Select all
mov al, 'Z'
mov ah, 0x0E
int 0x10
I had a hard time getting the stuff you provided to assemble, but finally got it. It does, in fact, put a bright white 'h' in the corner, but I wouldn't expect otherwise. This doesn't tell me that there is or isn't anything wrong with my assember, since it's not using its own DS at all, just another one.
By the way, this is how your code looks to get it to work:
Code: Select all
unsigned char *video_memory;
__asm(".intel_syntax noprefix\n"
"push ds\n" //preserve ds
"push ax\n" // and ax
"mov ax,0xB800\n"
"mov ds,ax\n" //sets ds to video memory
"mov [byte ptr ds:0], 'h'\n" //that might cause an error but you know what i mean
"mov [byte ptr ds:1], 0x0F\n" //just incase color was 00
"pop ax\n"
"pop ds\n"
".att_syntax\n" //needed because gcc makes att asm code
)
So... I'm still in the same place I was. Setting DS to 0000 and addressing 0x7E00 doesn't seem to get me stuff at 0x00007E00.
Re:Compiling/linking kernel
Posted: Sun May 28, 2006 4:21 pm
by earlz
so it won't work for reading stuff you don't explictly put DS in
that is very weird
Setting DS to 0000 and addressing 0x7E00 doesn't seem to get me stuff at 0x00007E00.
does that mean this doesn't work
Code: Select all
;so this wouldn't make it to where ah contained the letter E
;assuming E was at 0x7E00
mov ax,0
mov ds,ax
mov bx,7E00
mov ah,[ds:bx]
btw sorry for my code not working right away -- and i think i mis understood you a bit
if thats not what your talking about then I'm clueless
Re:Compiling/linking kernel
Posted: Sun May 28, 2006 4:59 pm
by Tyrel
Yeah, you understand now...
About 30 times I have looked back at my code that actually loads this into memory, and said to myself "yep, it's loading it to the right place!"... but just now I looked again, and I'm loading this to 0xFE00, not 0x7E00 !!!! ARG!
Now I've spent hours on this, people have spent many minutes reading my messages, and it was a stupid little mistake the whole time... *sigh*
Sorry about that...
Of course now something else is wrong, but I'll try to resolve that myself first... ugh
Re:Compiling/linking kernel
Posted: Sun May 28, 2006 5:02 pm
by earlz
don't worry about it i have seen much worse[from myself]