My new start.s

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
User avatar
Jeko
Member
Member
Posts: 500
Joined: Fri Mar 17, 2006 12:00 am
Location: Napoli, Italy

My new start.s

Post by Jeko »

This is my start.s file, loaded by GRUB... But there are some error messages from gcc compiler...
This is the code:

Code: Select all

.file	"start.S"

.section .text

; // Address adjustement.
#define ADDRADJUST	0xBFF00000

; // Kernel virtual start address.
#define K_VIR_START	0xC0000000

; // Kernel physiscal start address.
#define K_PHYS_START	0x100000

; // Paging constants.
#define	P_PRESENT 	0x01
#define P_WRITE		0x02

; // Page size.
#define PAGE_SHIFT	12
#define PAGE_SIZE	(1 << PAGE_SHIFT)

; // Page directory.
#define K_PDE		0x1000
; // Kernel page table #0 (4MB).
#define K_PTE		0x2000
; // First 4MB Identity-map page table.
#define I_PTE		0x3000

; // Multiboot constants.
#define MULTIBOOT_PAGE_ALIGN	(1 << 0)
#define MULTIBOOT_MEMORY_INFO	(1 << 1)
#define MULTIBOOT_HEADER_MAGIC	(0x1BADB002)
#define MULTIBOOT_HEADER_FLAGS	(MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO)
#define CHECKSUM		-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

.global _start
.global boot_info

.extern k_main
.extern K_STACK_START

_start:
	jmp	entry

; // Multiboot header (...required by GRUB!).
.align 4
	.long MULTIBOOT_HEADER_MAGIC
	.long MULTIBOOT_HEADER_FLAGS
	.long CHECKSUM

; // Linear address of a block of system bootstrap informations.
.align 4
	boot_info: .long	0

entry:
	; // Turn off floppy motor.
	movw	$0x3f2, %dx
	movb	$0x0c, %al
	outb	%al, %dx

	; // Save multiboot structure pointer.
	movl	%ebx, (boot_info-ADDRADJUST)

	; // Setup paging.
	xorl	%eax, %eax
	movl	$K_PDE, %edi
	movl	$1024, %ecx
	cld
	rep	stosl

	; // Setup first 4MB as identity-map (I_PTE).
	movl	$(P_PRESENT | P_WRITE), %eax
	movl	$1024, %ecx
	movl	$I_PTE, %edi

Map_I_PTE:
	stosl
	add	$PAGE_SIZE, %eax
	loop	Map_I_PTE

	; // Setup the kernel page table (K_PTE).
	movl	$(K_PHYS_START | P_PRESENT | P_WRITE), %eax
	movl	$1024, %ecx
	movl	$K_PTE, %edi

Map_K_PTE:
	stosl
	add	$PAGE_SIZE, %eax
	loop	Map_K_PTE

	; // Store the identity-map table (first 4MB).
	movl $(I_PTE | P_PRESENT | P_WRITE), K_PDE

	; // Store the kernel table (4MB of kernel virtual space).
	movl $(K_PTE | P_PRESENT | P_WRITE), K_PDE+(K_VIR_START>>PAGE_SHIFT)/1024*4

	; // Map page directory into itself.
	movl $(K_PDE | P_PRESENT | P_WRITE), K_PDE+1023*4

	; // Setup PDBR.
	movl	$K_PDE, %eax
	movl	%eax, %cr3

	; // Enable paging.
	movl	%cr0, %eax
	orl	$0x80010000, %eax ; // cr0.PG = cr0.WP = 1
	movl	%eax, %cr0

	; // Reload global descriptor table (GDT).
	lgdtl	(gdtr)

	; // Reflush CS register.
	ljmp	$0x10, $1f

1:
	; // Update segment registers.
	movw	$0x08, %ax
	movw	%ax, %ds
	movw	%ax, %es
	movw	%ax, %fs
	movw	%ax, %gs

	; // Initialize kernel stack pointer.
	movw	%ax, %ss
	movl	$K_STACK_START, %esp

	; // Jump to the kernel main routine.
	jmp	k_main

.align 4
gdtr:
	.word (gdt_end - gdt - 1)	; // GDT limit.
	.long (gdt - ADDRADJUST)	; // GDT linear address.

.align 4
gdt:
; // Dummy descriptor 0x00.
	.word 0			; // Limit 15:0
	.word 0			; // Base 15:0
	.byte 0			; // Base 23:16
	.byte 0			; // Access byte (descriptor type)
	.byte 0			; // Limits 19:16, Flags
	.byte 0			; // Base 31:24

; // Data descriptor 0x08.
	.word 0xFFFF		; // Limit 15:0
	.word 0			; // Base 15:0
	.byte 0			; // Base 23:16
	.byte 0x92         	; // Data, Present, Writeable (1,0,0,1,0010)
	.byte 0xCF		; // G=1, D=1, 0, AVL=0, 1111=F: Limit/Length (1,1,0,0,1111)
	.byte 0			; // Base 31:24

; // Code descriptor 0x10.
	.word 0xFFFF		; // Limit 15:0
	.word 0			; // Base 15:0
	.byte 0			; // Base 23:16
	.byte 0x9A		; // Code, Present, Non-conforming, Exec/read(1,0,0,1,1110)
	.byte 0xCF		; // G=1, D=1, 0, AVL=0, 1111=F: Limit/Length (1,1,0,0,1111)
	.byte 0			; // Base 31:24
gdt_end:
These are error messages:

