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

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
revival4u
Posts: 5
Joined: Mon Nov 26, 2007 3:16 am

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

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Again, the title bears absolutely no reseblance to the actual question.

Grr. :evil:
User avatar
Dandee Yuyo
Member
Member
Posts: 47
Joined: Fri Nov 09, 2007 6:46 pm
Location: Argentina

Post 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!
NaN - Not a Nerd
Working on: Physical Memory Management with a 5-lod mipmap XD
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post 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
revival4u
Posts: 5
Joined: Mon Nov 26, 2007 3:16 am

Post 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?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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.
User avatar
Dandee Yuyo
Member
Member
Posts: 47
Joined: Fri Nov 09, 2007 6:46 pm
Location: Argentina

Post by Dandee Yuyo »

Yep. I missed that. Use a.out, elf, coff or whatever. Then set up a proper linker script.
NaN - Not a Nerd
Working on: Physical Memory Management with a 5-lod mipmap XD
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post 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.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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.
Every good solution is obvious once you've found it.
Post Reply