mixed compilation

git-svn-id: svn://kolibrios.org@854 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-08-13 19:13:40 +00:00
parent c547e213e8
commit e7779275eb
27 changed files with 1380 additions and 965 deletions

Binary file not shown.

View File

@ -12,6 +12,11 @@ include "../proc32.inc"
include "../kglobals.inc" include "../kglobals.inc"
include "../lang.inc" include "../lang.inc"
CR0_PE equ 0x00000001 ;protected mode
CR0_WP equ 0x00010000 ;write protect
CR0_PG equ 0x80000000 ;paging
public _enter_bootscreen public _enter_bootscreen
public _leave_bootscreen public _leave_bootscreen
@ -60,7 +65,7 @@ include "../detect/biosdisk.inc"
cli cli
mov eax, cr0 mov eax, cr0
or eax, 0x80000001 or eax, CR0_PG+CR0_WP+CR0_PE
mov cr0, eax mov cr0, eax
jmp pword 0x08:__setvars jmp pword 0x08:__setvars

View File

@ -17,7 +17,7 @@ extrn _sys_pdbr
extrn _gdts extrn _gdts
extrn __edata extrn __edata
section '.init' code readable align 16 section '.start' code readable align 16
use32 use32

View File

@ -214,7 +214,7 @@ mouseunder equ (OS_BASE+0x0006900)
CDDataBuf equ (OS_BASE+0x0007000) CDDataBuf equ (OS_BASE+0x0007000)
FLOPPY_BUFF equ (OS_BASE+0x0008000) FLOPPY_BUFF equ (OS_BASE+0x0008000)
ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused
idts equ (OS_BASE+0x000B100)
WIN_STACK equ (OS_BASE+0x000C000) WIN_STACK equ (OS_BASE+0x000C000)
WIN_POS equ (OS_BASE+0x000C400) WIN_POS equ (OS_BASE+0x000C400)
FDD_BUFF equ (OS_BASE+0x000D000) FDD_BUFF equ (OS_BASE+0x000D000)

View File

@ -17,16 +17,16 @@ macro export dllname,[label,string]
forward forward
count = count+1 count = count+1
common common
dd 0,0,0, (module-OS_BASE) , 1 dd 0,0,0, (module+(0x100000000-OS_BASE)) , 1
dd count,count,(addresses-OS_BASE),(names-OS_BASE),(ordinal-OS_BASE) dd count,count,(addresses+(0x100000000-OS_BASE)),(names+(0x100000000-OS_BASE)),(ordinal+(0x100000000-OS_BASE))
addresses: addresses:
forward forward
dd (label-OS_BASE) dd (label+(0x100000000-OS_BASE))
common common
names: names:
forward forward
local name local name
dd (name-OS_BASE) dd (name+(0x100000000-OS_BASE))
common common
ordinal: count = 0 ordinal: count = 0
forward forward

View File

@ -103,8 +103,8 @@ kernel_export:
dd szPciWrite16 , pci_write16 dd szPciWrite16 , pci_write16
dd szPciWrite32 , pci_write32 dd szPciWrite32 , pci_write32
dd szAllocPage , alloc_page ;stdcall dd szAllocPage , _alloc_page ;stdcall
dd szAllocPages , alloc_pages ;stdcall dd szAllocPages , _alloc_pages ;stdcall
dd szFreePage , free_page dd szFreePage , free_page
dd szMapPage , map_page ;stdcall dd szMapPage , map_page ;stdcall
dd szMapSpace , map_space dd szMapSpace , map_space

View File

@ -575,7 +575,7 @@ proc kernel_alloc stdcall, size:dword
and ebx, not 7 and ebx, not 7
push ebx push ebx
stdcall alloc_pages, ebx stdcall _alloc_pages, ebx
pop ecx ; yes ecx!!! pop ecx ; yes ecx!!!
test eax, eax test eax, eax
jz .err jz .err
@ -594,7 +594,7 @@ proc kernel_alloc stdcall, size:dword
jz .end jz .end
@@: @@:
push ecx push ecx
call alloc_page call _alloc_page
pop ecx pop ecx
test eax, eax test eax, eax
jz .err jz .err

View File

@ -1,151 +0,0 @@
DWORD equ dword
WORD equ word
BYTE equ byte
PTR equ
_init:
push esi
push ebx
sub esp, 4
mov eax, DWORD PTR [_boot_mbi]
test BYTE PTR [eax], 2
je .L2
push ecx
push ecx
push DWORD PTR [eax+12]
push .LC0
call _printf
add esp, 16
.L2:
mov eax, DWORD PTR [_boot_mbi]
test BYTE PTR [eax], 4
je L4
push edx
push edx
push DWORD PTR [eax+16]
push .LC1
call _printf
add esp, 16
.L4:
mov eax, DWORD PTR [_boot_mbi]
test BYTE PTR [eax], 8
je .L6
push esi
xor esi, esi
push DWORD PTR [eax+24]
push DWORD PTR [eax+20]
push .LC2
call _printf
mov eax, DWORD PTR [_boot_mbi]
mov ebx, DWORD PTR [eax+24]
jmp .L22
.L9:
mov eax, DWORD PTR [ebx-12]
inc esi
push DWORD PTR [ebx-8]
mov DWORD PTR [_pg_balloc], eax
push eax
push DWORD PTR [ebx-16]
push .LC3
call _printf
.L22:
mov eax, DWORD PTR [_boot_mbi]
add esp, 16
mov edx, ebx
add ebx, 16
cmp esi, DWORD PTR [eax+20]
jb .L9
mov edx, DWORD PTR [edx-16]
push ebx
push ebx
sub edx, 536870912
lea eax, [edx+512]
mov DWORD PTR [_rd_fat], eax
lea eax, [edx+4790]
push edx
push .LC4
mov DWORD PTR [_rd_fat_end], eax
lea eax, [edx+9728]
mov DWORD PTR [_rd_root], eax
lea eax, [edx+16896]
mov DWORD PTR [_rd_base], edx
mov DWORD PTR [_rd_root_end], eax
call _printf
add esp, 16
.L6:
mov eax, DWORD PTR [_boot_mbi]
xor esi, esi
test BYTE PTR [eax], 64
je .L13
push ecx
push DWORD PTR [eax+44]
push DWORD PTR [eax+48]
push .LC5
call _printf
mov eax, DWORD PTR [_boot_mbi]
add esp, 16
mov ebx, DWORD PTR [eax+48]
jmp .L14
.L15:
push edx
push DWORD PTR [ebx+20]
push DWORD PTR [ebx+12]
push DWORD PTR [ebx+16]
push DWORD PTR [ebx+4]
push DWORD PTR [ebx+8]
push DWORD PTR [ebx]
push .LC6
call _printf
add esp, 32
cmp DWORD PTR [ebx+20], 1
jne .L16
mov eax, DWORD PTR [ebx+4]
add eax, DWORD PTR [ebx+12]
and eax, -4096
cmp esi, eax
jae .L16
mov esi, eax
.L16:
mov eax, DWORD PTR [ebx]
add eax, 4
lea ebx, [eax+ebx]
.L14:
mov edx, DWORD PTR [_boot_mbi]
mov eax, DWORD PTR [edx+48]
add eax, DWORD PTR [edx+44]
cmp ebx, eax
jb .L15
cmp esi, 268435456
jbe .L13
mov esi, 268435456
.L13:
mov DWORD PTR [_mem_amount], esi
pop eax
pop ebx
pop esi
ret
.LC0:
db "boot_device = 0x%x",10,0
.LC1:
db "cmdline = %s",10,0
.LC2:
db "mods_count = %d, mods_addr = 0x%x",10,0
.LC3:
db " mod_start = 0x%x, mod_end = 0x%x, string = %s",10,0
.LC4:
db " rd_base = %x",10,0
.LC5:
db "mmap_addr = 0x%x, mmap_length = 0x%x",10,0
.LC6:
db " size = 0x%x, base_addr = 0x%x%x, length = 0x%x%x, type = 0x%x",10,0
restore DWORD
restore WORD
restore BYTE
restore PTR

View File

