-;
-; Pmode setup stub
-; (A20 enable code and PIC reprogram from linux bootsector)
-;
-
-;
-; Base address of the kernel
-;
-KERNEL_BASE equ 0c0000000h
-
-;
-; Segment selectors
-;
-USER_CS equ 08h
-USER_DS equ 010h
-KERNEL_CS equ 020h
-KERNEL_DS equ 028h
-
-;
-; Space reserved in the gdt for tss descriptors
-;
-NR_TASKS equ 128
-
-;
-; We are a .com program
-;
-org 100h
-
-;
-; 16 bit code
-;
-BITS 16
-
-entry:
- ;
- ; Load stack
- ;
- cli
- push ds
- pop ss
- mov sp,real_stack_end
- sti
-
- ;
- ; Setup the loader space
- ;
- mov ebx,0
- mov eax,0
- mov ecx,0
- mov edx,0
- mov esi,0
- mov edi,0
-
- ;
- ; Calculate the end of this module
- ;
- mov ax,ds
- movzx ebx,ax
- shl ebx,4
- add ebx,_end
-
- ;
- ; Round up to the nearest page
- ;
- and ebx,~0xfff
- add ebx,01000h
-
- ;
- ; Set the start of the page directory
- ;
- mov [kernel_page_directory_base],ebx
-
- ;
- ; Set the start of the continuous range of physical memory
- ; occupied by the kernel
- ;
- mov [_start_mem],ebx
- add ebx,01000h
-
- ;
- ; Calculate the start of the system page table (0xc0000000 upwards)
- ;
- mov [system_page_table_base],ebx
- add ebx,01000h
-
- ;
- ; Calculate the start of the page table to map the first 4mb
- ;
- mov [lowmem_page_table_base],ebx
- add ebx,01000h
-
- ;
- ; Set the position for the first module to be loaded
- ;
- mov [next_load_base],ebx
-
- ;
- ; Set the address of the start of kernel code
- ;
- mov [_start_kernel],ebx
-
- ;
- ; Make the argument list into a c string
- ;
- mov di,081h
-l1:
- cmp byte [di],0dh
- je l2
- cmp byte [di],' '
- jne l12
- mov byte [di],0
-l12:
- inc di
- jmp l1
-l2:
- mov byte [di],0
- mov [end_cmd_line],di
-
- mov dx,082h
-l14:
- mov bx,dx
- cmp byte [bx],0
- je l16
-
- ;
- ; Process the arguments
- ;
- mov di,loading_msg
- call _print_string
- mov di,dx
- call _print_string
- mov ah,02h
- mov dl,0dh
- int 021h
- mov ah,02h
- mov dl,0ah
- int 021h
-
- ;
- ; Load the file
- ;
- push di
- mov dx,di
- call _load_file
- pop di
-
- ;
- ; Move onto the next module name in the command line
- ;
-l15:
- cmp di,[end_cmd_line]
- je l16
- cmp byte [di],0
- je l17
- inc di
- jmp l15
-l17:
- inc di
- mov dx,di
- jmp l14
-l16:
-
- ;
- ; Set the end of kernel memory
- ;
- mov eax,[next_load_base]
- mov [_end_mem],eax
-
- ;
- ; Begin the pmode initalization
- ;
- jmp _to_pmode
-
-exit:
- mov ax,04c00h
- int 21h
-
- ;
- ; Any errors detected jump here
- ;
-_error:
- mov di,err_msg
- call _print_string
- jmp exit
-
-end_cmd_line dw 0
-
-
-;
-; Read in a file to kernel_base, set kernel base to the end of the file in
-; memory rounded up to the nearest page
-;
-; In:
-; DI = filename
-;
-_load_file:
- inc dword [_nr_files]
-
- ;
- ; Open the file
- ;
- mov ah,03dh
- mov al,0
- mov dx,di
- int 021h
- jc _error
- mov [file_handle],ax
-
- ;
- ; Find filelength
- ;
- mov ah,042h
- mov al,2
- mov bx,[file_handle]
- mov cx,0
- mov dx,0
- int 021h
-
- ;
- ; Convert the filelength in DX:AX to a dword in EBX
- ;
- movzx ebx,dx
- shl ebx,16
- mov bx,ax
-
- ;
- ; Record the length of the module in boot parameter table
- ;
- mov esi,[_nr_files]
- dec esi
- mov [_module_lengths+esi*4],ebx
-
- ;
- ; Convert the length into
- ;
- mov [size_mod_4k],bx
- and word [size_mod_4k],0fffh
-
- shr ebx,12
- mov [size_div_4k],ebx
-
-
- ;
- ; Seek to beginning of file
- ;
- mov ah,042h
- mov al,0
- mov bx,[file_handle]
- mov cx,0
- mov dx,0
- int 021h
- jc _error
-
- ;
- ; Read in the module
- ;
- push ds
-
- ;
- ; Convert the linear point to the load address into a seg:off
- ;
- mov edi,[next_load_base]
- call convert_to_seg
- mov dx,di
-
- ;
- ; Move onto the next position in prepartion for a future read
- ;
- movzx eax,word [size_div_4k]
- mov bx,[size_mod_4k]
- cmp bx,0
- je l20
- inc eax
-l20:
- shl eax,0ch
- add [next_load_base],eax
-
- push fs
- pop ds
-
- ;
- ; We read the kernel in 4k chunks (because)
- ;
-l6:
- ;
- ; Check if we have read it all
- ;
- mov ax,[es:size_div_4k]
- cmp ax,0
- je l5
-
- ;
- ; Make the call (dx was loaded above)
- ;
- mov ah,3fh
- mov bx,[es:file_handle]
- mov cx,01000h
- int 21h
-
- ;
- ; We move onto the next pointer by altering ds
- ;
- mov ax,ds
- add ax,0100h
- mov ds,ax
- dec word [es:size_div_4k]
- jmp l6
-
-l5:
- ;
- ; Read the last section
- ;
- mov ah,3fh
- mov bx,[es:file_handle]
- mov cx,[es:size_mod_4k]
- int 21h
- pop ds
- jnc _no_error
- jmp _error
-
-_no_error:
- ret
-
-;
-; In: EDI = address
-; Out: FS = segment
-; DI = base
-;
-convert_to_seg:
- push eax
-
- mov eax,edi
- shr eax,16
- shl eax,12
- mov fs,ax
-
- and edi,0ffffh
-
- pop eax
- ret
-
-;
-; Print string in DS:DI
-;
-_print_string:
- push ax
- push dx
- push di
- mov ah,02h
-l3:
- mov dl,[di]
- cmp dl,0
- je l4
- int 021h
- inc di
- jmp l3
-l4:
- pop di
- pop dx
- pop ax
- ret
-
-;
-; Handle of the currently open file
-;
-file_handle dw 0
-
-;
-; Size of the current file mod 4k
-;
-size_mod_4k dw 0
-
-;
-; Size of the current file divided by 4k
-;
-size_div_4k dw 0
-
-;
-;
-;
-last_addr dw 0
-
-;
-; Generic error message
-;
-err_msg db 'Error during operation',0
-
-;
-;
-;
-loading_msg db 'Loading: ',0
-
-filelength_lo dw 0
-filelength_hi dw 0
-
-kernel_page_directory_base dd 0
-system_page_table_base dd 0
-lowmem_page_table_base dd 0
-next_load_base dd 0
-_start_kernel dd 0
-
-boot_param_struct_base dd 0
-
-;
-; These variables are passed to the kernel (as a structure)
-;
-align 4
-_boot_param_struct:
-_magic:
- dd 0
-_cursorx:
- dd 0
-_cursory:
- dd 0
-_nr_files:
- dd 0
-_start_mem:
- dd 0
-_end_mem:
- dd 0
-_module_lengths:
- times 64 dd 0
-_end_boot_param_struct
-
-;
-; Needed for enabling the a20 address line
-;
-empty_8042:
- jmp $+3
- jmp $+3
- in al,064h
- test al,02h
- jnz empty_8042
- ret
-
-;
-; GDT descriptor
-;
-align 8
-gdt_descr:
-gdt_limit:
- dw (((6+NR_TASKS)*8)-1)
-gdt_base:
- dd gdt
-
-
-_to_pmode:
- ;
- ; Setup kernel parameters
- ;
- mov dword [_magic],0xdeadbeef
-
- ;
- ; Save cursor position
- ;
- mov ah,03h
- mov bh,0h
- int 010h
- movzx eax,dl
- mov [_cursorx],eax
- movzx eax,dh
- mov [_cursory],eax
-
-
- mov bx,ds
- movzx eax,bx
- shl eax,4
- add eax,_boot_param_struct
- mov [boot_param_struct_base],eax
-
- cli
-
- ;
- ; Zero out the kernel page directory
- ;
- ;
- mov edi,[kernel_page_directory_base]
- call convert_to_seg
-
- mov cx,1024
-l10:
- mov dword [fs:di],0
- add di,4
- loop l10
-
- ;
- ; Map in the lowmem page table (and reuse it for the identity map)
- ;
- mov edi,[kernel_page_directory_base]
- call convert_to_seg
-
- mov eax,[lowmem_page_table_base]
- add eax,07h
- mov [fs:di],eax
- mov [fs:di+(0xd0000000/(1024*1024))],eax
-
- ;
- ; Map in the kernel page table
- ;
- mov eax,[system_page_table_base]
- add eax,07h
- mov [fs:di+3072],eax
-
- ;
- ; Setup the lowmem page table
- ;
- mov edi,[lowmem_page_table_base]
- call convert_to_seg
-
- mov ebx,0
-l9:
- mov eax,ebx
- shl eax,12 ; ebx = ebx * 4096
- add eax,07h ; user, rw, present
- mov [fs:edi+ebx*4],eax
- inc ebx
- cmp ebx,1024
- jl l9
-
- ;
- ; Setup the system page table
- ;
- mov edi,[system_page_table_base]
- call convert_to_seg
-
- mov eax,07h
-l8:
- mov edx,eax
- add edx,[_start_kernel]
- mov [fs:edi],edx
- add edi,4
- add eax,1000h
- cmp eax,100007h
- jl l8
-
- ;
- ; Load the page directory into cr3
- ;
- mov eax,[kernel_page_directory_base]
- mov cr3,eax
-
- ;
- ; Setup various variables
- ;
- mov bx,ds
- movzx eax,bx
- shl eax,4
- add [gdt_base],eax
-
- ;
- ; Enable the A20 address line (to allow access to over 1mb)
- ;
- call empty_8042
- mov al,0D1h ; command write
- out 064h,al
- call empty_8042
- mov al,0DFh ; A20 on
- out 060h,al
- call empty_8042
-
- ;
- ; Reprogram the PIC because they overlap the Intel defined
- ; exceptions
- ;
- mov al,011h ; initialization sequence
- out 020h,al ; send it to 8259A-1
- dw 0x00eb,0x00eb ; jmp $+2, jmp $+2
- out 0A0h,al ; and to 8259A-2
- dw 0x00eb,0x00eb
- mov al,020h ; start of hardware int's (0x20)
- out 021h,al
- dw 0x00eb,0x00eb
- mov al,028h ; start of hardware int's 2 (0x28)
- out 0A1h,al
- dw 0x00eb,0x00eb
- mov al,04h ; 8259-1 is master
- out 021h,al
- dw 0x00eb,0x00eb
- mov al,002h ; 8259-2 is slave
- out 0A1h,al
- dw 0x00eb,0x00eb
- mov al,01h ; 8086 mode for both
- out 021h,al
- dw 0x00eb,0x00eb
- out 0A1h,al
- dw 0x00eb,0x00eb
- mov al,0FFh ; mask off all interrupts for now
- out 021h,al
- dw 0x00eb,0x00eb
- out 0A1h,al
-
- ;
- ; Load stack
- ;
- mov bx,ds
- movzx eax,bx
- shl eax,4
- add eax,real_stack_end
- mov [real_stack_base],eax
- mov esp,[real_stack_base]
- mov edx,[boot_param_struct_base]
-
- ;
- ; load gdt
- ;
- lgdt [gdt_descr]
-
- ;
- ; Enter pmode and clear prefetch queue
- ;
- mov eax,cr0
- or eax,0x80000001
- mov cr0,eax
- jmp next
-next:
- ;
- ; NOTE: This must be position independant (no references to
- ; non absolute variables)
- ;
-
- ;
- ; Initalize segment registers
- ;
- mov ax,KERNEL_DS
- mov ds,ax
- mov ss,ax
- mov es,ax
- mov fs,ax
-
- ;
- ; Initalize eflags
- ;
- push dword 0
- popf
-
- ;
- ; Jump to start of 32 bit code at c0000000
- ;
- push edx
- push dword 0
- jmp dword KERNEL_CS:KERNEL_BASE
-
-
-;
-; Our initial stack
-;
-real_stack times 1024 db 0
-real_stack_end:
-
-real_stack_base dd 0
-
-
-;
-; Global descriptor table
-;
-align 8
-gdt:
- dw 0 ; Zero descriptor
- dw 0
- dw 0
- dw 0
-
- dw 00000h ; User code descriptor
- dw 00000h ; base: 0h limit: 3gb
- dw 0fa00h
- dw 000cch
-
- dw 00000h ; User data descriptor
- dw 00000h ; base: 0h limit: 3gb
- dw 0f200h
- dw 000cch
-
- dw 00000h
- dw 00000h
- dw 00000h
- dw 00000h
-
- dw 0ffffh ; Kernel code descriptor
- dw 00000h ;
- dw 09a00h ; base 0h limit 4gb
- dw 000cfh
-
- dw 0ffffh ; Kernel data descriptor
- dw 00000h ;
- dw 09200h ; base 0h limit 4gb
- dw 000cfh
-
-
- times NR_TASKS*8 db 0
-
-_end:
-
-
+;\r
+; Pmode setup stub\r
+; (A20 enable code and PIC reprogram from linux bootsector)\r
+;\r
+\r
+;\r
+; Base address of the kernel\r
+;\r
+KERNEL_BASE equ 0c0000000h\r
+\r
+;\r
+; Segment selectors\r
+;\r
+USER_CS equ 08h\r
+USER_DS equ 010h\r
+KERNEL_CS equ 020h\r
+KERNEL_DS equ 028h\r
+ \r
+;\r
+; Space reserved in the gdt for tss descriptors\r
+;\r
+NR_TASKS equ 128\r
+\r
+;\r
+; We are a .com program\r
+;\r
+org 100h\r
+\r
+;\r
+; 16 bit code\r
+;\r
+BITS 16\r
+\r
+entry:\r
+ ;\r
+ ; Load stack\r
+ ;\r
+ cli\r
+ push ds\r
+ pop ss\r
+ mov sp,real_stack_end\r
+ sti\r
+\r
+ ;\r
+ ; Setup the loader space\r
+ ;\r
+ mov ebx,0\r
+ mov eax,0\r
+ mov ecx,0\r
+ mov edx,0\r
+ mov esi,0\r
+ mov edi,0\r
+\r
+ ;\r
+ ; Calculate the end of this module\r
+ ;\r
+ mov ax,ds\r
+ movzx ebx,ax\r
+ shl ebx,4\r
+ add ebx,_end\r
+\r
+ ;\r
+ ; Round up to the nearest page\r
+ ;\r
+ and ebx,~0xfff\r
+ add ebx,01000h\r
+\r
+ ;\r
+ ; Set the start of the page directory\r
+ ;\r
+ mov [kernel_page_directory_base],ebx\r
+\r
+ ;\r
+ ; Set the start of the continuous range of physical memory\r
+ ; occupied by the kernel\r
+ ;\r
+ mov [_start_mem],ebx\r
+ add ebx,01000h\r
+\r
+ ;\r
+ ; Calculate the start of the system page table (0xc0000000 upwards)\r
+ ;\r
+ mov [system_page_table_base],ebx\r
+ add ebx,01000h\r
+\r
+ ;\r
+ ; Calculate the start of the page table to map the first 4mb\r
+ ;\r
+ mov [lowmem_page_table_base],ebx\r
+ add ebx,01000h\r
+\r
+ ;\r
+ ; Set the position for the first module to be loaded\r
+ ;\r
+ mov [next_load_base],ebx\r
+\r
+ ;\r
+ ; Set the address of the start of kernel code\r
+ ;\r
+ mov [_start_kernel],ebx\r
+\r
+ ;\r
+ ; Make the argument list into a c string\r
+ ;\r
+ mov di,081h\r
+l1:\r
+ cmp byte [di],0dh\r
+ je l2\r
+ cmp byte [di],' '\r
+ jne l12\r
+ mov byte [di],0\r
+l12:\r
+ inc di\r
+ jmp l1\r
+l2:\r
+ mov byte [di],0\r
+ mov [end_cmd_line],di\r
+\r
+ mov dx,082h\r
+l14:\r
+ mov bx,dx\r
+ cmp byte [bx],0\r
+ je l16\r
+\r
+ ;\r
+ ; Process the arguments\r
+ ;\r
+ mov di,loading_msg\r
+ call _print_string\r
+ mov di,dx\r
+ call _print_string\r
+ mov ah,02h\r
+ mov dl,0dh\r
+ int 021h\r
+ mov ah,02h\r
+ mov dl,0ah\r
+ int 021h\r
+\r
+ ;\r
+ ; Load the file\r
+ ;\r
+ push di\r
+ mov dx,di\r
+ call _load_file\r
+ pop di\r
+\r
+ ;\r
+ ; Move onto the next module name in the command line\r
+ ;\r
+l15:\r
+ cmp di,[end_cmd_line]\r
+ je l16\r
+ cmp byte [di],0\r
+ je l17\r
+ inc di\r
+ jmp l15\r
+l17:\r
+ inc di\r
+ mov dx,di\r
+ jmp l14\r
+l16:\r
+\r
+ ;\r
+ ; Set the end of kernel memory \r
+ ;\r
+ mov eax,[next_load_base]\r
+ mov [_end_mem],eax\r
+\r
+ ;\r
+ ; Begin the pmode initalization\r
+ ;\r
+ jmp _to_pmode\r
+\r
+exit:\r
+ mov ax,04c00h\r
+ int 21h\r
+\r
+ ;\r
+ ; Any errors detected jump here\r
+ ;\r
+_error:\r
+ mov di,err_msg\r
+ call _print_string\r
+ jmp exit\r
+\r
+end_cmd_line dw 0\r
+\r
+\r
+;\r
+; Read in a file to kernel_base, set kernel base to the end of the file in\r
+; memory rounded up to the nearest page\r
+;\r
+; In:\r
+; DI = filename\r
+;\r
+_load_file:\r
+ inc dword [_nr_files]\r
+\r
+ ;\r
+ ; Open the file\r
+ ;\r
+ mov ah,03dh\r
+ mov al,0\r
+ mov dx,di\r
+ int 021h\r
+ jc _error\r
+ mov [file_handle],ax\r
+ \r
+ ;\r
+ ; Find filelength\r
+ ;\r
+ mov ah,042h\r
+ mov al,2\r
+ mov bx,[file_handle]\r
+ mov cx,0\r
+ mov dx,0\r
+ int 021h\r
+\r
+ ;\r
+ ; Convert the filelength in DX:AX to a dword in EBX\r
+ ;\r
+ movzx ebx,dx\r
+ shl ebx,16\r
+ mov bx,ax\r
+\r
+ ;\r
+ ; Record the length of the module in boot parameter table\r
+ ;\r
+ mov esi,[_nr_files]\r
+ dec esi\r
+ mov [_module_lengths+esi*4],ebx\r
+\r
+ ; \r
+ ; Convert the length into \r
+ ;\r
+ mov [size_mod_4k],bx\r
+ and word [size_mod_4k],0fffh\r
+\r
+ shr ebx,12\r
+ mov [size_div_4k],ebx\r
+\r
+\r
+ ;\r
+ ; Seek to beginning of file\r
+ ;\r
+ mov ah,042h\r
+ mov al,0\r
+ mov bx,[file_handle]\r
+ mov cx,0\r
+ mov dx,0\r
+ int 021h\r
+ jc _error\r
+\r
+ ;\r
+ ; Read in the module\r
+ ;\r
+ push ds\r
+\r
+ ;\r
+ ; Convert the linear point to the load address into a seg:off\r
+ ;\r
+ mov edi,[next_load_base]\r
+ call convert_to_seg\r
+ mov dx,di\r
+\r
+ ;\r
+ ; Move onto the next position in prepartion for a future read\r
+ ;\r
+ mov eax,[size_div_4k]\r
+ mov bx,[size_mod_4k]\r
+ cmp bx,0\r
+ je l20\r
+ inc eax \r
+l20:\r
+ shl eax,0ch\r
+ add [next_load_base],eax\r
+\r
+ push fs\r
+ pop ds\r
+ \r
+ ;\r
+ ; We read the kernel in 4k chunks (because)\r
+ ;\r
+l6:\r
+ ;\r
+ ; Check if we have read it all\r
+ ;\r
+ mov ax,[es:size_div_4k]\r
+ cmp ax,0\r
+ je l5\r
+\r
+ ;\r
+ ; Make the call (dx was loaded above)\r
+ ;\r
+ mov ah,3fh\r
+ mov bx,[es:file_handle]\r
+ mov cx,01000h\r
+ int 21h \r
+\r
+ ;\r
+ ; We move onto the next pointer by altering ds\r
+ ;\r
+ mov ax,ds\r
+ add ax,0100h\r
+ mov ds,ax\r
+ dec word [es:size_div_4k]\r
+ jmp l6\r
+\r
+l5:\r
+ ;\r
+ ; Read the last section\r
+ ;\r
+ mov ah,3fh\r
+ mov bx,[es:file_handle]\r
+ mov cx,[es:size_mod_4k]\r
+ int 21h\r
+ pop ds\r
+ jnc _no_error\r
+ jmp _error\r
+\r
+_no_error:\r
+ ret\r
+\r
+;\r
+; In: EDI = address\r
+; Out: FS = segment\r
+; DI = base\r
+;\r
+convert_to_seg:\r
+ push eax\r
+\r
+ mov eax,edi\r
+ shr eax,16\r
+ shl eax,12\r
+ mov fs,ax\r
+\r
+ and edi,0ffffh\r
+\r
+ pop eax\r
+ ret\r
+\r
+;\r
+; Print string in DS:DI\r
+;\r
+_print_string:\r
+ push ax\r
+ push dx\r
+ push di\r
+ mov ah,02h\r
+l3:\r
+ mov dl,[di]\r
+ cmp dl,0\r
+ je l4\r
+ int 021h\r
+ inc di\r
+ jmp l3\r
+l4:\r
+ pop di\r
+ pop dx\r
+ pop ax\r
+ ret\r
+\r
+;\r
+; Handle of the currently open file\r
+;\r
+file_handle dw 0\r
+\r
+;\r
+; Size of the current file mod 4k\r
+;\r
+size_mod_4k dw 0\r
+\r
+;\r
+; Size of the current file divided by 4k\r
+;\r
+size_div_4k dd 0\r
+\r
+;\r
+;\r
+;\r
+last_addr dw 0\r
+\r
+;\r
+; Generic error message\r
+;\r
+err_msg db 'Error during operation',0\r
+\r
+;\r
+;\r
+;\r
+loading_msg db 'Loading: ',0\r
+\r
+filelength_lo dw 0\r
+filelength_hi dw 0\r
+\r
+kernel_page_directory_base dd 0\r
+system_page_table_base dd 0\r
+lowmem_page_table_base dd 0\r
+next_load_base dd 0\r
+_start_kernel dd 0\r
+\r
+boot_param_struct_base dd 0\r
+\r
+;\r
+; These variables are passed to the kernel (as a structure)\r
+;\r
+align 4\r
+_boot_param_struct:\r
+_magic:\r
+ dd 0\r
+_cursorx:\r
+ dd 0\r
+_cursory:\r
+ dd 0\r
+_nr_files:\r
+ dd 0\r
+_start_mem:\r
+ dd 0\r
+_end_mem:\r
+ dd 0\r
+_module_lengths:\r
+ times 64 dd 0\r
+_end_boot_param_struct\r
+ \r
+;\r
+; Needed for enabling the a20 address line\r
+;\r
+empty_8042:\r
+ jmp $+3\r
+ jmp $+3\r
+ in al,064h\r
+ test al,02h\r
+ jnz empty_8042\r
+ ret\r
+\r
+;\r
+; GDT descriptor\r
+;\r
+align 8\r
+gdt_descr:\r
+gdt_limit:\r
+ dw (((6+NR_TASKS)*8)-1)\r
+gdt_base:\r
+ dd gdt\r
+\r
+\r
+_to_pmode:\r
+ ;\r
+ ; Setup kernel parameters\r
+ ;\r
+ mov dword [_magic],0xdeadbeef\r
+\r
+ ;\r
+ ; Save cursor position\r
+ ;\r
+ mov ah,03h\r
+ mov bh,0h\r
+ int 010h\r
+ movzx eax,dl\r
+ mov [_cursorx],eax\r
+ movzx eax,dh\r
+ mov [_cursory],eax\r
+\r
+\r
+ mov bx,ds\r
+ movzx eax,bx\r
+ shl eax,4\r
+ add eax,_boot_param_struct\r
+ mov [boot_param_struct_base],eax \r
+\r
+ cli\r
+\r
+ ;\r
+ ; Zero out the kernel page directory\r
+ ;\r
+ ;\r
+ mov edi,[kernel_page_directory_base]\r
+ call convert_to_seg\r
+\r
+ mov cx,1024\r
+l10:\r
+ mov dword [fs:di],0\r
+ add di,4\r
+ loop l10\r
+\r
+ ;\r
+ ; Map in the lowmem page table (and reuse it for the identity map)\r
+ ;\r
+ mov edi,[kernel_page_directory_base]\r
+ call convert_to_seg\r
+\r
+ mov eax,[lowmem_page_table_base]\r
+ add eax,07h\r
+ mov [fs:di],eax\r
+ mov [fs:di+(0xd0000000/(1024*1024))],eax\r
+\r
+ ;\r
+ ; Map in the kernel page table\r
+ ;\r
+ mov eax,[system_page_table_base]\r
+ add eax,07h\r
+ mov [fs:di+3072],eax\r
+\r
+ ;\r
+ ; Setup the lowmem page table\r
+ ;\r
+ mov edi,[lowmem_page_table_base]\r
+ call convert_to_seg\r
+\r
+ mov ebx,0\r
+l9:\r
+ mov eax,ebx\r
+ shl eax,12 ; ebx = ebx * 4096\r
+ add eax,07h ; user, rw, present\r
+ mov [fs:edi+ebx*4],eax\r
+ inc ebx\r
+ cmp ebx,1024\r
+ jl l9\r
+\r
+ ;\r
+ ; Setup the system page table\r
+ ;\r
+ mov edi,[system_page_table_base]\r
+ call convert_to_seg\r
+\r
+ mov eax,07h\r
+l8:\r
+ mov edx,eax\r
+ add edx,[_start_kernel]\r
+ mov [fs:edi],edx\r
+ add edi,4\r
+ add eax,1000h\r
+ cmp eax,100007h\r
+ jl l8\r
+ \r
+ ;\r
+ ; Load the page directory into cr3\r
+ ;\r
+ mov eax,[kernel_page_directory_base]\r
+ mov cr3,eax\r
+\r
+ ;\r
+ ; Setup various variables\r
+ ;\r
+ mov bx,ds\r
+ movzx eax,bx\r
+ shl eax,4\r
+ add [gdt_base],eax\r
+\r
+ ;\r
+ ; Enable the A20 address line (to allow access to over 1mb)\r
+ ;\r
+ call empty_8042\r
+ mov al,0D1h ; command write\r
+ out 064h,al\r
+ call empty_8042\r
+ mov al,0DFh ; A20 on\r
+ out 060h,al\r
+ call empty_8042\r
+\r
+ ;\r
+ ; Reprogram the PIC because they overlap the Intel defined\r
+ ; exceptions \r
+ ;\r
+ mov al,011h ; initialization sequence\r
+ out 020h,al ; send it to 8259A-1\r
+ dw 0x00eb,0x00eb ; jmp $+2, jmp $+2\r
+ out 0A0h,al ; and to 8259A-2\r
+ dw 0x00eb,0x00eb\r
+ mov al,020h ; start of hardware int's (0x20)\r
+ out 021h,al\r
+ dw 0x00eb,0x00eb\r
+ mov al,028h ; start of hardware int's 2 (0x28)\r
+ out 0A1h,al\r
+ dw 0x00eb,0x00eb\r
+ mov al,04h ; 8259-1 is master\r
+ out 021h,al\r
+ dw 0x00eb,0x00eb\r
+ mov al,002h ; 8259-2 is slave\r
+ out 0A1h,al\r
+ dw 0x00eb,0x00eb\r
+ mov al,01h ; 8086 mode for both\r
+ out 021h,al\r
+ dw 0x00eb,0x00eb\r
+ out 0A1h,al\r
+ dw 0x00eb,0x00eb\r
+ mov al,0FFh ; mask off all interrupts for now\r
+ out 021h,al\r
+ dw 0x00eb,0x00eb\r
+ out 0A1h,al\r
+\r
+ ;\r
+ ; Load stack\r
+ ;\r
+ mov bx,ds\r
+ movzx eax,bx\r
+ shl eax,4\r
+ add eax,real_stack_end\r
+ mov [real_stack_base],eax\r
+ mov esp,[real_stack_base]\r
+ mov edx,[boot_param_struct_base]\r
+\r
+ ;\r
+ ; load gdt\r
+ ;\r
+ lgdt [gdt_descr]\r
+\r
+ ; \r
+ ; Enter pmode and clear prefetch queue\r
+ ;\r
+ mov eax,cr0\r
+ or eax,0x80000001\r
+ mov cr0,eax\r
+ jmp next\r
+next:\r
+ ;\r
+ ; NOTE: This must be position independant (no references to\r
+ ; non absolute variables)\r
+ ;\r
+\r
+ ;\r
+ ; Initalize segment registers\r
+ ;\r
+ mov ax,KERNEL_DS\r
+ mov ds,ax\r
+ mov ss,ax \r
+ mov es,ax\r
+ mov fs,ax\r
+\r
+ ;\r
+ ; Initalize eflags\r
+ ;\r
+ push dword 0\r
+ popf\r
+\r
+ ;\r
+ ; Jump to start of 32 bit code at c0000000\r
+ ;\r
+ push edx\r
+ push dword 0\r
+ jmp dword KERNEL_CS:KERNEL_BASE\r
+\r
+\r
+;\r
+; Our initial stack\r
+;\r
+real_stack times 1024 db 0\r
+real_stack_end:\r
+\r
+real_stack_base dd 0\r
+\r
+\r
+;\r
+; Global descriptor table\r
+;\r
+align 8\r
+gdt:\r
+ dw 0 ; Zero descriptor\r
+ dw 0\r
+ dw 0\r
+ dw 0\r
+ \r
+ dw 00000h ; User code descriptor\r
+ dw 00000h ; base: 0h limit: 3gb\r
+ dw 0fa00h\r
+ dw 000cch\r
+ \r
+ dw 00000h ; User data descriptor\r
+ dw 00000h ; base: 0h limit: 3gb\r
+ dw 0f200h\r
+ dw 000cch\r
+ \r
+ dw 00000h \r
+ dw 00000h \r
+ dw 00000h\r
+ dw 00000h\r
+\r
+ dw 0ffffh ; Kernel code descriptor \r
+ dw 00000h ; \r
+ dw 09a00h ; base 0h limit 4gb\r
+ dw 000cfh\r
+ \r
+ dw 0ffffh ; Kernel data descriptor\r
+ dw 00000h ; \r
+ dw 09200h ; base 0h limit 4gb\r
+ dw 000cfh\r
+\r
+ \r
+ times NR_TASKS*8 db 0\r
+\r
+_end:\r
+\r
+\r
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
if (current->BaseAddress >= Address &&
- current->BaseAddress < (Address+Length))
+ current->BaseAddress <= (Address+Length))
{
DPRINT("Finished MmInternalOpenMemoryAreaByRegion()\n",0);
return(current);
}
Extent = current->BaseAddress + current->Length;
- if (Extent >= Address &&
+ if (Extent > Address &&
Extent < (Address+Length))
{
DPRINT("Finished MmInternalOpenMemoryAreaByRegion()\n",0);
ListHead = &SystemAreaList;
}
else
- {
+ {
ListHead = &(KeGetCurrentProcess()->MemoryAreaList);
}
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry);
- DPRINT("current %x current->BaseAddress %x\n",current,
+ DPRINT("current %x current->BaseAddress %x ",current,
current->BaseAddress);
DPRINT("current->Length %x\n",current->Length);
- DPRINT("next %x next->BaseAddress %x\n",next,next->BaseAddress);
+ DPRINT("next %x next->BaseAddress %x ",next,next->BaseAddress);
Gap = (next->BaseAddress ) -(current->BaseAddress + current->Length);
- DPRINT("Gap %x\n",Gap);
+ DPRINT("Base %x Gap %x\n",current->BaseAddress,Gap);
if (Gap >= Length)
{
return(current->BaseAddress + current->Length);
current_entry = current_entry->Flink;
}
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
+ //DbgPrint("current %x returning %x\n",current,current->BaseAddress+
+// current->Length);
return(current->BaseAddress + current->Length);
}
NTSTATUS MmInitMemoryAreas(VOID)
+/*
+ * FUNCTION: Initialize the memory area list
+ */
{
DPRINT("MmInitMemoryAreas()\n",0);
InitializeListHead(&SystemAreaList);
DPRINT("MmCreateMemoryArea(Mode %x, Type %d, BaseAddress %x,"
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
Mode,Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
-
+// DbgPrint("Start1 %x\n",*((unsigned int *)0xc0017000));
MmLockMemoryAreaList(*BaseAddress,&oldlvl);
+// DbgPrint("Start1 %x\n",*((unsigned int *)0xc0017000));
if ((*BaseAddress)==0)
{
- *BaseAddress = MmFindGapWithoutLock(Mode,Length+(PAGESIZE*2));
+ *BaseAddress = MmFindGapWithoutLock(Mode,PAGE_ROUND_UP(Length)
+ +(PAGESIZE*2));
if ((*BaseAddress)==0)
{
MmUnlockMemoryAreaList(*BaseAddress,&oldlvl);
}
}
+// DbgPrint("Start1 %x\n",*((unsigned int *)0xc0017000));
*Result = ExAllocatePool(NonPagedPool,sizeof(MEMORY_AREA));
+// DbgPrint("Start1 %x\n",*((unsigned int *)0xc0017000));
RtlZeroMemory(*Result,sizeof(MEMORY_AREA));
+// DbgPrint("Start1 %x\n",*((unsigned int *)0xc0017000));
(*Result)->Type=Type;
(*Result)->BaseAddress=*BaseAddress;
(*Result)->Length=Length;
(*Result)->Attributes=Attributes;
DPRINT("&SystemAreaList %x ",&SystemAreaList);
DPRINT("SystemAreaList.Flink %x ",SystemAreaList.Flink);
+// DbgPrint("Start1 %x\n",*((unsigned int *)0xc0017000));
MmInsertMemoryAreaWithoutLock(*Result);
+// DbgPrint("(%s:%d) Start1 %x\n",__FILE__,__LINE__,
+// *((unsigned int *)0xc0017000));
MmUnlockMemoryAreaList(*BaseAddress,&oldlvl);
+// DbgPrint("Start1 %x\n",*((unsigned int *)0xc0017000));
DPRINT("SystemAreaList.Flink %x ",SystemAreaList.Flink);
DPRINT("(*Result)->Entry.Flink %x\n",(*Result)->Entry.Flink);
MmDumpMemoryAreas();