HelenOS sources
#include <abi/asmtool.h>
#include <arch/boot/boot.h>
#include <arch/boot/memmap.h>
#include <arch/mm/page.h>
#include <arch/pm.h>
#include <genarch/multiboot/multiboot.h>
#include <arch/cpuid.h>
#include <arch/cpu.h>
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
.section K_TEXT_START, "ax"
.code32
.macro pm_error msg
movl \msg, %esi
jmp pm_error_halt
.endm
.macro pm_status msg
#ifdef CONFIG_EGA
pushl %esi
movl \msg, %esi
call pm_early_puts
popl %esi
#endif
.endm
.macro pm2_status msg
pushl \msg
call early_puts
.endm
.align 4
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
.long multiboot_header
.long unmapped_start
.long 0
.long 0
.long multiboot_image_start
SYMBOL(multiboot_image_start)
cli
cld
movl $START_STACK, %esp
lgdtl bootstrap_gdtr
lidtl bootstrap_idtr
movw $GDT_SELECTOR(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds
movw %cx, %ss
jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point
multiboot_meeting_point:
movl %eax, multiboot_eax
movl %ebx, multiboot_ebx
pm_status $status_prot
#include "vesa_prot.inc"
#ifndef PROCESSOR_i486
pm_status $status_prot2
movl $(INTEL_CPUID_LEVEL), %eax
cpuid
cmp $0x0, %eax
jbe pse_unsupported
movl $(INTEL_CPUID_STANDARD), %eax
cpuid
bt $(INTEL_PSE), %edx
jnc pse_unsupported
pm_status $status_pse
call map_kernel_pse
jmp stack_init
#endif
pse_unsupported:
pm_status $status_non_pse
call map_kernel_non_pse
stack_init:
pushl $0
movl %esp, %ebp
pm2_status $status_prot3
pushl multiboot_ebx
pushl multiboot_eax
call ia32_pre_main
pm2_status $status_main
call main_bsp
cli
hlt0:
hlt
jmp hlt0
FUNCTION_BEGIN(map_kernel_pse)
movl %cr4, %ecx
orl $CR4_PSE, %ecx
andl $~CR4_PAE, %ecx
movl %ecx, %cr4
movl $(page_directory + 0), %esi
movl $(page_directory + 2048), %edi
xorl %ecx, %ecx
xorl %ebx, %ebx
floop_pse:
movl $(PDE_4M | PDE_RW | PDE_P), %eax
orl %ebx, %eax
movl %eax, (%esi, %ecx, 4)
movl %eax, (%edi, %ecx, 4)
addl $(4 * 1024 * 1024), %ebx
incl %ecx
cmpl $512, %ecx
jl floop_pse
movl %esi, %cr3
movl %cr0, %ebx
orl $CR0_PG, %ebx
movl %ebx, %cr0
ret
FUNCTION_END(map_kernel_pse)
FUNCTION_BEGIN(map_kernel_non_pse)
movl %cr4, %ecx
andl $~CR4_PAE, %ecx
movl %ecx, %cr4
call calc_kernel_end
call find_mem_for_pt
mov kernel_end, %esi
mov free_area, %ecx
cmpl %esi, %ecx
jbe use_kernel_end
mov %ecx, %esi
andl $(~(PAGE_SIZE - 1)), %esi
use_kernel_end:
addl $(PAGE_SIZE - 1), %esi
andl $(~(PAGE_SIZE - 1)), %esi
movl %esi, pt_loc
movl $KA2PA(ballocs), %edi
movl %esi, (%edi)
addl $4, %edi
movl $(2 * 1024 * 1024), (%edi)
xorl %ecx, %ecx
xorl %ebx, %ebx
floop_pt:
movl $(PTE_RW | PTE_P), %eax
orl %ebx, %eax
movl %eax, (%esi, %ecx, 4)
addl $PAGE_SIZE, %ebx
incl %ecx
cmpl $(512 * 1024), %ecx
jl floop_pt
movl $(page_directory + 0), %esi
movl $(page_directory + 2048), %edi
xorl %ecx, %ecx
movl pt_loc, %ebx
floop:
movl $(PDE_RW | PDE_P), %eax
orl %ebx, %eax
movl %eax, (%esi, %ecx, 4)
movl %eax, (%edi, %ecx, 4)
addl $PAGE_SIZE, %ebx
incl %ecx
cmpl $512, %ecx
jl floop
movl %esi, %cr3
movl %cr0, %ebx
orl $CR0_PG, %ebx
movl %ebx, %cr0
ret
FUNCTION_END(map_kernel_non_pse)
calc_kernel_end:
movl $KA2PA(kdata_end), %edi
movl %edi, kernel_end
ret
find_mem_for_pt:
cmpl $MULTIBOOT_LOADER_MAGIC, multiboot_eax
je check_multiboot_map
ret
check_multiboot_map:
movl multiboot_ebx, %ebx
movl (%ebx), %edx
andl $MULTIBOOT_INFO_FLAGS_MMAP, %edx
jnz use_multiboot_map
ret
use_multiboot_map:
movl MULTIBOOT_INFO_OFFSET_MMAP_ADDR(%ebx), %edx
movl %edx, %ecx
addl MULTIBOOT_INFO_OFFSET_MMAP_LENGTH(%ebx), %ecx
check_memmap_loop:
cmpl $MEMMAP_MEMORY_AVAILABLE, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_TYPE(%edx)
jnz next_region
cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE + 4(%edx)
jnz next_region
cmpl $(2 * 1024 * 1024 + PAGE_SIZE), MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE(%edx)
jbe next_region
cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS + 4(%edx)
jz found_region
next_region:
cmp %ecx, %edx
jbe next_region_do
ret
next_region_do:
addl MULTIBOOT_MEMMAP_OFFSET_SIZE(%edx), %edx
addl $MULTIBOOT_MEMMAP_SIZE_SIZE, %edx
jmp check_memmap_loop
found_region:
mov MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS(%edx), %ecx
add MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE(%edx), %ecx
sub $(2 * 1024 * 1024), %ecx
mov %ecx, free_area
ret
pm_error_halt:
movl $0xb8000, %edi
xorl %eax, %eax
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $2000, %ax
jb err_cursor_ok
movw $1998, %ax
err_cursor_ok:
movw %ax, %bx
shl $1, %eax
addl %eax, %edi
err_ploop:
lodsb
cmp $0, %al
je err_ploop_end
movb $0x0c, %ah
stosw
inc %bx
cmp $2000, %bx
jb err_ploop
movl %esi, %edx
movl $0xb80a0, %esi
movl $0xb8000, %edi
movl $960, %ecx
rep movsl
xorl %eax, %eax
movl $40, %ecx
rep stosl
movl %edx, %esi
movl $0xb8f00, %edi
movw $1920, %bx
jmp err_ploop
err_ploop_end:
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt1:
hlt
jmp hlt1
pm_early_puts:
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
movl $0xb8000, %edi
xorl %eax, %eax
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $2000, %ax
jb pm_puts_cursor_ok
movw $1998, %ax
pm_puts_cursor_ok:
movw %ax, %bx
shl $1, %eax
addl %eax, %edi
pm_puts_ploop:
lodsb
cmp $0, %al
je pm_puts_ploop_end
movb $0x0a, %ah
stosw
inc %bx
cmp $2000, %bx
jb pm_puts_ploop
movl %esi, %edx
movl $0xb80a0, %esi
movl $0xb8000, %edi
movl $960, %ecx
rep movsl
xorl %eax, %eax
movl $40, %ecx
rep stosl
movl %edx, %esi
movl $0xb8f00, %edi
movw $1920, %bx
jmp pm_puts_ploop
pm_puts_ploop_end:
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
ret
early_puts:
#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
pushl %edi
movl 0x08(%ebp), %esi
movl $(PA2KA(0xb8000)), %edi
xorl %eax, %eax
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
inb %dx, %al
cmp $2000, %ax
jb early_puts_cursor_ok
movw $1998, %ax
early_puts_cursor_ok:
movw %ax, %bx
shl $1, %eax
addl %eax, %edi
early_puts_ploop:
lodsb
cmp $0, %al
je early_puts_ploop_end
movb $0x0e, %ah
stosw
inc %bx
cmp $2000, %bx
jb early_puts_ploop
movl %esi, %edx
movl $(PA2KA(0xb80a0)), %esi
movl $(PA2KA(0xb8000)), %edi
movl $960, %ecx
rep movsl
xorl %eax, %eax
movl $40, %ecx
rep stosl
movl %edx, %esi
movl $(PA2KA(0xb8f00)), %edi
movw $1920, %bx
jmp early_puts_ploop
early_puts_ploop_end:
movw $0x3d4, %dx
movb $0xe, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx
movb $0xf, %al
outb %al, %dx
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
popl %edi
popl %esi
popl %ebx
leave
#endif
ret
#include "vesa_real.inc"
.section K_DATA_START, "aw", @progbits
.align 4096
page_directory:
.space 4096, 0
SYMBOL(bootstrap_idtr)
.word 0
.long 0
SYMBOL(bootstrap_gdtr)
.word GDT_SELECTOR(GDT_ITEMS)
.long KA2PA(gdt)
SYMBOL(multiboot_eax)
.long 0
SYMBOL(multiboot_ebx)
.long 0
pt_loc:
.long 0
kernel_end:
.long 0
free_area:
.long 0
status_prot:
.asciz "[prot] "
status_pse:
.asciz "[pse] "
status_non_pse:
.asciz "[non_pse] "
status_vesa_copy:
.asciz "[vesa_copy] "
status_multiboot_cmdline:
.asciz "[multiboot_cmdline] "
status_vesa_real:
.asciz "[vesa_real] "
status_prot2:
.asciz "[prot2] "
status_prot3:
.asciz "[prot3] "
status_main:
.asciz "[main] "
HelenOS homepage, sources at GitHub