@ -0,0 +1,95 @@
#include <types.h>
#include <core.h>
#include "multiboot.h"
extern u32_t pg_balloc;
extern u32_t mem_amount;
extern u32_t rd_base;
extern u32_t rd_fat ;
extern u32_t rd_fat_end ;
extern u32_t rd_root ;
extern u32_t rd_root_end ;
extern multiboot_info_t *boot_mbi;
/* Check if the bit BIT in FLAGS is set. */
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
void init()
{
u32_t last_page = 0;
if (CHECK_FLAG (boot_mbi->flags, 1))
printf ("boot_device = 0x%x\n", (unsigned) boot_mbi->boot_device);
/* Is the command line passed? */
if (CHECK_FLAG (boot_mbi->flags, 2))
printf ("cmdline = %s\n", (char *) boot_mbi->cmdline);
/* Are mods_* valid? */
if (CHECK_FLAG (boot_mbi->flags, 3))
{
module_t *mod;
int i;
printf ("mods_count = %d, mods_addr = 0x%x\n",
(u32_t) boot_mbi->mods_count, (u32_t) boot_mbi->mods_addr);
for (i = 0, mod = (module_t *) boot_mbi->mods_addr;
i < boot_mbi->mods_count;i++, mod++)
{
pg_balloc = mod->mod_end;
printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
(u32_t) mod->mod_start,(u32_t) mod->mod_end, (char *) mod->string);
};
mod--;
rd_base = mod->mod_start+OS_BASE;
rd_fat = rd_base + 512;
rd_fat_end = rd_base + 512 + 4278;
rd_root = rd_base + 512*19;
rd_root_end = rd_base + 512*33;
printf(" rd_base = %x\n", rd_base);
}
if (CHECK_FLAG (boot_mbi->flags, 6))
{
memory_map_t *mmap;
u32_t page;
printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
(unsigned) boot_mbi->mmap_addr, (unsigned) boot_mbi->mmap_length);
for (mmap = (memory_map_t *) boot_mbi->mmap_addr;
(u32_t) mmap < boot_mbi->mmap_addr + boot_mbi->mmap_length;
mmap = (memory_map_t *) ((u32_t) mmap
+ mmap->size + sizeof (mmap->size)))
{
u32_t page;
printf (" size = 0x%x, base_addr = 0x%x%x,"
" length = 0x%x%x, type = 0x%x\n",
(unsigned) mmap->size,
(unsigned) mmap->base_addr_high,
(unsigned) mmap->base_addr_low,
(unsigned) mmap->length_high,
(unsigned) mmap->length_low,
(unsigned) mmap->type);
if( mmap->type != 1)
continue;
page = (mmap->base_addr_low+mmap->length_low)&(~4095);
if(page > last_page)
last_page = page;
}
}
if(last_page > 256*1024*1024)
last_page = 256*1024*1024;
mem_amount = last_page;
};

View File

@ -231,7 +231,7 @@ proc init_LFB
cmp dword [LFBAddress], -1 cmp dword [LFBAddress], -1
jne @f jne @f
mov [BOOT_VAR+0x901c],byte 2 mov [BOOT_VAR+0x901c],byte 2
stdcall alloc_pages, 0x280000 shr 12 stdcall _alloc_pages, 0x280000 shr 12
add eax, OS_BASE add eax, OS_BASE
mov [LFBAddress], eax mov [LFBAddress], eax
ret ret
@ -325,7 +325,7 @@ proc new_mem_resize stdcall, new_size:dword
xchg esi, edi xchg esi, edi
@@: @@:
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .exit jz .exit
@ -347,7 +347,7 @@ proc new_mem_resize stdcall, new_size:dword
pop edi pop edi
pop esi pop esi
@@: @@:
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .exit jz .exit
stdcall map_page,esi,eax,dword PG_UW stdcall map_page,esi,eax,dword PG_UW
@ -477,17 +477,21 @@ proc page_fault_handler
align 4 align 4
.kernel_heap: .kernel_heap:
mov ecx, ebx
shr ebx, 22 shr ebx, 22
mov edx, [master_tab + ebx*4] mov edx, [master_tab + ebx*4]
test edx, PG_MAP test edx, PG_MAP
jz .check_ptab ;òàáëèöà ñòðàíèö íå ñîçäàíà jz .check_ptab ;òàáëèöà ñòðàíèö íå ñîçäàíà
shr ecx, 12
mov eax, [page_tabs+ecx*4]
.check_ptab: .check_ptab:
mov edx, [_sys_pdbr + ebx*4] mov edx, [_sys_pdbr + ebx*4]
test edx, PG_MAP test edx, PG_MAP
jnz @F jnz @F
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .fail jz .fail
@ -522,7 +526,7 @@ align 4
jz .fail ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ; jz .fail ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
;èñïîëüçîâàíèÿ. Îøèáêà ;èñïîëüçîâàíèÿ. Îøèáêà
.alloc: .alloc:
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .fail jz .fail
@ -566,7 +570,7 @@ align 4
; io permission map ; io permission map
; copy-on-write protection ; copy-on-write protection
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .fail jz .fail
@ -1180,7 +1184,7 @@ proc create_ring_buffer stdcall, size:dword, flags:dword
shr ebx, 12 shr ebx, 12
push ebx push ebx
stdcall alloc_pages, ebx stdcall _alloc_pages, ebx
pop ecx pop ecx
test eax, eax test eax, eax

View File

