Higher Half loading

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
wolfram
Posts: 19
Joined: Wed Aug 19, 2009 11:37 am
Location: Saint-Petersburg, Russia

Higher Half loading

Post by wolfram »

Please help me with my higher half kernel, I don't understand, why this code not working, why I get tripplefaults. When I look memory(xp <ADDRES> in QEMU), I see, that all structures(page directory and tables) are correct(may be it is IMHO?).
start.asm

Code: Select all

format ELF

MULTIBOOT_MEMORY_INFO			equ		1 shl 1
MULTIBOOT_BOOTLOADER_MAGIC		equ		0x1BADB002
MULTIBOOT_HEADER_FLAGS			equ		MULTIBOOT_MEMORY_INFO
MULTIBOOT_CHECKSUM				equ		-(MULTIBOOT_BOOTLOADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

section '.loader' executable writeable

public _start
public _stbss
public _endbss

extrn _loader

align 4
	dd	MULTIBOOT_BOOTLOADER_MAGIC
	dd	MULTIBOOT_HEADER_FLAGS
	dd	MULTIBOOT_CHECKSUM
	
_start:
	mov		esp, _endbss
	sub		esp, 0xC0000000 - 0x101000
	push	ebx
	call	_loader

section '.bss' writeable
_stbss:
	rb	8192
_endbss:
loader.c

Code: Select all

#include <x86_32/paging.h>
#include <x86_32/multiboot.h>

#define PHYS(x)		((x) - 0xC0000000 + 0x101000)
#define LD(x)		((unsigned long)&x)

void loader(multiboot_info_t*) __attribute__((section(".loader")));
extern char sttext;	/* start of text section(virtual) */
extern char endtext;
extern char stdata;	/* start of data section(virtual) */
extern char enddata;
extern char stbss;
extern char endbss;
extern char end;		/* end of kernel(virtual) */

#define TEXT_START	LD(sttext)
#define	DATA_START	LD(stdata)
#define	BSS_START	LD(stbss)
#define TEXT_END	LD(endtext)
#define	DATA_END	LD(enddata)
#define	BSS_END		LD(endbss)
#define	TEXT_SIZE	(TEXT_END-TEXT_START)
#define	DATA_SIZE	(DATA_END-DATA_START)
#define	STACK_SIZE	(BSS_END-BSS_START)
#define	END			LD(end)

void archmain();

void
loader(multiboot_info_t *mbi) {
	unsigned long	*page_directory		= (unsigned long*)PHYS(PAGE_ALIGN(END));
	unsigned long   *page_table0		= page_directory + PAGE_SIZE; /* 1st MB and loader */
	unsigned long	*page_table1		= page_table0 + PAGE_SIZE; /* for main kernel */
	int				i;
	
	/* clearing page directory and pagetables */
	for(i = 0; i < 1024; i++)
		page_directory[i] = 
		page_table0[i] =
		page_table1[i] = 0;
	
	/* Creating page table for 1st MB and loader */
	page_directory[0] = (unsigned long)page_table0	| PDE_PRESENT
													| PDE_WRITEABLE;
	/* Creating page table for kernel */
	page_directory[PDE_ENTRY(TEXT_START)] =	(unsigned long)page_table1	| PDE_PRESENT
																		| PDE_WRITEABLE;	
	/* mapping 1st MiB */
	for(i = 0; i < 256; i++)
		page_table0[i] = (i*PAGE_SIZE)	| PTE_PRESENT
										| PTE_WRITEABLE;
	/* mapping loader */
	page_table0[256] = (1024*1024) | PTE_PRESENT;
	/* mapping '.bss' */
	for(i = 0; i < STACK_SIZE/PAGE_SIZE; i++) {
		/* mapping 1:1, for loader */
		page_table0[PTE_ENTRY(PHYS(BSS_START))+i] = PHYS(BSS_START+i*PAGE_SIZE) | PTE_PRESENT
																				| PTE_WRITEABLE;
		/* mapping to kernel */
		page_table1[PTE_ENTRY(BSS_START)+i]= PHYS(BSS_START+i*PAGE_SIZE)| PTE_PRESENT
																		| PTE_WRITEABLE;
	}
	/* mapping '.text' */
	for(i = 0; i < PAGE_ALIGN(TEXT_SIZE)/PAGE_SIZE; i++) {
		page_table1[PTE_ENTRY(TEXT_START)+i] = PHYS(TEXT_START+i*PAGE_SIZE)| PTE_PRESENT;
	}
	/* mapping '.data' */
	for(i = 0; i < PAGE_ALIGN(DATA_SIZE)/PAGE_SIZE; i++) {
		page_table1[PTE_ENTRY(DATA_START)+i] = PHYS(DATA_START+i*PAGE_SIZE)	| PTE_PRESENT
																			| PTE_WRITEABLE;
	}
	/* enable paging */
	__asm volatile(	"add	$(0xC0000000 - 0x101000), %%esp\n" /* set stack to kernel adresses */
					"movl	%0, %%eax\n"
					"movl	%%eax, %%cr3\n"
					"movl	%%cr0, %%eax\n"
					"orl	$0x80000000, %%eax\n"
					"movl	%%eax, %%cr0"::"m"(page_directory));

	archmain();
	for(;;);
}
paging.h

Code: Select all

#ifndef X86_32_PAGING_H
#define X86_32_PAGIND_H

#define	PAGE_SHIFT		(12)
#define PAGE_SIZE		(1UL << PAGE_SHIFT)

#define PAGE_BASE(x)	((x) & ~(PAGE_SIZE - 1))
#define PAGE_ALIGN(x)	(((x) + PAGE_SIZE) & ~(PAGE_SIZE - 1))
/* Page directory entry */
#define	PDE_ENTRY(x)		((x) >> 22)
#define PDE_PRESENT			(1UL << 0)
#define	PDE_WRITEABLE		(1UL << 1)
#define	PDE_USERACCESS		(1UL << 2)
#define PDE_WRITETHROUGH	(1UL << 3)
#define	PDE_CACHEDISABLE	(1UL << 4)
#define PDE_ACCESSED		(1UL << 5)
/* Page table entry */
#define	PTE_ENTRY(x)		(((x) >> 12) & 0x3ff)
#define PTE_PRESENT			(1UL << 0)
#define	PTE_WRITEABLE		(1UL << 1)
#define	PTE_USERACCESS		(1UL << 2)
#define PTE_WRITETHROUGH	(1UL << 3)
#define	PTE_CACHEDISABLE	(1UL << 4)
#define PTE_ACCESSED		(1UL << 5)
#define PTE_DIRTY			(1UL << 6)

#endif /* X86_32_PAGING_H */
main.c

Code: Select all

static int i = 1;
void
archmain() {
	for(;;); /* (;,;)-=<fhtagn!> */
}
link.ld

Code: Select all

OUTPUT_FORMAT("elf32-i386")
ENTRY(_start)
SECTIONS
{
	. = 0x00100000;
	.loader :
	{
		*(.loader)
	}
	. = 0xC0000000;
	.text ALIGN(0x1000) : AT(ADDR(.text) - 0xBFF00000 + 0x1000)
	{
		_sttext = .;
		*(.text)
		*(.rodata*)
		_endtext = .;
	}
	.data ALIGN(0x1000) : AT(ADDR(.data) - 0xBFF00000 + 0x1000)
	{
		_stdata = .;
		*(.data)
		_enddata = .;
	}
	.bss ALIGN(0x1000) : AT(ADDR(.bss) - 0xBFF00000 + 0x1000)
	{
		*(.bss)
		*(COMMON)
	}
	_end = .;
}
torshie
Member
Member
Posts: 89
Joined: Sun Jan 11, 2009 7:41 pm

Re: Higher Half loading

Post by torshie »

You'd better try bochs, and use its internal debugger. It's very difficult to find out the bug by just staring at the code.
wolfram
Posts: 19
Joined: Wed Aug 19, 2009 11:37 am
Location: Saint-Petersburg, Russia

Re: Higher Half loading

Post by wolfram »

WTF?!! I'm nothing understand! One time - tripple fault. The other time - all normal. May be my code depends on phrases of the moon???
Seriosly: may the code depends on phrases^W compiler versions? If I compile in Windows(cygwin GCC 3.4, AFAIR) I have got tripple faults. When I compile in Ubuntu(GCC 4.3) I haven't faults.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Higher Half loading

Post by neon »

Hello,
wolfram wrote:WTF?!! I'm nothing understand! One time - tripple fault. The other time - all normal. May be my code depends on phrases of the moon???
That is usually an indication of your code relying on uninitialized data.

As torshie said, you should run your system using the bochs debugger. If it triple faults in bochs, post the register dump and any information that repeats - that will help you in finding where and what the problem is, and give you the cause of the triple fault.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply