You are not logged in.
Pages: 1
I've started to write a kernel, and I have successfully gotten a kernel.bin file. But I don't know how to get this into a QEMU-bootable image with grub. Does anybody have any experience with this?
If you want it, here is my code (not all of it; I left out kernel.*, as it's mostly memcpy/strlen kind of stuff):
main.c
#include "kernel.h"
#include "screen.h"
void kmain(unsigned long magic, unsigned long addr)
{
init_video();
puts((unsigned char *)"hello, world");
while(1);
}
bootstrap.asm
; bootstrap.asm
;
; Gets boot info from the bootloader, sets up the stack,
; and then runs the C function kmain.
[BITS 32]
global start
start:
mov esp, _sys_stack
jmp startkernel
ALIGN 4
mboot:
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
startkernel:
EXTERN kmain
call kmain
jmp $
SECTION .bss
resb 8192
_sys_stack:
screen.h
#ifndef __ONYX_SCREEN_H
#define __ONYX_SCREEN_H
#include "kernel.h"
// Screen Management Functions
unsigned short *__textbuf;
int attrib;
int __csr_x;
int __csr_y;
#define __ONYX_ROWS 80
#define __ONYX_COLS 24
void scroll();
void move_cursor();
extern void cls();
extern void putch(unsigned char c);
extern void puts(unsigned char *str);
extern void settextcolor(unsigned char fg, unsigned char bg);
extern void init_video();
#endif
screen.c
#include "screen.h"
#undef __ONYX_SCREEN_H
void scroll()
{
unsigned space, temp;
space = 0x20 | (attrib << 8);
if (__csr_y > __ONYX_ROWS)
{
temp = __csr_y - __ONYX_ROWS + 1;
memcpy((unsigned char *)__textbuf, (unsigned char *)__textbuf + (temp * __ONYX_COLS), (__ONYX_ROWS - temp) * __ONYX_COLS * 2);
memsetw(__textbuf + (__ONYX_ROWS - temp)*__ONYX_COLS, space, __ONYX_COLS);
__csr_y = __ONYX_ROWS - 1;
}
}
void move_cursor()
{
unsigned temp;
temp = __csr_y * __ONYX_COLS * __csr_x;
outportb(0x3D4, 14);
outportb(0x3D5, temp >> 8);
outportb(0x3D4, 15);
outportb(0x3D5, temp);
}
extern void cls()
{
unsigned space;
int i;
space = 0x20 | (attrib << 8);
for (i = 0; i < __ONYX_ROWS; i++)
memsetw(__textbuf + i*__ONYX_COLS, space, __ONYX_COLS);
__csr_x = __csr_y = 0;
move_cursor();
}
extern void putch(unsigned char c)
{
unsigned short *where;
unsigned att = attrib << 8;
if (c == 0x08)
{
if (__csr_x != 0)
__csr_x--;
}
else if (c == 0x09)
{
__csr_x = (__csr_x + 8) & ~(8-1);
}
else if (c == '\r')
{
__csr_x = 0;
__csr_y++;
}
else if (c >= ' ')
{
where = __textbuf + (__csr_y * __ONYX_COLS + __csr_x);
*where = c | att;
__csr_x++;
}
if (__csr_x >= __ONYX_COLS)
{
__csr_x = 0;
__csr_y++;
}
scroll();
move_cursor();
}
extern void puts(unsigned char *str)
{
int i;
for (i = 0; i < strlen((const char *)str); i++)
putch(str[i]);
}
extern void settextcolor(unsigned char fg, unsigned char bg)
{
attrib = (bg << 4) | (fg & 0x0F);
}
extern void init_video()
{
__textbuf = (unsigned short *)0xB8000;
attrib = 0x0F;
__csr_x = __csr_y = 0;
cls();
}
NOTE: there are other files, if you want to see them, let me know.
urxvtc / wmii / zsh / configs / onebluecat.net
Arch will not hold your hand
Offline
I solved my own problem. Assuming that you have a file called kernel.elf or something and it has a bootstrap linked in, then the following will create a floppy disk image bootable via qemu.
dd if=/dev/zero of=kernel.img bs=1024 count=1440 # create image file
losetup /dev/loop0 kernel.img # create link between /dev/loop0 and kernel.img
mkfs -q /dev/loop0 # make filesystem
mount /dev/loop0 /mnt # mount filesystem
mkdir -p /mnt/boot/grub # setup file hiarchy
cp /boot/grub/stage* /mnt/boot/grub # install grub
cp kernel.img /mnt/ # load kernel
echo -e "device (fd0) /dev/loop0\nroot (fd0)\nsetup (fd0)\nquit\n" | grub --device-map=/dev/null # setup grub
umount /mnt # unmount filesystem
losetup -d /dev/loop0 # remove link
Then boot using qemu -fda kernel.img. You should get a grub prompt. Type this:
root (fd0)
kernel /kernel.img
boot
And it should boot your kernel.
urxvtc / wmii / zsh / configs / onebluecat.net
Arch will not hold your hand
Offline
If your kernel is multiboot compatible you can also just do:
qemu -kernel <kernel image>
and skip grub entirely. qemu supports booting multiboot and/or linux kernels natively.
Offline
GRUB initializes some hardware componentes (RAM, PIC, ...) and I rely on that, so I can't use your suggestion. But thanks anyway.
urxvtc / wmii / zsh / configs / onebluecat.net
Arch will not hold your hand
Offline
Pages: 1