@ -1,687 +0,0 @@
DWORD equ dword
WORD equ word
BYTE equ byte
PTR equ
_mem_counter equ (BOOT_VAR + 0x9100)
_mem_table equ (BOOT_VAR + 0x9104)
_spinlock_initialize:
mov eax, DWORD PTR [esp+4]
mov DWORD PTR [eax], 0
ret
_buddy_find_block:
push ebx
mov eax, DWORD PTR [eax+12]
mov ebx, ecx
sub edx, eax
sar edx, 2
imul ecx, edx, -858993459
lea eax, [eax+edx*4]
.L4:
cmp DWORD PTR [eax+12], ebx
jne .L7
sub ecx, 1
sub eax, 20
cmp ecx, -1
jne .L4
xor eax, eax
.L7:
pop ebx
ret
@buddy_system_free@8:
push ebp
mov ebp, edx
push edi
push esi
mov esi, edx
push ebx
sub esp, 8
mov ebx, DWORD PTR [edx+12]
mov DWORD PTR [esp+4], ecx
cmp BYTE PTR [ecx+24], bl
mov edi, ebx
je .L17
mov edx, DWORD PTR [ecx+12]
mov DWORD PTR [esp], edx
jmp .L15
.L30:
mov eax, 1
sal eax, cl
add edx, eax
mov eax, DWORD PTR [esp+4]
cmp edx, DWORD PTR [eax+8]
jae .L17
.L31:
lea eax, [edx+edx*4]
mov edx, DWORD PTR [esp]
lea ecx, [edx+eax*4]
cmp ebx, DWORD PTR [ecx+12]
jne .L17
mov eax, DWORD PTR [ecx+8]
test eax, eax
jne .L17
mov eax, DWORD PTR [ecx+4]
cmp esi, ecx
mov edx, DWORD PTR [ecx]
mov DWORD PTR [esi+12], 255
mov DWORD PTR [ecx+12], 255
mov DWORD PTR [eax], edx
mov edx, DWORD PTR [ecx]
mov DWORD PTR [ecx], 0
mov DWORD PTR [edx+4], eax
mov edx, ebp
mov DWORD PTR [ecx+4], 0
jb .L26
mov edx, ecx
.L26:
mov ecx, edi
mov esi, edx
movzx eax, cl
mov ebp, edx
lea ebx, [eax+1]
mov eax, DWORD PTR [esp+4]
mov DWORD PTR [edx+12], ebx
movzx edi, BYTE PTR [eax+24]
mov edx, edi
cmp dl, bl
je .L17
mov edi, ebx
.L15:
mov eax, esi
mov ecx, ebx
sub eax, DWORD PTR [esp]
sar eax, 2
imul edx, eax, -858993459
mov eax, edx
shr eax, cl
test al, 1
je .L30
mov eax, 1
mov ecx, ebx
sal eax, cl
sub edx, eax
mov eax, DWORD PTR [esp+4]
cmp edx, DWORD PTR [eax+8]
jb .L31
.L17:
mov ecx, edi
movzx edx, cl
mov ecx, DWORD PTR [esp+4]
mov eax, DWORD PTR [ecx+28+edx*8]
mov DWORD PTR [ebp], eax
lea eax, [ecx+28+edx*8]
mov DWORD PTR [ebp+4], eax
mov eax, DWORD PTR [ecx+28+edx*8]
mov DWORD PTR [ecx+28+edx*8], ebp
mov DWORD PTR [eax+4], ebp
add esp, 8
pop ebx
pop esi
pop edi
pop ebp
ret
@buddy_system_alloc_block@8:
push ebp
mov ebp, ecx
push edi
mov ecx, 255
push esi
mov eax, ebp
push ebx
sub esp, 4
mov DWORD PTR [esp], edx
call _buddy_find_block
mov ebx, eax
mov eax, DWORD PTR [eax+4]
mov edx, DWORD PTR [ebx]
mov DWORD PTR [eax], edx
mov edx, DWORD PTR [ebx]
mov DWORD PTR [ebx], 0
mov DWORD PTR [edx+4], eax
mov eax, DWORD PTR [ebx+12]
mov DWORD PTR [ebx+4], 0
test eax, eax
jne .L38
jmp .L34
.L35:
mov DWORD PTR [ebx+8], 1
mov edx, esi
mov ecx, ebp
call @buddy_system_free@8
mov eax, DWORD PTR [ebx+12]
mov DWORD PTR [ebx+8], 0
test eax, eax
je .L34
.L38:
lea ecx, [eax-1]
mov edx, DWORD PTR [esp]
mov eax, 20
sal eax, cl
lea edi, [ebx+eax]
mov eax, ebp
mov DWORD PTR [ebx+12], ecx
mov esi, edi
mov DWORD PTR [edi+12], ecx
mov ecx, 255
call _buddy_find_block
cmp edi, eax
jne .L35
mov esi, ebx
mov ebx, edi
jmp .L35
.L34:
mov DWORD PTR [ebx+8], 1
mov eax, ebx
add esp, 4
pop ebx
pop esi
pop edi
pop ebp
ret
_zone_release:
push edi
push esi
push ebx
mov esi, DWORD PTR [esp+16]
mov eax, DWORD PTR [esp+20]
mov edi, DWORD PTR [esp+24]
mov edx, DWORD PTR [esi+4]
add edi, eax
cmp edi, edx
jb .L48
mov ebx, edx
add ebx, DWORD PTR [esi+8]
cmp eax, ebx
ja .L48
cmp eax, edx
mov ecx, eax
jae .L44
mov ecx, edx
.L44:
cmp edi, ebx
jbe .L45
mov edi, ebx
.L45:
cmp ecx, edi
jae .L48
mov ebx, ecx
.L47:
mov edx, DWORD PTR [esi+12]
mov eax, ecx
add ebx, 1
sub eax, DWORD PTR [esi+4]
lea eax, [eax+eax*4]
mov DWORD PTR [edx+8+eax*4], 0
sub ecx, DWORD PTR [esi+4]
lea edx, [ecx+ecx*4]
mov ecx, esi
sal edx, 2
add edx, DWORD PTR [esi+12]
call @buddy_system_free@8
cmp edi, ebx
mov ecx, ebx
ja .L47
.L48:
pop ebx
pop esi
pop edi
ret
_zone_reserve:
push edi
push esi
push ebx
mov esi, DWORD PTR [esp+16]
mov eax, DWORD PTR [esp+20]
mov ebx, DWORD PTR [esp+24]
mov edx, DWORD PTR [esi+4]
add ebx, eax
cmp ebx, edx
jb .L61
mov ecx, edx
add ecx, DWORD PTR [esi+8]
cmp eax, ecx
ja .L61
cmp eax, edx
jae .L54
mov eax, edx
.L54:
cmp ebx, ecx
mov edi, ebx
jbe .L55
mov edi, ecx
.L55:
cmp eax, edi
jae .L61
mov ebx, eax
jmp .L57
.L58:
add ebx, 1
cmp edi, ebx
mov eax, ebx
jbe .L61
.L62:
mov edx, DWORD PTR [esi+4]
.L57:
sub eax, edx
lea eax, [eax+eax*4]
lea edx, [0+eax*4]
add edx, DWORD PTR [esi+12]
mov ecx, DWORD PTR [edx+8]
test ecx, ecx
jne .L58
add ebx, 1
mov ecx, esi
call @buddy_system_alloc_block@8
mov eax, ebx
sub DWORD PTR [esi+16], 1
cmp edi, ebx
ja .L62
.L61:
pop ebx
pop esi
pop edi
ret
@buddy_system_alloc@8:
sub esp, 12
mov DWORD PTR [esp], ebx
lea eax, [ecx+28+edx*8]
mov ebx, edx
mov DWORD PTR [esp+4], esi
mov esi, ecx
mov DWORD PTR [esp+8], edi
cmp DWORD PTR [ecx+32+edx*8], eax
je .L64
mov ecx, DWORD PTR [ecx+32+edx*8]
mov eax, DWORD PTR [ecx+4]
mov edx, DWORD PTR [ecx]
mov DWORD PTR [ecx+8], 1
mov DWORD PTR [eax], edx
mov edx, DWORD PTR [ecx]
mov DWORD PTR [ecx], 0
mov DWORD PTR [edx+4], eax
mov DWORD PTR [ecx+4], 0
.L66:
mov ebx, DWORD PTR [esp]
mov eax, ecx
mov esi, DWORD PTR [esp+4]
mov edi, DWORD PTR [esp+8]
add esp, 12
ret
.L64:
movzx eax, BYTE PTR [ecx+24]
cmp eax, edx
jne .L71
.L67:
xor ecx, ecx
jmp .L66
.L71:
lea edx, [edx+1]
call @buddy_system_alloc@8
test eax, eax
mov edi, eax
je .L67
mov ecx, DWORD PTR [eax+12]
mov edx, 20
mov DWORD PTR [eax+12], ebx
mov DWORD PTR [eax+8], 1
sub ecx, 1
sal edx, cl
mov ecx, esi
add edx, eax
mov DWORD PTR [edx+12], ebx
call @buddy_system_free@8
mov ecx, edi
jmp .L66
_zone_frame_alloc:
sub esp, 8
mov ecx, eax
mov DWORD PTR [esp], ebx
mov ebx, eax
mov DWORD PTR [esp+4], esi
mov esi, edx
call @buddy_system_alloc@8
mov ecx, esi
mov edx, 1
sal edx, cl
mov esi, DWORD PTR [esp+4]
sub DWORD PTR [ebx+16], edx
sub eax, DWORD PTR [ebx+12]
add DWORD PTR [ebx+20], edx
mov ebx, DWORD PTR [esp]
add esp, 8
sar eax, 2
imul eax, eax, -858993459
ret
_frame_set_parent:
mov eax, DWORD PTR [esp+4]
sub eax, DWORD PTR [_z_core+4]
mov ecx, DWORD PTR [esp+8]
mov edx, DWORD PTR [_z_core+12]
lea eax, [eax+eax*4]
mov DWORD PTR [edx+16+eax*4], ecx
ret
@zone_free@8:
sub esp, 8
lea edx, [edx+edx*4]
mov DWORD PTR [esp], ebx
sal edx, 2
mov ebx, ecx
mov DWORD PTR [esp+4], esi
add edx, DWORD PTR [ecx+12]
mov eax, DWORD PTR [edx+8]
mov esi, DWORD PTR [edx+12]
sub eax, 1
test eax, eax
mov DWORD PTR [edx+8], eax
jne .L79
call @buddy_system_free@8
mov eax, 1
mov ecx, esi
sal eax, cl
add DWORD PTR [ebx+16], eax
sub DWORD PTR [ebx+20], eax
.L79:
mov ebx, DWORD PTR [esp]
mov esi, DWORD PTR [esp+4]
add esp, 8
ret
@zone_alloc@8:
sub esp, 8
mov DWORD PTR [esp], ebx
mov ebx, ecx
mov DWORD PTR [esp+4], esi
pushf
pop esi
cli
@@:
pause
mov eax, [_z_core]
test eax, eax
jnz @b
inc eax
xchg [_z_core], eax
test eax, eax
jnz @b
mov eax, ecx
call _zone_frame_alloc
mov edx, DWORD PTR [ebx+4]
mov DWORD PTR [ebx], 0
push esi
popf
mov ebx, DWORD PTR [esp]
add eax, edx
mov esi, DWORD PTR [esp+4]
sal eax, 12
add esp, 8
ret
alloc_page:
_alloc_page:
push ebx
pushf
pop ebx
cli
@@:
pause
mov eax, [_z_core]
test eax, eax
jnz @b
inc eax
xchg [_z_core], eax
test eax, eax
jnz @b
push edx
xor edx, edx
mov eax, _z_core
call _zone_frame_alloc
pop edx
mov [_z_core], 0
push ebx
popf
pop ebx
sal eax, 12
ret
alloc_pages:
_alloc_pages@4:
push ebx
pushf
pop ebx
cli
@@:
pause
mov eax, [_z_core]
test eax, eax
jnz @b
inc eax
xchg [_z_core], eax
test eax, eax
jnz @b
mov eax, DWORD PTR [esp+8]
add eax, 7
and eax, -8
xor ecx, ecx
bsr ecx, eax
inc ecx
push edx
mov edx, ecx
mov eax, _z_core
call _zone_frame_alloc
pop edx
mov [_z_core], 0
push ebx
popf
pop ebx
sal eax, 12
ret 4
_zone_create:
push esi
push ebx
sub esp, 4
mov ebx, DWORD PTR [esp+16]
mov esi, DWORD PTR [esp+24]
mov DWORD PTR [esp], ebx
call _spinlock_initialize
mov eax, DWORD PTR [esp+20]
mov DWORD PTR [ebx+8], esi
mov DWORD PTR [ebx+16], esi
mov DWORD PTR [ebx+20], 0
mov DWORD PTR [ebx+4], eax
xor eax, eax
bsr eax, esi
xor edx, edx
mov BYTE PTR [ebx+24], al
.L81:
lea eax, [ebx+28+edx*8]
mov DWORD PTR [ebx+28+edx*8], eax
mov DWORD PTR [ebx+32+edx*8], eax
movzx eax, BYTE PTR [ebx+24]
add edx, 1
cmp eax, edx
jae .L81
lea ecx, [esi+esi*4]
sal ecx, 2
call @balloc@4
test esi, esi
mov DWORD PTR [ebx+12], eax
je .L83
xor ecx, ecx
xor edx, edx
.L85:
mov eax, edx
add ecx, 1
add eax, DWORD PTR [ebx+12]
add edx, 20
cmp ecx, esi
mov DWORD PTR [eax+8], 1
mov DWORD PTR [eax+12], 0
jne .L85
.L83:
add esp, 4
mov eax, 1
pop ebx
pop esi
ret
_init_mm:
push ebx
sub esp, 24
mov eax, DWORD PTR [_mem_amount]
mov DWORD PTR [esp], .LC3
mov ebx, eax
shr ebx, 12
mov DWORD PTR [esp+8], ebx
mov DWORD PTR [esp+4], eax
call _printf
mov eax, DWORD PTR [_pg_balloc]
mov DWORD PTR [esp], .LC4
mov DWORD PTR [esp+8], eax
lea eax, [ebx+ebx*4]
sal eax, 2
mov DWORD PTR [esp+4], eax
call _printf
mov DWORD PTR [esp+8], ebx
mov DWORD PTR [esp+4], 0
mov DWORD PTR [esp], _z_core
call _zone_create
mov DWORD PTR [esp+8], ebx
mov DWORD PTR [esp+4], 0
mov DWORD PTR [esp], _z_core
call _zone_release
mov eax, DWORD PTR [_pg_balloc]
mov DWORD PTR [esp+4], 0
mov DWORD PTR [esp], _z_core
shr eax, 12
mov DWORD PTR [esp+8], eax
call _zone_reserve
add esp, 24
pop ebx
ret
.LC3:
db "last page = %x total pages = %x",10,0
.LC4:
db "conf_size = %x free mem start =%x",10,0
_frame_free:
push ebx
mov edx, DWORD PTR [esp+8]
pushf
pop ebx
cli
@@:
pause
mov eax, [_z_core]
test eax, eax
jnz @b
inc eax
xchg [_z_core], eax
test eax, eax
jnz @b
mov ecx, _z_core
shr edx, 12
call @zone_free@8
mov [_z_core], 0
push ebx
popf
pop ebx
ret
_core_free:
push ebx
mov edx, DWORD PTR [esp+8]
pushf
pop ebx
cli
@@:
pause
mov eax, [_z_core]
test eax, eax
jnz @b
inc eax
xchg [_z_core], eax
test eax, eax
jnz @b
mov ecx, _z_core
shr edx, 12
call @zone_free@8
mov [_z_core], 0
push ebx
popf
pop ebx
ret
_core_alloc:
push ebx
pushf
pop ebx
cli
@@:
pause
mov eax, [_z_core]
test eax, eax
jnz @b
inc eax
xchg [_z_core], eax
test eax, eax
jnz @b
mov edx, DWORD PTR [esp+8]
mov eax, _z_core
call _zone_frame_alloc
mov [_z_core], 0
push ebx
popf
pop ebx
sal eax, 12
ret
restore DWORD
restore WORD
restore BYTE
restore PTR

