3 ; (A20 enable code and PIC reprogram from linux bootsector)
7 ; Base address of the kernel
9 KERNEL_BASE equ 0c0000000h
20 ; Space reserved in the gdt for tss descriptors
25 ; We are a .com program
45 ; Setup the loader space
55 ; Calculate the end of this module
63 ; Round up to the nearest page
69 ; Set the start of the page directory
71 mov [kernel_page_directory_base],ebx
74 ; Set the start of the continuous range of physical memory
75 ; occupied by the kernel
81 ; Calculate the start of the system page table (0xc0000000 upwards)
83 mov [system_page_table_base],ebx
87 ; Calculate the start of the page table to map the first 4mb
89 mov [lowmem_page_table_base],ebx
93 ; Set the position for the first module to be loaded
95 mov [next_load_base],ebx
98 ; Set the address of the start of kernel code
100 mov [_start_kernel],ebx
103 ; Make the argument list into a c string
117 mov [end_cmd_line],di
126 ; Process the arguments
148 ; Move onto the next module name in the command line
151 cmp di,[end_cmd_line]
164 ; Set the end of kernel memory
166 mov eax,[next_load_base]
170 ; Begin the pmode initalization
179 ; Any errors detected jump here
190 ; Read in a file to kernel_base, set kernel base to the end of the file in
191 ; memory rounded up to the nearest page
197 inc dword [_nr_files]
220 ; Convert the filelength in DX:AX to a dword in EBX
227 ; Record the length of the module in boot parameter table
231 mov [_module_lengths+esi*4],ebx
234 ; Convert the length into
237 and word [size_mod_4k],0fffh
240 mov [size_div_4k],ebx
244 ; Seek to beginning of file
260 ; Convert the linear point to the load address into a seg:off
262 mov edi,[next_load_base]
267 ; Move onto the next position in prepartion for a future read
269 mov eax,[size_div_4k]
276 add [next_load_base],eax
282 ; We read the kernel in 4k chunks (because)
286 ; Check if we have read it all
288 mov ax,[es:size_div_4k]
293 ; Make the call (dx was loaded above)
296 mov bx,[es:file_handle]
301 ; We move onto the next pointer by altering ds
306 dec word [es:size_div_4k]
311 ; Read the last section
314 mov bx,[es:file_handle]
315 mov cx,[es:size_mod_4k]
343 ; Print string in DS:DI
364 ; Handle of the currently open file
369 ; Size of the current file mod 4k
374 ; Size of the current file divided by 4k
384 ; Generic error message
386 err_msg db 'Error during operation',0
391 loading_msg db 'Loading: ',0
396 kernel_page_directory_base dd 0
397 system_page_table_base dd 0
398 lowmem_page_table_base dd 0
402 boot_param_struct_base dd 0
405 ; These variables are passed to the kernel (as a structure)
423 _end_boot_param_struct
426 ; Needed for enabling the a20 address line
442 dw (((6+NR_TASKS)*8)-1)
449 ; Setup kernel parameters
451 mov dword [_magic],0xdeadbeef
454 ; Save cursor position
468 add eax,_boot_param_struct
469 mov [boot_param_struct_base],eax
474 ; Zero out the kernel page directory
477 mov edi,[kernel_page_directory_base]
487 ; Map in the lowmem page table (and reuse it for the identity map)
489 mov edi,[kernel_page_directory_base]
492 mov eax,[lowmem_page_table_base]
495 mov [fs:di+(0xd0000000/(1024*1024))],eax
498 ; Map in the kernel page table
500 mov eax,[system_page_table_base]
505 ; Setup the lowmem page table
507 mov edi,[lowmem_page_table_base]
513 shl eax,12 ; ebx = ebx * 4096
514 add eax,07h ; user, rw, present
515 mov [fs:edi+ebx*4],eax
521 ; Setup the system page table
523 mov edi,[system_page_table_base]
529 add edx,[_start_kernel]
537 ; Load the page directory into cr3
539 mov eax,[kernel_page_directory_base]
543 ; Setup various variables
551 ; Enable the A20 address line (to allow access to over 1mb)
554 mov al,0D1h ; command write
562 ; Reprogram the PIC because they overlap the Intel defined
565 mov al,011h ; initialization sequence
566 out 020h,al ; send it to 8259A-1
567 dw 0x00eb,0x00eb ; jmp $+2, jmp $+2
568 out 0A0h,al ; and to 8259A-2
570 mov al,040h ; start of hardware int's (0x20)
573 mov al,048h ; start of hardware int's 2 (0x28)
576 mov al,04h ; 8259-1 is master
579 mov al,002h ; 8259-2 is slave
582 mov al,01h ; 8086 mode for both
587 mov al,0FFh ; mask off all interrupts for now
598 add eax,real_stack_end
599 mov [real_stack_base],eax
600 mov esp,[real_stack_base]
601 mov edx,[boot_param_struct_base]
609 ; Enter pmode and clear prefetch queue
617 ; NOTE: This must be position independant (no references to
618 ; non absolute variables)
622 ; Initalize segment registers
638 ; Jump to start of 32 bit code at c0000000
642 jmp dword KERNEL_CS:KERNEL_BASE
648 real_stack times 1024 db 0
655 ; Global descriptor table
659 dw 0 ; Zero descriptor
664 dw 00000h ; User code descriptor
665 dw 00000h ; base: 0h limit: 3gb
669 dw 00000h ; User data descriptor
670 dw 00000h ; base: 0h limit: 3gb
679 dw 0ffffh ; Kernel code descriptor
681 dw 09a00h ; base 0h limit 4gb
684 dw 0ffffh ; Kernel data descriptor
686 dw 09200h ; base 0h limit 4gb
690 times NR_TASKS*8 db 0