480 lines
7.4 KiB
ArmAsm
480 lines
7.4 KiB
ArmAsm
.code16
|
|
main:
|
|
ljmp $0x0,$entry
|
|
|
|
entry:
|
|
/* Set up initial segments */
|
|
xor %ax, %ax
|
|
mov %ax, %ds
|
|
mov %ax, %ss
|
|
|
|
/* Don't lose dl */
|
|
mov %dl, boot_disk
|
|
|
|
/* Initialize stack to just below us */
|
|
mov $0x7c00, %ax
|
|
mov %ax, %sp
|
|
|
|
/* Prepare to switch to unreal mode */
|
|
cli
|
|
push %ds
|
|
push %es
|
|
|
|
/* Enable A20 */
|
|
in $0x92, %al
|
|
or $2, %al
|
|
out %al, $0x92
|
|
|
|
/* Switch to unreal mode */
|
|
lgdtw gdtr
|
|
mov %cr0, %eax
|
|
or $1, %al
|
|
mov %eax, %cr0
|
|
jmp pmode
|
|
pmode:
|
|
mov $0x10, %bx
|
|
mov %bx, %ds
|
|
mov %bx, %es
|
|
and $0xfe, %al
|
|
mov %eax, %cr0
|
|
jmp unrealmode
|
|
unrealmode:
|
|
pop %es
|
|
pop %ds
|
|
|
|
/* Clear the screen */
|
|
mov $0, %al
|
|
movl $3840, %ecx
|
|
movl $0xb8000, %edi
|
|
addr32 rep stosb
|
|
|
|
/* Check if we can actually go to long mode on this */
|
|
mov $0x80000001, %eax
|
|
cpuid
|
|
and $0x20000000, %edx
|
|
jnz can_long
|
|
|
|
movl $str_Need_long, %esi
|
|
call print_string
|
|
jmp _oh_no
|
|
|
|
can_long:
|
|
/* Spot check memory */
|
|
movl $0x12345678, %eax
|
|
movl $0x5000000, %ebx
|
|
movl %eax, (%ebx)
|
|
movl (%ebx), %edx
|
|
cmp %edx, %eax
|
|
jz good_memory
|
|
|
|
movl $str_More_mem, %esi
|
|
call print_string
|
|
|
|
_oh_no:
|
|
jmp _oh_no
|
|
|
|
good_memory:
|
|
/* Ask for drive params */
|
|
mov $0x48, %ah
|
|
mov boot_disk, %dl
|
|
mov $drive_params, %si
|
|
int $0x13
|
|
|
|
.extern _bss_start
|
|
|
|
boot_from_cd:
|
|
/* Collect information on lower memory. */
|
|
mov $0x500, %ax
|
|
mov %ax, %es
|
|
clc
|
|
int $0x12
|
|
mov %ax, lower_mem
|
|
|
|
/* Collect information on upper memory. */
|
|
mov $0x0, %di
|
|
call do_e820
|
|
jc hang
|
|
|
|
/* Get video mode info */
|
|
mov $0, %ax
|
|
mov %ax, %es
|
|
mov $vbe_cont_info, %di
|
|
mov $0x4F00, %ax
|
|
int $0x10
|
|
|
|
/* Actually switch to protected mode. */
|
|
mov %cr0, %eax
|
|
or $1, %eax
|
|
mov %eax, %cr0
|
|
|
|
mov $0x10, %ax
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
mov %ax, %fs
|
|
mov %ax, %gs
|
|
mov %ax, %ss
|
|
|
|
cli
|
|
|
|
.global bios_main
|
|
ljmp $0x08,$bios_main
|
|
|
|
hang:
|
|
jmp hang
|
|
|
|
do_e820:
|
|
xor %ebx, %ebx
|
|
xor %bp, %bp
|
|
mov $0x534D4150, %edx
|
|
mov $0xe820, %eax
|
|
movl $0x1,%es:20(%di)
|
|
mov $24, %ecx
|
|
int $0x15
|
|
jb do_e820.failed
|
|
mov $0x534D4150, %edx
|
|
cmp %edx, %eax
|
|
jne do_e820.failed
|
|
test %ebx, %ebx
|
|
je do_e820.failed
|
|
jmp do_e820.jmpin
|
|
do_e820.e820lp:
|
|
mov $0xe820, %eax
|
|
movl $0x1,%es:20(%di)
|
|
mov $24, %ecx
|
|
int $0x15
|
|
jb do_e820.e820f
|
|
mov $0x534D4150, %edx
|
|
do_e820.jmpin:
|
|
jcxz do_e820.skipent
|
|
cmp $20, %cl
|
|
jbe do_e820.notext
|
|
testb $0x1, %es:20(%di)
|
|
je do_e820.skipent
|
|
do_e820.notext:
|
|
mov %es:8(%di), %ecx
|
|
or %es:12(%di), %ecx
|
|
jz do_e820.skipent
|
|
inc %bp
|
|
add $24, %di
|
|
do_e820.skipent:
|
|
test %ebx, %ebx
|
|
jne do_e820.e820lp
|
|
do_e820.e820f:
|
|
mov %bp, mmap_ent
|
|
clc
|
|
ret
|
|
do_e820.failed:
|
|
stc
|
|
ret
|
|
|
|
print_string:
|
|
movl $0xb8000, %edi
|
|
print_string.loop:
|
|
movb (%esi), %ah
|
|
cmp $0, %ah
|
|
je print_string.exit
|
|
movb %ah, (%edi)
|
|
inc %edi
|
|
movb $7, (%edi)
|
|
inc %esi
|
|
inc %edi
|
|
jmp print_string.loop
|
|
print_string.exit:
|
|
ret
|
|
|
|
pm_stack:
|
|
.quad 0
|
|
|
|
.global do_bios_call
|
|
do_bios_call:
|
|
.code32
|
|
/* Standard function entry point stuff */
|
|
push %ebp
|
|
mov %esp, %ebp
|
|
push %eax
|
|
push %ebx
|
|
push %ecx
|
|
push %edx
|
|
push %esi
|
|
push %edi
|
|
/* Save stack because bios might mess it up? */
|
|
movl %esp, %eax
|
|
movl %eax, (pm_stack)
|
|
|
|
/* Prepare intermediary mode */
|
|
mov $0x20, %ax
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
mov %ax, %fs
|
|
mov %ax, %gs
|
|
mov %ax, %ss
|
|
|
|
/* Enable intermediary mode */
|
|
ljmp $0x18,$do_bios_call.0
|
|
|
|
do_bios_call.0:
|
|
.code16
|
|
/* Disable protected mode */
|
|
mov %cr0, %eax
|
|
and $~1, %eax
|
|
mov %eax, %cr0
|
|
|
|
/* Jump to deactivate protected mode */
|
|
ljmp $0x0,$do_bios_call.1
|
|
|
|
do_bios_call.1:
|
|
/* Set up real mode segments */
|
|
xor %ax, %ax
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
mov %ax, %fs
|
|
mov %ax, %gs
|
|
mov %ax, %ss
|
|
|
|
/* Enable interrupts while BIOS is active */
|
|
sti
|
|
|
|
/* Function switch */
|
|
movl 32(%esp), %ebx
|
|
|
|
/* 1: Read disk */
|
|
mov $0x01, %ax
|
|
cmp %bx, %ax
|
|
je do_bios_call.read_disk
|
|
|
|
/* 2: Query mode index */
|
|
mov $0x02, %ax
|
|
cmp %bx, %ax
|
|
je do_bios_call.query_mode
|
|
|
|
/* 3: Set mode */
|
|
mov $0x03, %ax
|
|
cmp %bx, %ax
|
|
je do_bios_call.set_mode
|
|
|
|
mov $0x04, %ax
|
|
cmp %bx, %ax
|
|
je do_bios_call.test_key
|
|
|
|
/* Else: Bad call, jump to loop. */
|
|
jmp do_bios_call.done
|
|
|
|
do_bios_call.read_disk:
|
|
mov $0x42, %ah /* Extended read */
|
|
mov boot_disk, %dl /* Using our boot disk */
|
|
mov $dap, %si /* From the DAP below */
|
|
int $0x13
|
|
jmp do_bios_call.done
|
|
|
|
do_bios_call.query_mode:
|
|
movl 36(%esp), %ecx
|
|
mov $0x0, %ax
|
|
mov %ax, %es
|
|
mov $vbe_info, %edi
|
|
mov $0x4F01, %ax
|
|
int $0x10
|
|
jmp do_bios_call.done
|
|
|
|
do_bios_call.set_mode:
|
|
movl 36(%esp), %ebx
|
|
mov $0x4F02, %ax
|
|
int $0x10
|
|
jmp do_bios_call.done
|
|
|
|
do_bios_call.test_key:
|
|
movl 36(%esp), %ebx
|
|
xor %ax, %ax
|
|
mov %bl, %ah
|
|
int $0x16
|
|
movl %eax, 20(%esp)
|
|
jmp do_bios_call.done
|
|
|
|
do_bios_call.done:
|
|
/* Disable interrupts again */
|
|
cli
|
|
|
|
/* Restore data segment, gdt */
|
|
xor %ax,%ax
|
|
mov %ax, %ds
|
|
lgdtw gdtr
|
|
|
|
/* Enable protected mode */
|
|
mov %cr0, %eax
|
|
or $1, %eax
|
|
mov %eax, %cr0
|
|
|
|
/* Jump to activate protected mode */
|
|
ljmp $0x08,$do_bios_call.2
|
|
|
|
do_bios_call.2:
|
|
.code32
|
|
/* Restore protected mode data segments */
|
|
mov $0x10, %ax
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
mov %ax, %fs
|
|
mov %ax, %gs
|
|
mov %ax, %ss
|
|
|
|
/* Restore stack */
|
|
movl (pm_stack), %eax
|
|
movl %eax, %esp
|
|
|
|
/* Pop callee-saved registers we may messed with */
|
|
pop %edi
|
|
pop %esi
|
|
pop %edx
|
|
pop %ecx
|
|
pop %ebx
|
|
pop %eax
|
|
pop %ebp
|
|
|
|
/* Return */
|
|
ret
|
|
|
|
.align 8
|
|
gdtr:
|
|
.word gdt_end - gdt_base - 1
|
|
.long gdt_base
|
|
|
|
gdt_base:
|
|
.quad 0
|
|
.word 0xFFFF
|
|
.word 0
|
|
.byte 0
|
|
.byte 0x9a
|
|
.byte 0xcf
|
|
.byte 0
|
|
|
|
.word 0xffff
|
|
.word 0
|
|
.byte 0
|
|
.byte 0x92
|
|
.byte 0xcf
|
|
.byte 0
|
|
|
|
.word 0xffff
|
|
.word 0
|
|
.byte 0
|
|
.byte 0x9e
|
|
.byte 0
|
|
.byte 0
|
|
|
|
.word 0xffff
|
|
.word 0
|
|
.byte 0
|
|
.byte 0x92
|
|
.byte 0
|
|
.byte 0
|
|
gdt_end:
|
|
|
|
.global boot_disk
|
|
boot_disk:
|
|
.byte 0
|
|
|
|
.global mmap_ent
|
|
mmap_ent:
|
|
.byte 0
|
|
.byte 0
|
|
|
|
.global lower_mem
|
|
lower_mem:
|
|
.byte 0
|
|
.byte 0
|
|
|
|
.align 4
|
|
.global dap
|
|
dap:
|
|
.byte 16
|
|
.byte 0 /* always 0 */
|
|
.global dap_sectors
|
|
dap_sectors:
|
|
.word 1
|
|
.global dap_buffer
|
|
dap_buffer:
|
|
.long 0x0
|
|
.global dap_lba_low
|
|
dap_lba_low:
|
|
.long 0
|
|
.global dap_lba_high
|
|
dap_lba_high:
|
|
.long 0
|
|
|
|
.align 4
|
|
drive_params:
|
|
.word 0x1A
|
|
.word 0 /* flags */
|
|
.long 0 /* cylinders */
|
|
.long 0 /* heads */
|
|
.long 0 /* sectors */
|
|
.quad 0 /* total sectors */
|
|
.global drive_params_bps
|
|
drive_params_bps:
|
|
.word 0 /* bytes per sector */
|
|
|
|
.align 4
|
|
.global vbe_info
|
|
vbe_info:
|
|
.word 0 /* attributes */
|
|
.word 0 /* old shit (window a/b) */
|
|
.word 0 /* Granulatory of banks, don't care. */
|
|
.word 0 /* Window size, don't care. */
|
|
.long 0 /* Segments... */
|
|
.long 0 /* old bank switching thing */
|
|
.global vbe_info_pitch
|
|
vbe_info_pitch:
|
|
.word 0 /* PITCH */
|
|
.global vbe_info_width
|
|
vbe_info_width:
|
|
.word 0 /* WIDTH */
|
|
.global vbe_info_height
|
|
vbe_info_height:
|
|
.word 0 /* HEIGHT */
|
|
.word 0 /* w, y */
|
|
.byte 0 /* planes */
|
|
.global vbe_info_bpp
|
|
vbe_info_bpp:
|
|
.byte 0 /* bits per pixel */
|
|
.byte 0 /* banks */
|
|
.byte 0 /* Memory model */
|
|
.byte 0 /* bank size */
|
|
.byte 0 /* pages */
|
|
.byte 0 /* reserved */
|
|
.byte 0 /* RED mask */
|
|
.byte 0 /* RED offset */
|
|
.byte 0 /* GREEN mask */
|
|
.byte 0 /* GREEN offset */
|
|
.byte 0 /* BLUE maask */
|
|
.byte 0 /* BLUE offset */
|
|
.byte 0 /* ALPHA mask */
|
|
.byte 0 /* ALPHA offset */
|
|
.byte 0 /* Color attributes */
|
|
.global vbe_info_fbaddr
|
|
vbe_info_fbaddr:
|
|
.long 0 /* Framebuffer address */
|
|
.long 0 /* Extra memory offset */
|
|
.word 0 /* Extra memory size */
|
|
.zero 206 /* Other crap */
|
|
|
|
.align 4
|
|
vbe_cont_info:
|
|
.ascii "VBE2"
|
|
.word 0x200
|
|
.long 0
|
|
.long 0 /* caps */
|
|
.global vbe_cont_info_mode_off
|
|
vbe_cont_info_mode_off:
|
|
.word 0 /* MODES */
|
|
vbe_cont_info_mode_seg:
|
|
.word 0
|
|
.zero 494
|
|
|
|
str_Need_long:
|
|
.asciz "ToaruOS 2.0 requires a 64-bit processor."
|
|
str_More_mem:
|
|
.asciz "ToaruOS 2.0 needs at least 128MiB of RAM, and 1GiB is recommended."
|
|
|
|
.global disk_space
|
|
disk_space:
|
|
.zero 2048
|