View File

@ -0,0 +1,644 @@
#include <types.h>
#include <core.h>
#include <spinlock.h>
#include <link.h>
#include <mm.h>
extern u32_t pg_balloc;
extern u32_t mem_amount;
void __fastcall *balloc(u32_t size);
zone_t z_core;
static inline u32_t save_edx(void)
{
u32_t val;
asm volatile ("mov %0, edx":"=r"(val));
return val;
};
static inline void restore_edx(u32_t val)
{
asm volatile (""::"d" (val) );
};
static void buddy_system_create(zone_t *z);
static void __fastcall buddy_system_free(zone_t *z, link_t *block);
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx);
static addr_t __fastcall zone_alloc(zone_t *zone, u32_t order);
size_t buddy_conf_size(int max_order);
static inline void frame_initialize(frame_t *frame);
static inline u32_t fnzb(u32_t arg);
void init_mm();
static void zone_create(zone_t *z, pfn_t start, count_t count);
static void zone_reserve(zone_t *z, pfn_t base, count_t count);
static void zone_release(zone_t *z, pfn_t base, count_t count);
void init_mm()
{
int i;
u32_t base;
u32_t size;
count_t pages;
size_t conf_size;
size_t core_size;
pages = mem_amount >> FRAME_WIDTH;
printf("last page = %x total pages = %x\n",mem_amount, pages);
conf_size = pages*sizeof(frame_t);
printf("conf_size = %x free mem start =%x\n",conf_size, pg_balloc);
zone_create(&z_core, 0, pages);
zone_release(&z_core, 0, pages);
zone_reserve(&z_core, 0, pg_balloc >> FRAME_WIDTH);
#if 0
core_size = (pg_free+conf_size+1024*1024*5)&(-1024*1024*4);
// printf("core size = %x core heap = %x\n",core_size,core_size-conf_size-pg_free);
u32_t p0, p1;
u32_t b0, b1;
p0 = core_size>>12;
p1 = (last_page-core_size)>>12;
b0 = p0*sizeof(frame_t);
b1 = p1*sizeof(frame_t);
// printf("buddy_0: %x pages conf_size %x\n", p0, b0);
// printf("buddy_1: %x pages conf_size %x\n", p1, b1);
zone_create(&z_core, 0, p0);
zone_create(&z_user, p0, p1);
// printf("free mem start = %x\n",pg_balloc);
for(i = 0; i < mem_counter; i++)
{
u32_t page;
if( mem_table[i].type != 1)
continue;
page = (mem_table[i].base+mem_table[i].size)&(~4095);
if(page > last_page)
last_page = page;
zone_release(&z_core,mem_table[i].base>>12, mem_table[i].size>>12);
zone_release(&z_user,mem_table[i].base>>12, mem_table[i].size>>12);
};
zone_reserve(&z_core, 0x100000>>12,(pg_balloc-OS_BASE-0x100000)>>12);
#endif
};
static void zone_create(zone_t *z, pfn_t start, count_t count)
{
unsigned int i;
// int znum;
/* Theoretically we could have here 0, practically make sure
* nobody tries to do that. If some platform requires, remove
* the assert
*/
// ASSERT(confframe);
/* If conframe is supposed to be inside our zone, then make sure
* it does not span kernel & init
*/
// printf("create zone: base %x count %x\n", start, count);
spinlock_initialize(&z->lock);
z->base = start;
z->count = count;
z->free_count = count;
z->busy_count = 0;
z->max_order = fnzb(count);
ASSERT(z->max_order < BUDDY_SYSTEM_INNER_BLOCK);
for (i = 0; i <= z->max_order; i++)
list_initialize(&z->order[i]);
z->frames = (frame_t *)balloc(count*sizeof(frame_t));
for (i = 0; i < count; i++) {
frame_initialize(&z->frames[i]);
}
}
static void zone_reserve(zone_t *z, pfn_t base, count_t count)
{
int i;
pfn_t top = base+count;
if( (base+count < z->base)||(base > z->base+z->count))
return;
if(base < z->base)
base = z->base;
if(top > z->base+z->count)
top = z->base+z->count;
printf("zone reserve base %x top %x\n", base, top);
for (i = base; i < top; i++)
zone_mark_unavailable(z, i - z->base);
};
static void zone_release(zone_t *z, pfn_t base, count_t count)
{
int i;
pfn_t top = base+count;
if( (base+count < z->base)||(base > z->base+z->count))
return;
if(base < z->base)
base = z->base;
if(top > z->base+z->count)
top = z->base+z->count;
printf("zone release base %x top %x\n", base, top);
for (i = base; i < top; i++) {
z->frames[i-z->base].refcount = 0;
buddy_system_free(z, &z->frames[i-z->base].buddy_link);
}
};
static inline index_t frame_index(zone_t *zone, frame_t *frame)
{
return (index_t) (frame - zone->frames);
}
static inline index_t frame_index_abs(zone_t *zone, frame_t *frame)
{
return (index_t) (frame - zone->frames);
}
static inline int frame_index_valid(zone_t *zone, index_t index)
{
return (index < zone->count);
}
/** Compute pfn_t from frame_t pointer & zone pointer */
static inline index_t make_frame_index(zone_t *zone, frame_t *frame)
{
return (frame - zone->frames);
}
static inline void frame_initialize(frame_t *frame)
{
frame->refcount = 1;
frame->buddy_order = 0;
}
static inline count_t fnzb(u32_t arg)
{
int n;
asm volatile ("xor %0, %0 \n\t"
"bsr %0, %1"
:"=r" (n)
:"r"(arg)
);
return n;
}
static link_t *buddy_find_block(zone_t *zone, link_t *child,
u32_t order)
{
frame_t *frame;
index_t index;
frame = (frame_t*)child;
index = frame_index(zone, frame);
do {
if (zone->frames[index].buddy_order != order) {
return &zone->frames[index].buddy_link;
}
} while(index-- > 0);
return NULL;
}
static inline link_t * buddy_bisect(zone_t *z, link_t *block) {
frame_t *frame_l, *frame_r;
frame_l = (frame_t*)block;
frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
return &frame_r->buddy_link;
}
static inline u32_t buddy_get_order(zone_t *z, link_t *block) {
frame_t *frame = (frame_t*)block;
return frame->buddy_order;
}
static inline void buddy_set_order(zone_t *z, link_t *block,
u32_t order) {
frame_t *frame = (frame_t*)block;
frame->buddy_order = order;
}
static link_t *buddy_coalesce(zone_t *z, link_t *block_1,
link_t *block_2)
{
frame_t *frame1, *frame2;
frame1 = (frame_t*)block_1;
frame2 = (frame_t*)block_2;
return frame1 < frame2 ? block_1 : block_2;
}
static inline void buddy_mark_busy(zone_t *z, link_t * block) {
frame_t * frame = (frame_t*)block;
frame->refcount = 1;
}
static inline void buddy_mark_available(zone_t *z, link_t *block) {
frame_t *frame = (frame_t*)block;
frame->refcount = 0;
}
#define IS_BUDDY_ORDER_OK(index, order) \
((~(((u32_t) -1) << (order)) & (index)) == 0)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
static link_t *find_buddy(zone_t *zone, link_t *block)
{
frame_t *frame;
index_t index;
u32_t is_left, is_right;
frame = (frame_t*)block;
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),frame->buddy_order));
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
ASSERT(is_left ^ is_right);
if (is_left) {
index = (frame_index(zone, frame)) + (1 << frame->buddy_order);
} else { /* if (is_right) */
index = (frame_index(zone, frame)) - (1 << frame->buddy_order);
}
if (frame_index_valid(zone, index)) {
if (zone->frames[index].buddy_order == frame->buddy_order &&
zone->frames[index].refcount == 0) {
return &zone->frames[index].buddy_link;
}
}
return NULL;
}
static link_t* __fastcall buddy_system_alloc_block(zone_t *z, link_t *block)
{
link_t *left,*right, *tmp;
u32_t order;
left = buddy_find_block(z, block, BUDDY_SYSTEM_INNER_BLOCK);
ASSERT(left);
list_remove(left);
while (1) {
if (! buddy_get_order(z,left)) {
buddy_mark_busy(z, left);
return left;
}
order = buddy_get_order(z, left);
right = buddy_bisect(z, left);
buddy_set_order(z, left, order-1);
buddy_set_order(z, right, order-1);
tmp = buddy_find_block(z, block, BUDDY_SYSTEM_INNER_BLOCK);
if (tmp == right) {
right = left;
left = tmp;
}
ASSERT(tmp == left);
buddy_mark_busy(z, left);
buddy_system_free(z, right);
buddy_mark_available(z, left);
}
}
static void __fastcall buddy_system_free(zone_t *z, link_t *block)
{
link_t *buddy, *hlp;
u8_t i;
/*
* Determine block's order.
*/
i = buddy_get_order(z, block);
ASSERT(i <= z->max_order);
if (i != z->max_order) {
/*
* See if there is any buddy in the list of order i.
*/
buddy = find_buddy(z, block);
if (buddy) {
ASSERT(buddy_get_order(z, buddy) == i);
/*
* Remove buddy from the list of order i.
*/
list_remove(buddy);
/*
* Invalidate order of both block and buddy.
*/
buddy_set_order(z, block, BUDDY_SYSTEM_INNER_BLOCK);
buddy_set_order(z, buddy, BUDDY_SYSTEM_INNER_BLOCK);
/*
* Coalesce block and buddy into one block.
*/
hlp = buddy_coalesce(z, block, buddy);
/*
* Set order of the coalesced block to i + 1.
*/
buddy_set_order(z, hlp, i + 1);
/*
* Recursively add the coalesced block to the list of order i + 1.
*/
buddy_system_free(z, hlp);
return;
}
}
/*
* Insert block into the list of order i.
*/
list_append(block, &z->order[i]);
}
static inline frame_t * zone_get_frame(zone_t *zone, index_t frame_idx)
{
ASSERT(frame_idx < zone->count);
return &zone->frames[frame_idx];
}
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx)
{
frame_t *frame;
link_t *link;
frame = zone_get_frame(zone, frame_idx);
if (frame->refcount)
return;
link = buddy_system_alloc_block(zone, &frame->buddy_link);
ASSERT(link);
zone->free_count--;
}
static link_t* __fastcall buddy_system_alloc(zone_t *z, u32_t i)
{
link_t *res, *hlp;
ASSERT(i <= z->max_order);
/*
* If the list of order i is not empty,
* the request can be immediatelly satisfied.
*/
if (!list_empty(&z->order[i])) {
res = z->order[i].next;
list_remove(res);
buddy_mark_busy(z, res);
return res;
}
/*
* If order i is already the maximal order,
* the request cannot be satisfied.
*/
if (i == z->max_order)
return NULL;
/*
* Try to recursively satisfy the request from higher order lists.
*/
hlp = buddy_system_alloc(z, i + 1);
/*
* The request could not be satisfied
* from higher order lists.
*/
if (!hlp)
return NULL;
res = hlp;
/*
* Bisect the block and set order of both of its parts to i.
*/
hlp = buddy_bisect(z, res);
buddy_set_order(z, res, i);
buddy_set_order(z, hlp, i);
/*
* Return the other half to buddy system. Mark the first part
* full, so that it won't coalesce again.
*/
buddy_mark_busy(z, res);
buddy_system_free(z, hlp);
return res;
}
static __fastcall pfn_t zone_frame_alloc(zone_t *zone, u32_t order)
{
pfn_t v;
link_t *tmp;
frame_t *frame;
/* Allocate frames from zone buddy system */
tmp = buddy_system_alloc(zone, order);
ASSERT(tmp);
/* Update zone information. */
zone->free_count -= (1 << order);
zone->busy_count += (1 << order);
/* Frame will be actually a first frame of the block. */
frame = (frame_t*)tmp;
/* get frame address */
v = make_frame_index(zone, frame);
return v;
}
/** Set parent of frame */
void __fastcall frame_set_parent(pfn_t pfn, void *data)
{
/* zone_t *zone = find_zone_and_lock(pfn, &hint);
ASSERT(zone);
*/
spinlock_lock(&z_core.lock);
zone_get_frame(&z_core, pfn-z_core.base)->parent = data;
spinlock_unlock(&z_core.lock);
}
static inline int to_order(count_t arg)
{
int n;
asm volatile (
"xor eax, eax \n\t"
"bsr eax, edx \n\t"
"inc eax"
:"=a" (n)
:"d"(arg)
);
return n;
}
addr_t __fastcall zone_alloc(zone_t *zone, u32_t order)
{
eflags_t efl;
pfn_t v;
efl = safe_cli();
spinlock_lock(&zone->lock);
v = zone_frame_alloc(zone, order);
v += zone->base;
spinlock_unlock(&zone->lock);
safe_sti(efl);
return (v << FRAME_WIDTH);
}
addr_t core_alloc(u32_t order) //__cdecl __dllexport
{
eflags_t efl;
pfn_t v;
efl = safe_cli();
spinlock_lock(&z_core.lock);
v = zone_frame_alloc(&z_core, order);
spinlock_unlock(&z_core.lock);
safe_sti(efl);
return (v << FRAME_WIDTH);
};
addr_t alloc_page() //obsolete
{
eflags_t efl;
u32_t edx;
pfn_t v;
edx = save_edx();
efl = safe_cli();
spinlock_lock(&z_core.lock);
v = zone_frame_alloc(&z_core, 0);
spinlock_unlock(&z_core.lock);
safe_sti(efl);
restore_edx(edx);
return (v << FRAME_WIDTH);
};
addr_t __stdcall alloc_pages(count_t count) //obsolete
{
eflags_t efl;
u32_t edx;
pfn_t v;
count = (count+7)&~7;
edx = save_edx();
efl = safe_cli();
spinlock_lock(&z_core.lock);
v = zone_frame_alloc(&z_core, to_order(count));
spinlock_unlock(&z_core.lock);
safe_sti(efl);
restore_edx(edx);
return (v << FRAME_WIDTH);
};
void __fastcall zone_free(zone_t *zone, pfn_t frame_idx)
{
frame_t *frame;
u32_t order;
frame = &zone->frames[frame_idx];
/* remember frame order */
order = frame->buddy_order;
ASSERT(frame->refcount);
if (!--frame->refcount) {
buddy_system_free(zone, &frame->buddy_link);
/* Update zone information. */
zone->free_count += (1 << order);
zone->busy_count -= (1 << order);
}
}
void core_free(addr_t frame) //export
{
eflags_t efl;
efl = safe_cli();
spinlock_lock(&z_core.lock);
zone_free(&z_core, frame>>12);
spinlock_unlock(&z_core.lock);
safe_sti(efl);
}
void frame_free(addr_t frame) //export
{
eflags_t efl;
zone_t *zone;
efl = safe_cli();
spinlock_lock(&z_core.lock);
zone_free(&z_core, frame>>12);
spinlock_unlock(&z_core.lock);
safe_sti(efl);
}

