title: Problems with simple C bootstrap/kernel
body: <p>Recently I've become interested in writing my own really really basic OS.
  I wrote (well, copied) some basic Assembly that establishes a stack and does some basic things and this seemed to work fine, however attempting to introduce C into the mix has screwed everything up.</p>
  <p>I have two main project files: loader.s which is some NASM that creates the stack and calls my C function, and kernel.c which contains the basic C function.</p>
  <p>My issue at the moment is essentially that QEMU freezes up when I run my kernel.bin file. I'm guessing there are any number of things wrong with my code -- perhaps this question isn't really appropriate for a StackOverflow format due to its extreme specificity. My project files are as follows:</p>
  <p><strong>loader.s:</strong></p>
  <pre><code>BITS 16                         ; 16 Bits
  
  extern kmain                    ; Our 'proper' kernel function in C
  
  loader:
      mov ax, 07C0h           ; Move the starting address [7C00h] into 'ax'
      add ax, 32              ; Leave 32 16 byte blocks [200h] for the 512 code segment
      mov ss, ax              ; Set 'stack segment' to the start of our stack
      mov sp, 4096            ; Set the stack pointer to the end of our stack [4096 bytes in size]
  
      mov ax, 07C0h           ; Use 'ax' to set 'ds'
      mov ds, ax              ; Set data segment to where we're loaded
      mov es, ax              ; Set our extra segment
  
      call kmain              ; Call the kernel proper
  
      cli                     ; Clear ints
  
      jmp $                   ; Hang
  
  
  ; Since putting these in and booting the image without '-kernel' can't find
  ; a bootable device, we'll comment these out for now and run the ROM with
  ; the '-kernel' flag in QEMU
          ;times 510-($-$$) db 0          ; Pad remained of our boot sector with 0s
          ;dw 0xAA55                      ; The standard 'magic word' boot sig
  </code></pre>
  <p><strong>kernel.c:</strong></p>
  <pre><code>#include &lt;stdint.h&gt;
  
  void kmain(void)
  {
          unsigned char *vidmem = (char*)0xB8000; //Video memory address
          vidmem[0] = 65; //The character 'A'
          vidmem[1] = 0x07; //Light grey (7) on black (0)
  }
  </code></pre>
  <p>I compile everything like so:</p>
  <blockquote>
  <p>nasm -f elf -o loader.o loader.s</p>
  <p>i386-elf-gcc -I/usr/include -o kernel.o -c kernel.c -Wall -nostdlib -fno-builtin -nostartfiles -nodefaultlibs</p>
  <p>i386-elf-ld -T linker.ld -o kernel.bin loader.o kernel.o</p>
  </blockquote>
  <p>And then test like so:</p>
  <blockquote>
  <p>qemu-system-x86_64 -kernel kernel.bin</p>
  </blockquote>
  <p>Hopefully someone can have a look over this for me -- the code snippets aren't massively long.</p>
  <p>Thanks.</p>