Page 1 of 1

Using GRUB

Posted: Fri Feb 08, 2008 12:40 pm
by Jeko
I have a kernel in elf format, and I want to use GRUB for booting.

I have stage1 and stage2 files and menu.lst.

How can I use these files for booting from a floppy?

Posted: Fri Feb 08, 2008 1:05 pm
by StephanvanSchaik
How to use GRUB

I think this is what you need.

Posted: Fri Feb 08, 2008 1:16 pm
by Jeko
I need to make a floppy image with grub to copy to floppy without rebooting my computer, each time I run "make all"

I need a floppy disk image with GRUB preloaded onto it, that I will update each time with my new kernel binary file.

Posted: Fri Feb 08, 2008 1:46 pm
by babernat
Not sure if this is what you're asking, but this is how I do it. If you want a simple pre-built floppy image with grub and whatnot on it, then check out bran's kernel dev tutorial. That's what I used. I think I found it on osdever.net or something.

In my make file I first build and link everything and then mount the floppy disk image, copy the file, then unmount the image. It's as simple as that, especially if you're using linux or some other nix clone.

Make sense?

Posted: Fri Feb 08, 2008 3:37 pm
by StephanvanSchaik

Posted: Tue Feb 12, 2008 8:02 am
by Jeko
StephanVanSchaik wrote:GRUB Floppy Image
ok. Now I need to know how to copy my kernel in this prebuilt image.

Posted: Tue Feb 12, 2008 8:10 am
by AJ
Hi,

Mount the image on Linux, or use VFD on Windows, access the drive as a normal disk drive and copy your kernel across.

Cheers,
Adam

Posted: Wed Feb 13, 2008 7:45 am
by Jeko
AJ wrote:Hi,

Mount the image on Linux, or use VFD on Windows, access the drive as a normal disk drive and copy your kernel across.

Cheers,
Adam
I'm in Linux. What are commands to do this? (I'm a newbie in Linux...)

Posted: Wed Feb 13, 2008 8:10 am
by Brynet-Inc
MarkOS wrote:I'm in Linux. What are commands to do this? (I'm a newbie in Linux...)
There is a Wiki here for a reason, use it. http://www.osdev.org/wiki/Loopback_Device

Posted: Thu Feb 14, 2008 8:38 am
by Jeko
Brynet-Inc wrote:
MarkOS wrote:I'm in Linux. What are commands to do this? (I'm a newbie in Linux...)
There is a Wiki here for a reason, use it. http://www.osdev.org/wiki/Loopback_Device
Ok. Thank you!
This is my makefile for doing a GRUB floppy image:

Code: Select all

	$(LD) $(LDFLAGS) $(OBJFILES)
	sudo losetup /dev/loop0 boot/floppy.img
	sudo mount /dev/loop0 /mnt
	#sudo mkdir /mnt/boot
	#sudo mkdir /mnt/system
	sudo cp kernel.bin /mnt/system/kernel.bin
	sudo cp boot/menu.cfg /mnt/boot/menu.cfg
	sudo umount /dev/loop0
	sudo losetup -d /dev/loop0
	#These lines open Bochs!
	sudo losetup /dev/loop0 boot/floppy.img
	sudo bochs -f confbochs.txt
	sudo losetup -d /dev/loop0
But there is an error:
ccache gcc -Wall -O -floop-optimize2 -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -nostdinc -I include -ffreestanding -fno-stack-protector -c kernel.c -o kernel.o
nasm -felf -o loader.o loader.asm
ld -Tlink.ld -o kernel.bin ./kernel.o ./loader.o
sudo losetup /dev/loop0 boot/floppy.img
make: *** [kernel.bin] Error 2


But if I do "sudo losetup /dev/loop0 boot/floppy.img directly from command line, it works perfectly... Why?

Posted: Thu Feb 14, 2008 11:42 am
by xyzzy
Have the Makefile use /sbin/losetup - some distros have an extension to bash that automaticaly puts /sbin and /usr/sbin in your PATH when you use sudo.

Posted: Thu Feb 21, 2008 1:36 pm
by Jeko
Thank you!

Now I have another problem...
In my kernel loader (code loaded by GRUB), written in NASM, I wrote this:

Code: Select all

...
global _loader, bootinfo
extern _main
But when I use bootinfo:

Code: Select all

...
mov (bootinfo-ADDRADJUST), ebx
...
There is an error message:

Code: Select all