View File

@ -0,0 +1,119 @@
/* multiboot.h - the header for Multiboot */
/* Copyright (C) 1999, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Macros. */
/* The magic number for the Multiboot header. */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
/* The flags for the Multiboot header. */
#ifdef __ELF__
# define MULTIBOOT_HEADER_FLAGS 0x00000003
#else
# define MULTIBOOT_HEADER_FLAGS 0x00010003
#endif
/* The magic number passed by a Multiboot-compliant boot loader. */
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/* The size of our stack (16KB). */
#define STACK_SIZE 0x4000
/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
#ifdef HAVE_ASM_USCORE
# define EXT_C(sym) _ ## sym
#else
# define EXT_C(sym) sym
#endif
#ifndef ASM
/* Do not include here in boot.S. */
/* Types. */
/* The Multiboot header. */
typedef struct multiboot_header
{
unsigned long magic;
unsigned long flags;
unsigned long checksum;
unsigned long header_addr;
unsigned long load_addr;
unsigned long load_end_addr;
unsigned long bss_end_addr;
unsigned long entry_addr;
} multiboot_header_t;
/* The symbol table for a.out. */
typedef struct aout_symbol_table
{
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long reserved;
} aout_symbol_table_t;
/* The section header table for ELF. */
typedef struct elf_section_header_table
{
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
} elf_section_header_table_t;
/* The Multiboot information. */
typedef struct multiboot_info
{
unsigned long flags;
unsigned long mem_lower;
unsigned long mem_upper;
unsigned long boot_device;
unsigned long cmdline;
unsigned long mods_count;
unsigned long mods_addr;
union
{
aout_symbol_table_t aout_sym;
elf_section_header_table_t elf_sec;
} u;
unsigned long mmap_length;
unsigned long mmap_addr;
} multiboot_info_t;
/* The module structure. */
typedef struct module
{
unsigned long mod_start;
unsigned long mod_end;
unsigned long string;
unsigned long reserved;
} module_t;
/* The memory map. Be careful that the offset 0 is base_addr_low
but no size. */
typedef struct memory_map
{
unsigned long size;
unsigned long base_addr_low;
unsigned long base_addr_high;
unsigned long length_low;
unsigned long length_high;
unsigned long type;
} memory_map_t;
#endif /* ! ASM */