Code: Select all

gcc -Wall -O -floop-optimize2 -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -nostdinc -I include -ffreestanding -fno-stack-protector -c boot/start.s -o boot/start.o
boot/start.s: Assembler messages:
boot/start.s:72: Error: undefined symbol `P_PRESENT' in operation
boot/start.s:72: Error: undefined symbol `P_WRITE' in operation
boot/start.s:81: Error: undefined symbol `K_PHYS_START' in operation
boot/start.s:81: Error: undefined symbol `P_PRESENT' in operation
boot/start.s:81: Error: undefined symbol `P_WRITE' in operation
boot/start.s:90: Error: undefined symbol `I_PTE' in operation
boot/start.s:90: Error: undefined symbol `P_PRESENT' in operation
boot/start.s:90: Error: undefined symbol `P_WRITE' in operation
boot/start.s:93: Error: undefined symbol `K_VIR_START' in operation
boot/start.s:93: Error: undefined symbol `PAGE_SHIFT' in operation
boot/start.s:93: Error: undefined symbol `K_PTE' in operation
boot/start.s:93: Error: undefined symbol `P_PRESENT' in operation
boot/start.s:93: Error: undefined symbol `P_WRITE' in operation
boot/start.s:96: Error: undefined symbol `K_PDE' in operation
boot/start.s:96: Error: undefined symbol `P_PRESENT' in operation
boot/start.s:96: Error: undefined symbol `P_WRITE' in operation
boot/start.s:62: Error: can't resolve `boot_info' {.text section} - `ADDRADJUST' {*UND* section}
boot/start.s:130: Error: can't resolve `.text' {.text section} - `ADDRADJUST' {*UND* section}
Last edited by Jeko on Fri Feb 22, 2008 8:32 am, edited 1 time in total.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

You're using preprocessor macros, but you haven't run your code through the preprocessor, it seems!

Try running it through "cpp" first.
User avatar
Jeko
Member
Member
Posts: 500
Joined: Fri Mar 17, 2006 12:00 am
Location: Napoli, Italy

Post by Jeko »

JamesM wrote:You're using preprocessor macros, but you haven't run your code through the preprocessor, it seems!

Try running it through "cpp" first.
how?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

I'm not an expert on GAS, but I believe gcc can be easily made to preprocess it for you - possibly by changing the extension of your file to .S (note the capital, this is convention for "assembler file needing preprocessing").

else, run these commands instead of your gcc command.

Code: Select all

cpp -P -x assembler-with-cpp boot/start.s tmp.s
gcc -Wall -O -floop-optimize2 -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -nostdinc -I include -ffreestanding -fno-stack-protector -c tmp.s -o boot/start.o 
User avatar
Jeko
Member
Member
Posts: 500
Joined: Fri Mar 17, 2006 12:00 am
Location: Napoli, Italy

Post by Jeko »

JamesM wrote:I'm not an expert on GAS, but I believe gcc can be easily made to preprocess it for you - possibly by changing the extension of your file to .S (note the capital, this is convention for "assembler file needing preprocessing").

else, run these commands instead of your gcc command.

Code: Select all

cpp -P -x assembler-with-cpp boot/start.s tmp.s
gcc -Wall -O -floop-optimize2 -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -nostdinc -I include -ffreestanding -fno-stack-protector -c tmp.s -o boot/start.o 
Thank you very much!
I now need another small thing... How can I reserve stack space for kernel and how much space must I reserve?
I'm doing this with (at the end of start.asm):

Code: Select all

.section .bss
.align 32
stack:
	resb 0x4000
So I reserve 0x4000 with the instruction resb. But there are two problems...
1) 0x4000 is too much or too low?
2)

Code: Select all

start.S: Assembler messages:
start.S:161: Error: no such instruction: `resb $0x4000'
xyzzy
Member
Member
Posts: 391
Joined: Wed Jul 25, 2007 8:45 am
Libera.chat IRC: aejsmith
Location: London, UK
Contact:

Post by xyzzy »

I think resb is NASM only. Also, 0x1000 should suffice, which is 1 page, or 4KB.

Code: Select all

 .section .bss
.align 0x1000

stack:         .fill   0x1000
That is what I use, works with GAS
User avatar
Jeko
Member
Member
Posts: 500
Joined: Fri Mar 17, 2006 12:00 am
Location: Napoli, Italy

Post by Jeko »

AlexExtreme wrote:I think resb is NASM only. Also, 0x1000 should suffice, which is 1 page, or 4KB.

Code: Select all

 .section .bss
.align 0x1000

stack:         .fill   0x1000
That is what I use, works with GAS
Thank you. Now it works very well!

But, after I unset identical_map pages with:

Code: Select all

//! Page tables area start address.
#define PAGE_TABLE_MAP		(0xFFC00000)

//! Page tables area end address.
#define PAGE_DIR_MAP		(0xFFC00000 + (PAGE_TABLE_MAP / (1024)))

//! Access to the page directory entry referred to the
//! virtual address \p addr.
#define ADDR_TO_PDE(addr)	(unsigned int *)(PAGE_DIR_MAP + (((unsigned int) (addr) / (1024 * 1024))&(~0x3)))

*ADDR_TO_PDE( 0 ) = 0;
I can still write to video memory at 0xB8000. It's normal? Maybe there is an error in my code? Or maybe I must invalidate the page?

However I want to give thanks to all members of this forum. Thank you very much for your (for me) significant help!
Post Reply