1

I am writing a simple kernel in C and ASM(to call assembly instructions generated by C compile). I am following this excellent articles from osdev.org. After read an kernel written in assembly and compiled and executed, it was worked fine, I see the kernel.bin running on qemu, fantastic. But I want really to write it in C. I found an example in same web page.

I compiled it and tried run the kernel.bin on qemu but I get "boot failed" from all devices: hard disk, floopd and CD-rom. then I disassembled the kernel.bin generated by ks.o (kernel.asm assembled using nasm) and kernel.o (kernel.c assembled using gcc) assembled to bin file using the ld. The kernel.bin:

http://pastebin.com/Y0pLFvij I can't see my string or any instruction to assembly write my string on video.

The C code that generate it:

#define WHITE_TXT 0x07 // white on black text
unsigned int k_printf(char *message, unsigned int line);
void k_clear_screen();

k_main() 
{
    k_clear_screen();
    k_printf("Hi!\nHow's this for a starter OS?", 0);
};

unsigned int k_printf(char *message, unsigned int line) // the message and then the line #
{
    char *vidmem = (char *) 0xb8000;
    unsigned int i=0;

    i=(line*80*2);

    while(*message!=0)
    {
        if(*message=='\n') // check for a new line
        {
            line++;
            i=(line*80*2);
            *message++;
        } else {
            vidmem[i]=*message;
            *message++;
            i++;
            vidmem[i]=WHITE_TXT;
            i++;
        };
    };

    return(1);
};

void k_clear_screen() // clear the entire text screen
{
    char *vidmem = (char *) 0xb8000;
    unsigned int i=0;
    while(i < (80*25*2))
    {
        vidmem[i]=' ';
        i++;
        vidmem[i]=WHITE_TXT;
        i++;
    };

and the assembly that call it:

[bits 32]

[global start]
[extern k_main] ; this is in the c file

start:
  call k_main

  cli  ; stop interrupts
  hlt ; halt the CPU

the link.ld

OUTPUT_FORMAT("binary")

ENTRY(start)

SECTIONS

{

  .text  0x100000 : {

    code = .; _code = .; __code = .;

    *(.text)

    . = ALIGN(4096);

  }

  .data  : {

    data = .; _data = .; __data = .;

    *(.data)

    . = ALIGN(4096);

  }

  .bss  :

  {

    bss = .; _bss = .; __bss = .;

    *(.bss)

    . = ALIGN(4096);

  }

  end = .; _end = .; __end = .;

}

and the makefile:

bin:
    nasm -f aout -o ks.o kernelbase.asm 
    gcc -Wall -c -o kernel.o kernel.c    
    ld -T link.ld -o kernel.bin ks.o kernel.o 
run1:
    qemu kernel.bin

clear:
    rm -f *.o

cbin:
    rm -f *.bin

and the kernel in pure assembly, disassembled: http://pastebin.com/Bkvkq3YQ that worked fine for me, and I can see the instrutions to write on video.

My OS: Ubuntu 10.4
Compiler: gcc
Assembler : NASM

Where am I wrong?

11
  • There is code missing. The C code cannot possibly compile in that form. Commented Mar 4, 2012 at 15:48
  • No, the C code is does not compile too well. Also, there are warnings. Commented Mar 4, 2012 at 15:52
  • What do you think the difference is between C converted to asm then assembled and "really write it in C". Certainly gcc does this, you compile a c program it compiles to asm, then calls the assembler and linker for you. No difference (so long as you use the same compiler/assembler/linker, compile options, and linker script. Commented Mar 4, 2012 at 16:09
  • @NiklasB.: how to remove this warnings? Commented Mar 4, 2012 at 16:31
  • @dwelch:I know that there no difference, all is assembly. When I say "Written in C" is uses C syntax and C compiler to make assembly. Commented Mar 4, 2012 at 16:34

1 Answer 1

1

I tried to do that tutorial and the code failed too. Finally I did this:

Compile both files for 32 bit:

nasm -f elf32 ks.asm -o kernelbase.o
gcc -m32 -c kernel.c -o kernel.o

And link:

gcc -m32 kernelbase.o kernel.o -o Kernel.bin

After a while I found out that I don't get any errors by using gcc for linking.

Hope I helped :-)

Sign up to request clarification or add additional context in comments.

2 Comments

what is -c flag on nasm options? I removed it and was compiled successfully and I can see valid assembly output. another question: have you tried run kernel.bin? I tried run it with qemu kernel.bin but I get something like "boot failed" cannot found any device, then I liked it using ld: ld -T link.ld -o kernel.bin kernelbase.o kernel.o , looks like a progress, it know the and show "Booting from hard disk" but never start the kernel. Thanks very much, @XCoder.
Sorry "-c" was my mistake I compiled it without the "-c". So far I haven't test it. (no time) ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.