View File

@ -0,0 +1,13 @@
#include <types.h>
#include <spinlock.h>
#include <core.h>
#ifdef USE_SMP
void spinlock_initialize(spinlock_t *sl)
{
atomic_set(&sl->val, 0);
}
#endif

View File

@ -13,37 +13,47 @@
$Revision$ $Revision$
align 4 align 4
idtreg: _init_idt:
dw 8*0x41-1 push edi
dd idts+8 push esi
mov edi, idts
mov dword [idtreg+2], edi
build_interrupt_table: mov esi, sys_int
mov ecx, 0x40
@@:
lodsd
mov [edi], ax ; lower part of offset
mov [edi+2], word os_code ; segment selector
mov ax, word 10001110b shl 8 ; type: interrupt gate
mov [edi+4], eax
add edi, 8
loop @b
mov eax, i40
mov ecx, i40
and eax, 0x0000FFFF
and ecx, 0xFFFF0000
or eax, os_code shl 16
or ecx, (11101111b shl 8)
mov [edi], eax
mov [edi+4], ecx
lidt [idtreg]
pop esi
pop edi
ret
mov edi, idts+8
mov esi, sys_int
mov ecx, 0x40
@@:
lodsd
mov [edi], ax ; lower part of offset
mov [edi+2], word os_code ; segment selector
mov ax, word 10001110b shl 8 ; type: interrupt gate
mov [edi+4], eax
add edi, 8
loop @b
;mov edi,8*0x40+idts+8
mov dword [edi], (i40 and 0xFFFF) or (os_code shl 16)
mov dword [edi+4], (11101111b shl 8) or (i40 and 0xFFFF0000)
; type: trap gate
ret
iglobal iglobal
msg_sel_ker db "kernel", 0 msg_sel_ker db "kernel", 0
msg_sel_app db "application", 0 msg_sel_app db "application", 0
align 4
sys_int: sys_int:
dd e0,debug_exc,e2,e3 dd e0,debug_exc,e2,e3
dd e4,e5,e6,e7 dd e4,e5,e6,e7
@ -66,6 +76,11 @@ end if
times 16 dd unknown_interrupt times 16 dd unknown_interrupt
dd i40 dd i40
idtreg:
dw 8*0x41-1
dd idts
endg endg
macro save_ring3_context macro save_ring3_context

View File

@ -383,7 +383,7 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
; cmp eax, [pg_data.pages_free] ; cmp eax, [pg_data.pages_free]
; ja .fail ; ja .fail
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .fail jz .fail
mov [dir_addr], eax mov [dir_addr], eax
@ -408,7 +408,7 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
mov edx, [app_tabs] mov edx, [app_tabs]
xor edi, edi xor edi, edi
@@: @@:
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .fail jz .fail
@ -450,7 +450,7 @@ if GREEDY_KERNEL
else else
.alloc: .alloc:
call alloc_page call _alloc_page
test eax, eax test eax, eax
jz .fail jz .fail
@ -944,7 +944,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
pl0_stack dd ? pl0_stack dd ?
endl endl
stdcall alloc_pages, (RING0_STACK_SIZE+512) shr 12 stdcall _alloc_pages, (RING0_STACK_SIZE+512) shr 12
add eax, OS_BASE add eax, OS_BASE
mov [pl0_stack], eax mov [pl0_stack], eax
@ -988,7 +988,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
add eax, RING0_STACK_SIZE add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
call alloc_page call _alloc_page
add eax, OS_BASE add eax, OS_BASE
mov esi,[current_slot] mov esi,[current_slot]
mov esi,[esi+APPDATA.cur_dir] mov esi,[esi+APPDATA.cur_dir]

View File