nasm -felf -o boot/loader.o boot/loader.asm
boot/loader.asm:58: error: symbol `bootinfo' undefined
How can I do to resolve this problem?

Another small thing... After booting with GRUB, I must turn off floppy motor? Or it's turned off directly from GRUB?

Posted: Thu Feb 21, 2008 1:50 pm
by lukem95
yeah GRUB leaves it spun up.

you dont HAVE to disable it, but its a neatness thing.

Posted: Fri Feb 22, 2008 5:53 am
by Jeko
lukem_95 wrote:yeah GRUB leaves it spun up.

you dont HAVE to disable it, but its a neatness thing.
Ok. Thank you!
I have another question. I can't resolve this problem...
I have this code for loading my kernel (code loaded by grub):

Code: Select all

global _loader, bootinfo	; Make entry point visible to linker.
extern _main			; _main is defined elsewhere

; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN	equ	1<<0			; align loaded modules on page boundaries
MEMINFO		equ	1<<1			; provide memory map
FLAGS		equ	MODULEALIGN | MEMINFO	; this is the Multiboot 'flag' field
MAGIC		equ	0x1BADB002		; 'magic number' lets bootloader find the header
CHECKSUM	equ	-(MAGIC + FLAGS)	; checksum required


; Page directory.

K_PDE	equ	0x1000

; Kernel page table #0 (4MB).

K_PTE	equ	0x2000

; First 4MB Identity-map page table.

I_PTE	equ	0x3000
ADDRADJUST	equ	0xBFF00000
KERNEL_VIRTUAL_BASE	equ	0xC0000000                  ; 3GB
KERNEL_PAGE_NUMBER	equ	(KERNEL_VIRTUAL_BASE >> 22)  ; Page directory index of kernel's 4MB PTE.


section .data
align 0x1000
BootPageDirectory:
	; This page directory entry identity-maps the first 4MB of the 32-bit physical address space.
	; All bits are clear except the following:
	; bit 7: PS The kernel page is 4MB.
	; bit 1: RW The kernel page is read/write.
	; bit 0: P  The kernel page is present.
	; This entry must be here -- otherwise the kernel will crash immediately after paging is
	; enabled because it can't fetch the next instruction! It's ok to unmap this page later.
	dd 0x00000083
	times (KERNEL_PAGE_NUMBER - 1) dd 0                 ; Pages before kernel space.
	; This page directory entry defines a 4MB page containing the kernel.
	dd 0x00000083
	times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0  ; Pages after the kernel image.

section .text
align 4
MultiBootHeader:
	dd MAGIC
	dd FLAGS
	dd CHECKSUM

align 4
bootinfo:
	dd 0

; reserve initial kernel stack space -- that's 16k.
STACKSIZE equ 0x4000

_loader:
	; Turn off floppy motor
	mov dx, 0x3f2

	mov al, 0x0c

	out dx, al

	; Salva il puntatore alla struttura multiboot
	mov [bootinfo - KERNEL_VIRTUAL_BASE], ebx

	


	; NOTE: Until paging is set up, the code must be position-independent and use physical
	; addresses, not virtual ones!
	mov ecx, (BootPageDirectory - KERNEL_VIRTUAL_BASE)
	mov cr3, ecx                                        ; Load Page Directory Base Register.

	mov ecx, cr4
	or ecx, 0x00000010                          ; Set PSE bit in CR4 to enable 4MB pages.
	mov cr4, ecx

	mov ecx, cr0
	or ecx, 0x80000000                          ; Set PG bit in CR0 to enable paging.
	mov cr0, ecx

	; Start fetching instructions in kernel space.
	lea ecx, [StartInHigherHalf]
 	jmp ecx                                                     ; NOTE: Must be absolute jump!

StartInHigherHalf:
	; Unmap the identity-mapped first 4MB of physical address space. It should not be needed
	; anymore.
	mov dword [BootPageDirectory], 0
 	invlpg [0]

	; NOTE: From now on, paging should be enabled. The first 4MB of physical address space is
	; mapped starting at KERNEL_VIRTUAL_BASE. Everything is linked to this address, so no more
	; position-independent code or funny business with virtual-to-physical address translation
	; should be necessary. We now have a higher-half kernel.
	mov esp, stack+STACKSIZE           ; set up the stack
	push eax                           ; pass Multiboot magic number

	; pass Multiboot info structure -- WARNING: This is a physical address and may not be
	; in the first 4MB!
	push ebx

	call  _main                  ; call kernel proper
	hlt                          ; halt machine should kernel return


section .bss
align 32
stack:
	resb STACKSIZE      ; reserve 16k stack on a quadword boundary
It's taken from HigherHalfTutorial.
In my kernel.c i have this code:

Code: Select all

//The symbol table for a.out format.

struct aout_symbol_table_t {

	unsigned long tab_size;

	unsigned long str_size;

	unsigned long address;

	unsigned long reserved;

};



//The section header table for ELF format.

struct elf_section_header_table_t {

	unsigned long num;

	unsigned long size;

	unsigned long address;

	unsigned long shndx;

};



//The multiboot informations.

struct multiboot_info_t

{

	unsigned long flags;

	unsigned long mem_lower;

	unsigned long mem_upper;

	unsigned long boot_device;

	unsigned long cmdline;

	unsigned long mods_addr;

	union

	{

		struct aout_symbol_table_t aout_sym_t;

		struct elf_section_header_table_t elf_sec_t;

	} u;

	unsigned long mmap_length;

	unsigned long mmap_addr;

};
extern struct multiboot_info_t *bootinfo;




if( bootinfo->flags & 0x02 )


	physical_memory = (bootinfo->mem_upper) * 1024;


else


	halt();

But when I try to use the global variable bootinfo, bochs reboots without any error message...
Why?