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 movzx eax,word [size_div_4k]
277 add [next_load_base],eax
283 ; We read the kernel in 4k chunks (because)
287 ; Check if we have read it all
289 mov ax,[es:size_div_4k]
294 ; Make the call (dx was loaded above)
297 mov bx,[es:file_handle]
302 ; We move onto the next pointer by altering ds
307 dec word [es:size_div_4k]
312 ; Read the last section
315 mov bx,[es:file_handle]
316 mov cx,[es:size_mod_4k]
344 ; Print string in DS:DI
365 ; Handle of the currently open file
370 ; Size of the current file mod 4k
375 ; Size of the current file divided by 4k
385 ; Generic error message
387 err_msg db 'Error during operation',0
392 loading_msg db 'Loading: ',0
397 kernel_page_directory_base dd 0
398 system_page_table_base dd 0
399 lowmem_page_table_base dd 0
403 boot_param_struct_base dd 0
406 ; These variables are passed to the kernel (as a structure)
424 _end_boot_param_struct
427 ; Needed for enabling the a20 address line
443 dw (((6+NR_TASKS)*8)-1)
450 ; Setup kernel parameters
452 mov dword [_magic],0xdeadbeef
455 ; Save cursor position
469 add eax,_boot_param_struct
470 mov [boot_param_struct_base],eax
475 ; Zero out the kernel page directory
478 mov edi,[kernel_page_directory_base]
488 ; Map in the lowmem page table (and reuse it for the identity map)
490 mov edi,[kernel_page_directory_base]
493 mov eax,[lowmem_page_table_base]
496 mov [fs:di+(0xd0000000/(1024*1024))],eax
499 ; Map in the kernel page table
501 mov eax,[system_page_table_base]
506 ; Setup the lowmem page table
508 mov edi,[lowmem_page_table_base]
514 shl eax,12 ; ebx = ebx * 4096
515 add eax,07h ; user, rw, present
516 mov [fs:edi+ebx*4],eax
522 ; Setup the system page table
524 mov edi,[system_page_table_base]
530 add edx,[_start_kernel]
538 ; Load the page directory into cr3
540 mov eax,[kernel_page_directory_base]
544 ; Setup various variables
552 ; Enable the A20 address line (to allow access to over 1mb)
555 mov al,0D1h ; command write
563 ; Reprogram the PIC because they overlap the Intel defined
566 mov al,011h ; initialization sequence
567 out 020h,al ; send it to 8259A-1
568 dw 0x00eb,0x00eb ; jmp $+2, jmp $+2
569 out 0A0h,al ; and to 8259A-2
571 mov al,020h ; start of hardware int's (0x20)
574 mov al,028h ; start of hardware int's 2 (0x28)
577 mov al,04h ; 8259-1 is master
580 mov al,002h ; 8259-2 is slave
583 mov al,01h ; 8086 mode for both
588 mov al,0FFh ; mask off all interrupts for now
599 add eax,real_stack_end
600 mov [real_stack_base],eax
601 mov esp,[real_stack_base]
602 mov edx,[boot_param_struct_base]
610 ; Enter pmode and clear prefetch queue
618 ; NOTE: This must be position independant (no references to
619 ; non absolute variables)
623 ; 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