Page 1 of 1

PLEASE HELP ME, how to jump to C code in kernel?

Posted: Mon Nov 26, 2007 6:37 am
by revival4u
this program is running in Linux

Using NASM assembler and GCC compiler


I loaded 3rd sector to memory address of 0x2000:0x0000

(1st sector is bootloader "boot.bin", 2nd sector is kernel.bin and 3rd sector is "kRoutine.bin" -> but i wonder if the 3rd sector is correct or not)

in "boot.asm"

Code: Select all

        .read_kRoutine 
                mov             ax, 0x2000 
                mov             es, ax 
                mov             bx, 0x00 

                mov             ah, 0x02 
                mov             al, 0x01 
                mov             ch, 0x00 
                mov             cl, 0x03 
                mov             dh, 0x00 
                mov             dl, 0x00 
                int             0x13 

                ;jc             .read_kRoutine 

		...

		jmp		0x1000:0x0000	;jmp to kernel.bin
and i jump to 0x00020000

in "kernel.asm"

Code: Select all

                jmp             0x2000:0x0000	;jmp to kRoutine.bin


"kRoutine.c" and "kRoutineAsm.asm" will be binded

in "kRoutine.c"

Code: Select all


#include <stdio.h> 

int main(void){ 
        printk(); 
        halt(); 
} 



in "kRoutineAsm.asm"

Code: Select all

printk: 
                push    ebp 
                mov             ebp, esp 

                push    eax 
                push    edi 
                push    es 
                pushad 

                mov             ax, SysVideoSelector 
                mov             es, ax 
                mov             edi, 0 

                mov             byte [es:edi], 'H' 
                inc             edi 
                mov             byte [es:edi], 0x06 
                inc             edi 

                mov             byte [es:edi], 'i' 
                inc             edi 
                mov             byte [es:edi], 0x06 
                inc             edi 

                popad 
                pop             es 
                pop             edi 
                pop             eax 

                mov             esp, ebp 
                pop             ebp 

                ret

halt: 
                HLT 
                jmp             halt 









assemble and compile all the source files

Code: Select all

            nasm -f bin boot.asm -o boot.bin 
             nasm -f bin kernel.asm -o kernel.bin 
             gcc -c kRoutine.c 
             nasm -f elf32 kRoutineAsm.asm 
and linking like above

Code: Select all

       ld -Ttext 0x00020000 -e main -o kRoutine kRoutine.o RoutineAsm.o 
and remove unnecessary information to make binary file

Code: Select all

        objcopy -R .note -R .comment -S -O binary kRoutine kRoutine.bin 
and combine all of binary file.

Code: Select all

       cat boot.bin kernel.bin kRoutine.bin > disk.img 
I want to ask is that

this following 2 commands are correct?

Code: Select all

		ld -Ttext 0x00020000 -e main -o kRoutine kRoutine.o kRoutineAsm.o 
	        objcopy -R .note -R .comment -S -O binary kRoutine kRoutine.bin 
		
and file "kRoutine.bin" is exactly saved in 3rd sector of image?

and can execute main() in "kRoutine.c" by jump to 0x00020000 ?

Code: Select all

		jmp 0x2000:0000
		



Thanks for reading!!

Have a nice day

Posted: Mon Nov 26, 2007 7:07 am
by JamesM
Again, the title bears absolutely no reseblance to the actual question.

Grr. :evil:

Posted: Mon Nov 26, 2007 8:05 am
by Dandee Yuyo
Some suggestions:

* Don't #include <stdio.h> You are actually not using it and it won't work.
* Use the gcc flags to not include any standard headers and libs.
* This is important, for not saying crucial: Set up a stack somewhere.
* Use __attribute((noreturn) for your main function (just to be neat)
* Be sure the compiled asm code is before the compiled C code on the compiled image and the very first one.
* Then, don't try to jump directly to C, jump to the asm code that in turns calls the C code (What is called a stub). You might need to add underscores or not depending on the gcc settings. So in your kernel that is loaded at 0x2000:0000:

Code: Select all

[ORG 0x20000]
[EXTERN _main]
start:
     call _main
     jmp $

; Put the rest of your asm routines such printk here, mark as "global" to be visible from C

[GLOBAL _printk]
printk:
     ....
Hope it helps!

Posted: Mon Nov 26, 2007 8:18 am
by jal
JamesM wrote:Again, the title bears absolutely no reseblance to the actual question.
Well, the OP did put "please help me" in the title, in allcaps to draw our attention, and probably he actually needs help. Whether that is in OS design or basic nettiquette is a second, but...


JAL

Posted: Mon Nov 26, 2007 8:39 am
by revival4u
Dandee Yuyo wrote:Some suggestions:

* Don't #include <stdio.h> You are actually not using it and it won't work.
* Use the gcc flags to not include any standard headers and libs.
* This is important, for not saying crucial: Set up a stack somewhere.
* Use __attribute((noreturn) for your main function (just to be neat)
* Be sure the compiled asm code is before the compiled C code on the compiled image and the very first one.
* Then, don't try to jump directly to C, jump to the asm code that in turns calls the C code (What is called a stub). You might need to add underscores or not depending on the gcc settings. So in your kernel that is loaded at 0x2000:0000:

Code: Select all

[ORG 0x20000]
[EXTERN _main]
start:
     call _main
     jmp $

; Put the rest of your asm routines such printk here, mark as "global" to be visible from C

[GLOBAL _printk]
printk:
     ....
Hope it helps!

Thanks for your suggestions

but, in binary format doesn't support GLOBAL or EXTERN directives...

how to jump to C code?

Posted: Mon Nov 26, 2007 9:05 am
by JamesM
If your format doesn't support global or extern directives, you can't jump to C code, as (amazingly) you can't link two dependent compilation units together.

I suggest you get a format which does support global/extern. What I would do is assemble the object files as ELF objects then link the final executable as binary.

Posted: Mon Nov 26, 2007 9:13 am
by Dandee Yuyo
Yep. I missed that. Use a.out, elf, coff or whatever. Then set up a proper linker script.

Posted: Mon Nov 26, 2007 9:33 am
by neon
I highley recommend following a filesystem format and not reading/writing random sectors like that. Trust me--you'll thank me later.

Its okay to load and execute just another sector at bootup as needed, but please do not call it a kernel.

Posted: Mon Nov 26, 2007 9:58 am
by Solar
  • assemble and compile all the source files
  • and linking like above
  • and remove unnecessary information to make binary file
  • and combine all of binary file.
That's compile, link, reduce, link. Cannot work. First complete the linking process (while you still have symbol tables to link with), then make the file into a flat binary as the last step.

Or, better still (am I really saying this again?), do some more user-space programming to get the feel for your toolchain before going for kernel-space code. You can practice joining ASM and C code with a simple "Hello World" example in userspace, without the added difficulties of kernel-space code.