Page 1 of 1

Why my kernel Written in C doesn't work,while Assembly dose?

Posted: Mon Aug 08, 2005 4:32 am
by raywill
I am trying to write a small experimental OS.But I encountered some questions.Hope you can help me.
My bootloader works very well.It can load the kernel to the right position .At first I wrote my small kernel in asm,it works well.Later I changed my kernel to asm-C mixed one.Then it doesn't work.
I will show you my codes:

Code: Select all

----------------------------------------------
;BOOTLOADER.asm
; myboot.asm   bootstrap for real mode image or loader
;Aug,01,2005


%define IMAGE_SEG   0x1000


   org   0x7C00

entry:
   jmp   short begin
   nop
   
   ;reserved as my own param area
   times 0x3B db 0

begin:
   xor   ax, ax
   mov   ds, ax
   cli
   mov   ss, ax
   mov   sp, 0x7C00
   mov   bp, sp
   sti
   
   call   read
   

eof:
   mov   ax,sucmsg      ;Leaving boot
   mov   si,ax
   call   disps
   jmp   IMAGE_SEG:0
   
error:      
   mov   ax,errmsg      ;Leaving boot
   mov   si,ax
   call   disps
      
   xor   ah, ah
   int   16h      ;Wait for a key
   int   19h      ;Try to reboot
read:   
   mov   ax,loadmsg      ;Leaving boot
   mov   si,ax
   call   disps
   mov   ch,0
   mov   cl,2         ;we write our kernel to disk start from sector two
   mov   dh,0
   mov   dl,0         ;DL = Drive number   
   xor   bx,bx
   mov   ax,IMAGE_SEG      ;ES:BX = address
   mov   es,ax         ;   =1000:0000
   mov   al,0x5         ;read 5 sectors
   mov   ah, 2         ;AH = Read command
   int   13h         ;Do it
   jc   error
   ret

;In:   DS:SI points to the string to be displayed.
;Out:   None
disps:
   mov   ax, 0x0e0D   
   mov   bh ,0x00    
   mov   bl,7      
.1   int   10h
   lodsb
   test   al,al
   jnz   .1
   ret
   
errmsg   db   10,"Error Executing bootsector",13
   db   10,"Press any key to reboot",13,10,0
loadmsg   db   10,"Loading kernel...",13,10,0
sucmsg   db   10,"Ready to jump to kernel",13,10,0
size   equ   $ - entry
%if size+11+2 > 512
  %error "code is too large for boot sector"
%endif
   times   (512 - size  - 2) db 0

   db   0x55, 0xAA      ;2  byte boot signature
----------------------------------------------------
My KernelBuild.bat looks like this:

Code: Select all

gcc -c c.c -o c.o
nasm -f aout tl.asm -o tl.o
ld -Ttext=0x10000 -e begin tl.o c.o
rename a.out krnl.bin
The following is the kernel.

Code: Select all

/* TL.asm (TestLoader) ,this part is also works well,if I deleted the part written in C */
;TL.asm  Test the loader
;Aug,01,2005

[global begin]
[extern _main]

begin:
   mov   ax, cs
   mov   ds,ax
   
   mov   ax,showmsg
   mov   si,ax
   call   disps
   
   mov   ax,rbtmsg
   mov   si,ax
   call   disps
   
   call   _main      ;written in C
   
   xor   ah, ah
   int   16h      ;Wait for a key
   int   19h      ;Try to reboot

disp:
   mov   ah, 0x0e       
         mov   bh ,0x00   
   mov   bl,7      
   int   10h
   ret

disps:
   mov   ax, 0x0e0D 
   mov   bh ,0x00   ;
   mov   bl,7      
.1   int   10h
   lodsb
   test   al,al
   jnz   .1
   ret   
   
showmsg   db   10,"Hello World!",13,10,0
rbtmsg   db   10,"Mission End!",13,"Press any key to exit",13,10,0
   times (512*40) db 0

Code: Select all

/*C.c written in C,this part doesn't work correctly : ( */

char* msg = "Kernel loaded and Start Running Now..." ;

int main()
{
    unsigned char* videomem = ( unsigned char* )0xb8000 ;
    while( *msg != '\0' ){
        *videomem++ = *msg++ ; 
        *videomem++ = 0x1b ;      }
    for(;;);
    return 0;
}
PS.My work Enviroment:
Bochs ,WindowsXP,DJGPP(with gcc,ld,nasm in it),Hex Workshop(Binary file editor)