@ -269,11 +269,8 @@ code_16:
endofcode: endofcode:
gdte: gdte:
edata: ;equ $-OS_BASE
section '.bss' code readable align 4096 section '.bss' data writeable align 4096
org edata
align 4096 align 4096
@ -286,6 +283,9 @@ __os_stack rb 512
cur_saved_data rb 4096 cur_saved_data rb 4096
fpu_data: rb 512 fpu_data: rb 512
idts rq 0x41
; device irq owners ; device irq owners
irq_owner rd 16 ; process id irq_owner rd 16 ; process id

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KERN_ATOMIC_H_
#define KERN_ATOMIC_H_
typedef struct atomic {
volatile long count;
} atomic_t;
static inline void atomic_inc(atomic_t *val) {
#ifdef USE_SMP
asm volatile ("lock inc %0\n" : "+m" (val->count));
#else
asm volatile ("inc %0\n" : "+m" (val->count));
#endif /* USE_SMP */
}
static inline void atomic_dec(atomic_t *val) {
#ifdef USE_SMP
asm volatile ("lock dec %0\n" : "+m" (val->count));
#else
asm volatile ("dec %0\n" : "+m" (val->count));
#endif /* USE_SMP */
}
/*
static inline long atomic_postinc(atomic_t *val)
{
long r = 1;
asm volatile (
"lock xadd %1, %0\n"
: "+m" (val->count), "+r" (r)
);
return r;
}
static inline long atomic_postdec(atomic_t *val)
{
long r = -1;
asm volatile (
"lock xadd %1, %0\n"
: "+m" (val->count), "+r"(r)
);
return r;
}
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
static inline u32_t test_and_set(atomic_t *val) {
uint32_t v;
asm volatile (
"movl $1, %0\n"
"xchgl %0, %1\n"
: "=r" (v),"+m" (val->count)
);
return v;
}
*/
/* ia32 specific fast spinlock */
static inline void atomic_lock_arch(atomic_t *val)
{
u32_t tmp;
// preemption_disable();
asm volatile (
"0:\n"
"pause\n\t" /* Pentium 4's HT love this instruction */
"mov %1, [%0]\n\t"
"test %1, %1\n\t"
"jnz 0b\n\t" /* lightweight looping on locked spinlock */
"inc %1\n\t" /* now use the atomic operation */
"xchg [%0], %1\n\t"
"test %1, %1\n\t"
"jnz 0b\n\t"
: "+m" (val->count), "=r"(tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
*/
// CS_ENTER_BARRIER();
}
static inline void atomic_set(atomic_t *val, long i)
{
val->count = i;
}
static inline long atomic_get(atomic_t *val)
{
return val->count;
}
#endif /* KERN_ATOMIC_H_ */

View File

@ -0,0 +1,48 @@
#define OS_BASE 0xE0000000
void printf (const char *format, ...);
#define CALLER ((addr_t) __builtin_return_address(0))
extern void panic_printf(char *fmt, ...) __attribute__((noreturn));
#ifdef CONFIG_DEBUG
# define panic(format, ...) \
panic_printf("Kernel panic in %s() at %s:%u: " format, __func__, \
__FILE__, __LINE__, ##__VA_ARGS__);
# define ASSERT(expr) \
if (!(expr)) { \
panic("assertion failed (%s), caller=%p\n", #expr, CALLER); \
}
#else
# define panic(format, ...) \
panic_printf("Kernel panic: " format, ##__VA_ARGS__);
# define ASSERT(expr)
#endif
static inline eflags_t safe_cli(void)
{
eflags_t tmp;
asm volatile (
"pushf\n\t"
"pop %0\n\t"
"cli\n"
: "=r" (tmp)
);
return tmp;
}
static inline void safe_sti(eflags_t efl)
{
asm volatile (
"push %0\n\t"
"popf\n"
: : "r" (efl)
);
}

View File

@ -0,0 +1,50 @@
typedef struct link
{
struct link *prev;
struct link *next;
}link_t;
#define list_get_instance(link, type, member) \
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
static inline void link_initialize(link_t *link)
{
link->prev = NULL;
link->next = NULL;
}
static inline void list_initialize(link_t *head)
{
head->prev = head;
head->next = head;
}
static inline void list_append(link_t *link, link_t *head)
{
link->prev = head->prev;
link->next = head;
head->prev->next = link;
head->prev = link;
}
static inline void list_remove(link_t *link)
{
link->next->prev = link->prev;
link->prev->next = link->next;
link_initialize(link);
}
static inline bool list_empty(link_t *head)
{
return head->next == head ? true : false;
}
static inline void list_prepend(link_t *link, link_t *head)
{
link->next = head->next;
link->prev = head;
head->next->prev = link;
head->next = link;
}

View File

@ -0,0 +1,59 @@
typedef struct
{
link_t buddy_link; /**< link to the next free block inside one order */
count_t refcount; /**< tracking of shared frames */
u32_t buddy_order; /**< buddy system block order */
void *parent; /**< If allocated by slab, this points there */
} frame_t;
typedef struct {
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
pfn_t base; /**< frame_no of the first frame in the frames array */
count_t count; /**< Size of zone */
frame_t *frames; /**< array of frame_t structures in this zone */
count_t free_count; /**< number of free frame_t structures */
count_t busy_count; /**< number of busy frame_t structures */
u32_t max_order;
link_t order[21];
int flags;
} zone_t;
# define PA2KA(x) (((u32_t) (x)) + OS_BASE)
# define KA2PA(x) (((u32_t) (x)) - OS_BASE)
#define PAGE_SIZE 4096
#define FRAME_WIDTH 12
#define BUDDY_SYSTEM_INNER_BLOCK 0xff
static inline count_t SIZE2FRAMES(size_t size)
{
if (!size)
return 0;
return (count_t) ((size - 1) >> FRAME_WIDTH) + 1;
}
static inline addr_t PFN2ADDR(pfn_t frame)
{
return (addr_t) (frame << FRAME_WIDTH);
}
static inline pfn_t ADDR2PFN(addr_t addr)
{
return (pfn_t) (addr >> FRAME_WIDTH);
};
void init_mm();
pfn_t core_alloc(u32_t order);
pfn_t alloc_page() __attribute__ ((deprecated));
pfn_t __stdcall alloc_pages(count_t count) __asm__ ("_alloc_pages") __attribute__ ((deprecated));
void core_free(pfn_t frame);
void frame_free(pfn_t frame);

View File

@ -0,0 +1,65 @@
#include <atomic.h>
#ifdef USE_SMP
typedef struct
{
atomic_t val;
} spinlock_t;
/*
* SPINLOCK_DECLARE is to be used for dynamically allocated spinlocks,
* where the lock gets initialized in run time.
*/
#define SPINLOCK_DECLARE(slname) spinlock_t slname
/*
* SPINLOCK_INITIALIZE is to be used for statically allocated spinlocks.
* It declares and initializes the lock.
*/
#define SPINLOCK_INITIALIZE(slname) \
spinlock_t slname = { \
.val = { 0 } \
}
extern void spinlock_initialize(spinlock_t *sl);
extern int spinlock_trylock(spinlock_t *sl);
#define spinlock_lock(x) atomic_lock_arch(&(x)->val)
/** Unlock spinlock
*
* Unlock spinlock.
*
* @param sl Pointer to spinlock_t structure.
*/
static inline void spinlock_unlock(spinlock_t *sl)
{
ASSERT(atomic_get(&sl->val) != 0);
/*
* Prevent critical section code from bleeding out this way down.
*/
// CS_LEAVE_BARRIER();
atomic_set(&sl->val, 0);
// preemption_enable();
}
#else
/* On UP systems, spinlocks are effectively left out. */
#define SPINLOCK_DECLARE(name)
#define SPINLOCK_EXTERN(name)
#define SPINLOCK_INITIALIZE(name)
#define spinlock_initialize(x)
#define spinlock_lock(x)
#define spinlock_trylock(x)
#define spinlock_unlock(x)
#endif

View File

@ -0,0 +1,24 @@
#define NULL (void*)0
typedef unsigned char u8_t;
typedef unsigned short int u16_t;
typedef unsigned int u32_t;
typedef unsigned long long u64_t;
typedef u32_t addr_t;
typedef u32_t pfn_t;
typedef u32_t count_t;
typedef u32_t size_t;
typedef u32_t index_t;
typedef u32_t eflags_t;
typedef int bool;
#define true (bool)1
#define false (bool)0

View File

@ -114,78 +114,50 @@ public _sys_pdbr
public _gdts public _gdts
public _high_code public _high_code
public __hlt
public _panic_printf
public _printf
public _pg_balloc
public _mem_amount
public @balloc@4
public __setvars public __setvars
extrn _enter_bootscreen extrn _enter_bootscreen
extrn _leave_bootscreen extrn _leave_bootscreen
extrn _init
extrn _init_mm
public _rd_base
public _rd_fat
public _rd_fat_end
public _rd_root
public _rd_root_end
extrn _alloc_pages
extrn _alloc_page
extrn _bx_from_load extrn _bx_from_load
section '.flat' code readable align 16 section '.flat' code readable align 4096
use32 use32
org 0xE0102000
align 4 align 4
use32 use32
; CLEAR 0x280000 - HEAP_BASE
; xor eax,eax
; mov edi,0x280000
; mov ecx,(0x800000-0x280000) / 4
; cld
; rep stosd
; mov edi,0x40000
; mov ecx,(0x90000-0x40000)/4
; rep stosd
; CLEAR KERNEL UNDEFINED GLOBALS
; mov edi, endofcode-OS_BASE
; mov ecx, (uglobals_size/4)+4
; rep stosd
; call test_cpu ; call test_cpu
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc ; bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc
; call init_BIOS32 ; call init_BIOS32
; mov dword [sys_pgdir-OS_BASE], PG_LARGE+PG_SW
; mov dword [sys_pgdir-OS_BASE+4], PG_LARGE+PG_SW+4*1024*1024
; mov ecx, 32
; lea edi, [sys_pgdir-OS_BASE+0xE00]
; mov eax, PG_LARGE+PG_SW
;@@:
; stosd
; add eax, 4*1024*1024
; loop @B
; mov ebx, cr4
; or ebx, CR4_PSE
; and ebx, not CR4_PAE
; mov cr4, ebx
; mov eax, sys_pgdir-OS_BASE
; mov ebx, cr0
; or ebx,CR0_PG+CR0_WP
; mov cr3, eax
; mov cr0, ebx
; lgdt [gdts]
; jmp pword os_code:high_code ; jmp pword os_code:high_code
align 4 align 4
bios32_entry dd ? ;bios32_entry dd ?
tmp_page_tabs dd ? ;tmp_page_tabs dd ?
__DEBUG__ fix 1 __DEBUG__ fix 1
@ -197,10 +169,20 @@ MEM_WC equ 1 ;write combined memory
MEM_UC equ 0 ;uncached memory MEM_UC equ 0 ;uncached memory
include 'printf.inc' __hlt:
include 'core/mm.asm' cli
@@:
hlt
jmp @B
include 'core/init.asm' align 4
_panic_printf:
mov dword [esp], __hlt
jmp _printf
align 4
include 'printf.inc'
align 4 align 4
proc test_cpu proc test_cpu
@ -303,6 +285,7 @@ endp
align 4 align 4
_high_code: _high_code:
mov ax,os_stack mov ax,os_stack
mov dx,app_data mov dx,app_data
mov ss,ax mov ss,ax
@ -313,9 +296,6 @@ _high_code:
mov fs, dx mov fs, dx
mov gs, dx mov gs, dx
; push ecx
; push ebx
; bt [cpu_caps], CAPS_PGE ; bt [cpu_caps], CAPS_PGE
; jnc @F ; jnc @F
@ -549,16 +529,14 @@ __setvars:
wrmsr wrmsr
.noSYSCALL: .noSYSCALL:
; ----------------------------------------- ; -----------------------------------------
; LOAD IDT ; LOAD IDT
call build_interrupt_table call _init_idt
lidt [idtreg]
mov [LFBSize], 0x800000 mov [LFBSize], 0x800000
call init_LFB call init_LFB
call init_fpu call init_fpu
call init_malloc call init_malloc
stdcall alloc_kernel_space, 0x51000 stdcall alloc_kernel_space, 0x51000
mov [default_io_map], eax mov [default_io_map], eax
@ -620,7 +598,7 @@ __setvars:
stdcall kernel_alloc, [mem_BACKGROUND] stdcall kernel_alloc, [mem_BACKGROUND]
mov [img_background], eax mov [img_background], eax
mov [SLOT_BASE + 256 + APPDATA.dir_table], _sys_pdbr - OS_BASE mov [SLOT_BASE + 256 + APPDATA.dir_table], _sys_pdbr + (0x100000000-OS_BASE)
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f ; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f
@ -649,8 +627,6 @@ __setvars:
include 'detect/disks.inc' include 'detect/disks.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!! ;!!!!!!!!!!!!!!!!!!!!!!!!!!
xchg bx, bx
call Parser_params call Parser_params
; READ RAMDISK IMAGE FROM HD ; READ RAMDISK IMAGE FROM HD

View File

@ -12,15 +12,15 @@ SECTIONS
.boot . + __image_base__ : .boot . + __image_base__ :
{ {
*(.boot) *(.boot)
*(.init) *(.start)
. = ALIGN(4096); . = ALIGN(4096);
} }
.flat : .flat . + 0xE0000000:
{ {
*(.flat) *(.flat) *(.text) *(.rdata) *(.data)
} }
__edata = .; __edata = . - 0xE0000000;
.bss ALIGN(4096) : .bss ALIGN(4096) :
{ {

View File

@ -2,16 +2,21 @@
CC = gcc CC = gcc
FASM = fasm.exe FASM = fasm.exe
INCLUDE = include INCLUDE = include/
CFLAGS = -c -O2 -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf -masm=intel DEFS = -DUSE_SMP
CFLAGS = -c -O2 -DCONFIG_DEBUG -I $(INCLUDE) -fomit-frame-pointer -fno-builtin-printf -masm=intel
LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32 LDFLAGS = -shared -s -Map kernel.map --image-base 0x100000 --file-alignment 32
KERNEL_SRC:= \ KERNEL_SRC:= \
kernel.asm \ kernel.asm \
init.c \
mm.c \
spinlock.c \
boot/boot.asm \ boot/boot.asm \
boot/init.asm boot/start.asm
KERNEL_OBJS = $(patsubst %.s, bin/%.obj, $(patsubst %.asm, bin/%.obj,\ KERNEL_OBJS = $(patsubst %.s, bin/%.obj, $(patsubst %.asm, bin/%.obj,\
@ -25,13 +30,13 @@ kernel.gz :kernel.mnt
kernel.mnt: $(KERNEL_OBJS) Makefile ld.x kernel.mnt: $(KERNEL_OBJS) Makefile ld.x
ld $(LDFLAGS) -T ld.x -o $@ $(KERNEL_OBJS) ld $(LDFLAGS) -T ld.x -o $@ $(KERNEL_OBJS)
bin/%.obj : core/%.c Makefile
$(CC) $(CFLAGS) -o $@ $<
bin/%.obj: %.asm bin/%.obj: %.asm
$(FASM) $< $@ $(FASM) $< $@
bin/%.obj : core/%.c
$(CC) $(CFLAGS) -o $@ -c $<
all: $(SUBDIRS) all: $(SUBDIRS)
.PHONY: all .PHONY: all

View File

@ -458,7 +458,7 @@ SIS900_init_txd:
;*************** load Transmit Descriptor Register *************** ;*************** load Transmit Descriptor Register ***************
mov dx, [io_addr] ; base address mov dx, [io_addr] ; base address
add dx, SIS900_txdp ; TX Descriptor Pointer add dx, SIS900_txdp ; TX Descriptor Pointer
mov eax, txd - OS_BASE ; First Descriptor mov eax, txd + (0x100000000-OS_BASE) ; First Descriptor
out dx, eax ; move the pointer out dx, eax ; move the pointer
ret ret
@ -484,9 +484,9 @@ SIS900_init_rxd_Loop:
cmp ebx, NUM_RX_DESC ; cmp ebx, NUM_RX_DESC ;
jne SIS900_init_rxd_Loop_0 ; jne SIS900_init_rxd_Loop_0 ;
xor ebx, ebx ; xor ebx, ebx ;
SIS900_init_rxd_Loop_0: ; SIS900_init_rxd_Loop_0: ;
imul ebx, 12 ; imul ebx, 12 ;
add ebx, rxd - OS_BASE ; add ebx, rxd + (0x100000000-OS_BASE);
mov [rxd+eax], ebx ;save link to next descriptor mov [rxd+eax], ebx ;save link to next descriptor
mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size
mov ebx, ecx ;find where the buf is located mov ebx, ecx ;find where the buf is located
@ -500,7 +500,7 @@ SIS900_init_rxd_Loop_0: ;
; descriptor********* ; descriptor*********
mov dx, [io_addr] mov dx, [io_addr]
add dx, SIS900_rxdp add dx, SIS900_rxdp
mov eax, rxd - OS_BASE mov eax, rxd + (0x100000000-OS_BASE)
out dx, eax out dx, eax
ret ret
@ -998,7 +998,7 @@ SIS900_transmit:
out dx, eax out dx, eax
;*******load Transmit Descriptor Register ******* ;*******load Transmit Descriptor Register *******
lea edx,[ebp+SIS900_txdp] lea edx,[ebp+SIS900_txdp]
mov eax, txd - OS_BASE mov eax, txd + (0x100000000-OS_BASE)
out dx, eax out dx, eax
;******* copy packet to descriptor******* ;******* copy packet to descriptor*******
push esi push esi