Page 1 of 1

Multiboot disabling interrupts

Posted: Sun Jun 23, 2013 5:47 am
by narke
Hi guys,

I changed the multiboot code of my project but interrupts aren't called anymore.
If I replace the new multiboot code with an old one then interrupts are called again.

I wasn't versed in asm for years so I suspect I made an obvious error but I'm not seeing it.

The original multicode is here: https://github.com/narke/Versatile/blob ... ultiboot.S
The linker script is this one: https://github.com/narke/Versatile/blob ... script.lds

Can someone tell what I messed up please?

The new one written in NASM is this:

Code: Select all

; Declare constants used for creating a multiboot header.
PAGE_ALIGN       equ  1<<0                   		; align loaded modules on page boundaries
MEMORY_INFO      equ  1<<1                   		; provide memory map
HEADER_FLAGS	  equ  PAGE_ALIGN | MEMORY_INFO      	; this is the Multiboot 'flag' field
HEADER_MAGIC	  equ  0x1BADB002             		; 'magic number' lets bootloader find the header
CHECKSUM    	  equ  -(HEADER_MAGIC + HEADER_FLAGS)	; checksum of above, to prove we are multiboot
STACK_SIZE	    equ  0x4000							; the size of the stack is 16KB


struc multiboot_header
    .magic:			resb 64
    .flags:			resb 64
    .checksum:		resb 64
    .header_addr:	resb 64
    .load_addr:		resb 64
    .load_end_addr:	resb 64
    .bss_end_addr:	resb 64
    .entry_addr:	resb 64
endstruc


; Declare a header as in the Multiboot Standard.
section .multiboot
align 4
	dd HEADER_MAGIC
	dd HEADER_FLAGS
	dd CHECKSUM
	dd multiboot_header
	dd multiboot_entry


; The stack is defined here
[section .init_stack nobits alloc noexec write align=4]
stack_bottom:
	resb STACK_SIZE
stack_top:
	
 
; The linker script specifies _start as the entry point to the kernel and the
; bootloader will jump to this position once the kernel has been loaded. It
; doesn't make sense to return from this function as the bootloader is gone.
section .text
global _start
_start:
multiboot_entry:
	; Set up a stack
	mov ebp, stack_top
	mov esp, ebp
	
	; Set EFLAGS to 0
	push 0
	; pop stack into the EFLAGS register
	popf

	; Push the magic and the address on the stack, so that they
	; will be the parameters of the C main function
	push ebx
	push eax
 
	; Calling kernel's entry point.
	extern versatile_main
	call versatile_main
 
	; In case the function returns, we'll want to put the computer into an
	; infinite loop. To do that, we use the clear interrupt ('cli') instruction
	; to disable interrupts, the halt instruction ('hlt') to stop the CPU until
	; the next interrupt arrives, and jumping to the halt instruction if it ever
	; continues execution, just to be safe.
	cli
	
.hang:
	hlt
	jmp .hang
	

Re: Multiboot disabling interrupts

Posted: Sun Jun 23, 2013 9:54 am
by Combuster
If you use the A.out kludge, do it properly or don't do it. The header and entry fields are only half the needed fields and they are not used.

Re: Multiboot disabling interrupts

Posted: Sun Jun 23, 2013 11:34 am
by narke
Combuster wrote:If you use the A.out kludge, do it properly or don't do it. The header and entry fields are only half the needed fields and they are not used.
I tweaked to get this: http://pastebin.com/5zw951mw, but I'm not understanding why it's not equivalent to this: https://github.com/narke/Versatile/blob ... ultiboot.S.

With the latter interrupts works, with my rewrite I'm able to boot and display characters but I'm not getting interrupts anymore.

Re: Multiboot disabling interrupts

Posted: Sun Jun 23, 2013 11:44 pm
by Combuster
this: http://pastebin.com/5zw951mw, but I'm not understanding why it's not equivalent to this: https://github.com/narke/Versatile/blob ... ultiboot.S.
I see you can't even spot the difference of 20 added/removed bytes in the multiboot header...

Re: Multiboot disabling interrupts

Posted: Fri Jun 28, 2013 5:15 pm
by narke
I solved it by rewriting this way:

Code: Select all

; @see http://wiki.osdev.org/Bare_Bones
; Slightly modified by me

extern roentgenium_main	; this is our kernel's entry point

; setting up the Multiboot header - see GRUB docs for details
MBALIGN 	        equ  1<<0		; align loaded modules on page boundaries
MEMINFO		equ  1<<1		; provide memory map
FLAGS		equ  MBALIGN | MEMINFO	; this is the Multiboot 'flag' field
MAGIC		equ  0x1BADB002		; 'magic number' lets bootloader find the header
CHECKSUM	equ  -(MAGIC + FLAGS)	; checksum required to prove that we are multiboot
STACK_SIZE	equ  0x4000		; our stack size is 16KiB


; The multiboot header must come first.
section .multiboot

; Multiboot header must be aligned on a 4-byte boundary
align 4

multiboot_header:
dd MAGIC
dd FLAGS
dd -(MAGIC + FLAGS)

; The beginning of our kernel code
section .text

global multiboot_entry
multiboot_entry:
	mov esp, stack + STACK_SIZE	; set up the stack
	mov [magic], eax		; multiboot magic number
	mov [multiboot_info], ebx	; multiboot data structure

	call roentgenium_main		; calling the kernel

hang:
	hlt				; something bad happened, machine halted
	jmp hang



; reserve initial kernel stack space
stack:
resb STACK_SIZE		; reserve 16 KiB stack
multiboot_info: resd 1	; we will use this in kernel's main
magic: resd 1		; we will use this in kernel's main
and the linker script:

Code: Select all

ENTRY (multiboot_entry)

SECTIONS
{
    /* Roentgenium is loaded at 0x00100000.
	A multi-boot compatible kernel cannot be loaded before the 1MB mark, 
	it must be loaded at or above 1MB. */
    . = 0x00100000;
    
    .multiboot :
    {
        /* The multiboot header must come within the first 8K of
	our kernel  */
	*(.multiboot);

	/* 32 bit aligned as required by the multiboot specs */	
	LONG(0);
    }

    .text ALIGN (0x1000) :
    {
        *(.text)
    }

    .rodata ALIGN (0x1000) :
    {
        *(.rodata*)
    }

    .data ALIGN (0x1000) :
    {
        *(.data)
    }

    .bss :
    {
        sbss = .;
        *(COMMON)
        *(.bss)
        ebss = .;
    }
}
I want to thank also the people on osdev's IRC.