I think the problem is caused by the following command.
gcc -c c.c -o c.o
nasm -f aout tl.asm -o tl.o
ld -Ttext=0x10000 -e begin tl.o c.o
rename a.out krnl.bin
But I don't know where and why.
Do any one know what's the matter with this?Lots of thanks!


All the code can be found in the attach file.

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Mon Aug 08, 2005 5:24 am
by Solar
You are not telling the linker that it should generate a flat binary. That means it takes the C source, adds the C runtime and startup files (error 1), and makes it into a PE / COFF executable (don't know which one DJGPP does by default - error 2).

If you took the BareBones tutorial in the FAQ as template, note that the BareBones kernel is considered to be loaded by GRUB, which is capable of loading complete executable files - your bootloader most likely isn't.

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Mon Aug 08, 2005 5:46 am
by raywill
Solar wrote: You are not telling the linker that it should generate a flat binary. That means it takes the C source, adds the C runtime and startup files (error 1), and makes it into a PE / COFF executable (don't know which one DJGPP does by default - error 2).

If you took the BareBones tutorial in the FAQ as template, note that the BareBones kernel is considered to be loaded by GRUB, which is capable of loading complete executable files - your bootloader most likely isn't.
Thanks.Do you mean I should add
-ffrontstanding option when compiling the file?
I ever tried so.But it seems that it doesn't work. :(

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Mon Aug 08, 2005 6:01 am
by Solar
raywill wrote: Do you mean I should add
-ffrontstanding option when compiling the file?
I ever tried so.But it seems that it doesn't work. :(
Oi, oi... frontstanding? :D

Call gcc with [tt]-ffreestanding -nostdlib -nostartfiles -nodefaultlibs[/tt].

Call ld with [tt]--oformat binary[/tt].

Some of the above is not strictly necessary, but it should get you closer to the solution of your problem.

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Tue Aug 09, 2005 2:43 am
by Pype.Clicker
hm, also, using DJGPP will generate you 32-bit code ... since there's no switch to pmode in your bootloader (using 16-bit realmode), you cannot run 32-bit code from there. period.

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Tue Aug 09, 2005 5:28 am
by raywill
Solar wrote:
raywill wrote: Do you mean I should add
-ffrontstanding option when compiling the file?
I ever tried so.But it seems that it doesn't work. :(
Oi, oi... frontstanding? :D

Call gcc with [tt]-ffreestanding -nostdlib -nostartfiles -nodefaultlibs[/tt].

Call ld with [tt]--oformat binary[/tt].

Some of the above is not strictly necessary, but it should get you closer to the solution of your problem.
I have tried what you told me.but it still doesn't work.
I am sure there is something wrong with my way to link those file.But I tried for a long time,no result.

Can you or anyone else try to make my code run ?I am attaching all my files here.
If you succeed in making them run,can you send me a copy of those file ? My email address is [email protected]
Or you can just leave me a message here.

Really thanks.

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Tue Aug 09, 2005 5:34 am
by raywill
Pype.Clicker wrote: hm, also, using DJGPP will generate you 32-bit code ... since there's no switch to pmode in your bootloader (using 16-bit realmode), you cannot run 32-bit code from there. period.

But why when I use pure assembly code it doesn't cause any problem ?
What should be noticed when building especally linking the kernel?

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Tue Aug 09, 2005 5:58 am
by Solar
raywill wrote:
Pype.Clicker wrote: hm, also, using DJGPP will generate you 32-bit code ... since there's no switch to pmode in your bootloader (using 16-bit realmode), you cannot run 32-bit code from there. period.
But why when I use pure assembly code it doesn't cause any problem ?
AFAIK, NASM defaults to 16bit Real Mode code.
What should be noticed when building especally linking the kernel?
Not sure I understand the above. GCC does not support a segmented data model, and thus cannot generate 16bit code. You have to make the switch in Assembler, then jump into C code.

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Mon Aug 15, 2005 2:46 am
by raywill
Now I completely understand where the problem lies.

Thank you all.

Using gcc to build a protected mode kernel is a good choice.

BUT,if I really want to build a real mode OS,what should I do?

Can you suggest any good C compiler ?

Re:Why my kernel Written in C doesn't work,while Assembly do

Posted: Mon Aug 15, 2005 6:50 am
by Kim
You could try http://www.openwatcom.org/ it says it supports 16bit code. Iam not sure if it will do for you.