3 ; (A20 enable code and PIC reprogram from linux bootsector)
7 ; Base address of the kernel
14 %define KERNEL_CS (0x8)
15 %define KERNEL_DS (0x10)
16 %define LOADER_CS (0x18)
17 %define LOADER_DS (0x20)
19 struc multiboot_module
26 struc multiboot_address_range
30 mar_lengthhigh: resd 1
36 ; We are a .com program
74 mov sp, real_stack_end
78 ;; Setup the 32-bit registers
88 ;; Set the position for the first module to be loaded
90 mov dword [next_load_base], LOAD_BASE
93 ;; Setup various variables
101 ;; Setup the loader code and data segments
106 mov [_loader_code_base_0_15], ax
108 mov byte [_loader_code_base_16_23], al
113 mov [_loader_data_base_0_15], ax
115 mov byte [_loader_data_base_16_23], al
123 ;; Enable the A20 address line (to allow access to over 1mb)
126 mov al, 0D1h ; command write
129 mov al, 0DFh ; A20 on
134 ;; Make the argument list into a c string
142 je .end_of_command_line
147 .end_of_command_line:
150 mov [dos_cmdline_end], di
153 ;; Make the argument list into a c string
158 je .end_of_command_line2
165 .end_of_command_line2
168 ;; Check if we want to skip the first character
171 jne .first_char_is_zero
178 ;; Check if we have reached the end of the string
188 ;; Process the arguments
193 mov si, _multiboot_kernel_cmdline
204 cmp di, [dos_cmdline_end]
219 ;; Display a message saying we are loading the module
232 mov dx, [_multiboot_mods_count]
234 add dx, _multiboot_module_strings
235 mov bx, [_multiboot_mods_count]
236 imul bx, bx, multiboot_module_size
237 add bx, _multiboot_modules
242 mov [bx + mbm_string], eax
259 ; Check if it is a symbol file
273 ; Check if it is a symbol file
287 ;; Check for a module list file
306 mov bx,_lst_name_local
328 ;; We are here because the terminator was encountered
329 mov byte [bx],0 ; Zero terminate
332 mov [dos_cmdline_end],bx ; Put in cmd_line_length
333 mov dx,_lst_name_local; Put this address in di
334 mov di,dx ; This, too, at the start of the
358 ;; Move onto the next module name in the command line
361 cmp di, [dos_cmdline_end]
364 je .found_module_name
375 ;; Initialize the multiboot information
381 mov [_multiboot_info_base], eax
382 add dword [_multiboot_info_base], _multiboot_info
384 mov dword [_multiboot_flags], 0xc
386 mov [_multiboot_cmdline], eax
387 add dword [_multiboot_cmdline], _multiboot_kernel_cmdline
390 ;; Hide the kernel's entry in the list of modules
392 mov [_multiboot_mods_addr], eax
393 mov ebx, _multiboot_modules
394 add ebx, multiboot_module_size
395 add dword [_multiboot_mods_addr], ebx
396 dec dword [_multiboot_mods_count]
399 ;; get extended memory size in KB
403 mov [_multiboot_mem_upper],ebx
404 mov [_multiboot_mem_lower],ebx
415 mov [_multiboot_mem_upper],ebx
417 add dword [_multiboot_mem_upper],eax
426 mov [_multiboot_mem_upper], edx
428 add dword [_multiboot_mem_upper], ecx
432 ;; int 15h opt e801 don't work , try int 15h, option 88h
437 mov [_multiboot_mem_upper],ax
440 ;; int 15h opt 88h don't work , try read cmos
445 and eax, 0xffff ; clear carry
447 mov [_multiboot_mem_upper],eax
452 and eax, 0xffff ; clear carry
453 add [_multiboot_mem_lower],eax
458 ;; Retrieve BIOS memory map if available
461 mov edi, _multiboot_address_ranges
466 mov ecx, multiboot_address_range_size
474 add edi, multiboot_address_range_size
480 ;; Prepare multiboot memory map structures
483 ;; Fill in the address descriptor size field
484 mov dword [_multiboot_address_range_descriptor_size], multiboot_address_range_size
486 ;; Set flag and base address and length of memory map
487 or dword [_multiboot_flags], 40h
489 sub eax, _multiboot_address_ranges
490 mov dword [_multiboot_mmap_length], eax
495 mov [_multiboot_mmap_addr], eax
496 add dword [_multiboot_mmap_addr], _multiboot_address_ranges
503 ;; Begin the pmode initalization
507 ;; Save cursor position
509 mov ax, 3 ;! Reset video mode
516 mov ax, 1112h ;! Use 8x8 font
519 mov ax, 1200h ;! Use alternate print screen
522 mov ah, 1h ;! Define cursor (scan lines 6 to 7)
530 mov ah, 6 ; Scroll active page up
531 mov al, 32h ; Clear 50 lines
532 mov cx, 0 ; Upper left of scroll
533 mov dx, 314fh ; Lower right of scroll
534 mov bh, 1*10h+1 ; Use normal attribute on blanked lines
555 ; mov [_cursorx], eax
557 ; mov [_cursory], eax
562 ;; Load the absolute address of the multiboot information structure
564 mov ebx, [_multiboot_info_base]
567 ;; Enter pmode and clear prefetch queue
575 ;; NOTE: This must be position independant (no references to
576 ;; non absolute variables)
580 ;; Initalize segment registers
596 ;; Load the multiboot magic value into eax
601 ;; Jump to start of the kernel
603 jmp dword KERNEL_CS:(LOAD_BASE+0x1000)
615 ; Print string in DS:DI
676 ; print_ax - print the number in the ax register
786 times pe_doshdr_size db 0
804 mov edi, [next_load_base]
805 add edi, [_current_file_size]
814 ;; Clear unused space in the last page
838 ;; Read in the DOS EXE header
841 mov bx, [_current_filehandle]
842 mov cx, pe_doshdr_size
846 mov dx, error_file_read_failed
851 ;; Check the DOS EXE magic
853 mov ax, word [_cpe_doshdr + e_magic]
863 mov ebx, dword [_multiboot_mods_count]
871 mov bx, [_current_filehandle]
874 mov dx, error_file_seek_failed
878 mov bx, [_current_filehandle]
883 mov dx, error_file_read_failed
889 mov dword [_mb_bss_end_addr], 0
903 mov dx, error_file_open_failed
908 ;; Save the file handle
910 mov [_current_filehandle], ax
920 ;; Seek to the start of the file
923 mov bx, [_current_filehandle]
928 mov dx, error_file_seek_failed
935 ;; Seek to the end of the file to get the file size
941 mov bx, [_current_filehandle]
944 mov dx, error_file_seek_failed
949 mov [_current_size], edx
950 mov [_current_file_size], edx
956 mov bx, [_current_filehandle]
959 mov dx, error_file_seek_failed
963 mov edi, [next_load_base]
966 cmp dword [_current_size], 32768
970 ;; Read in the file data
974 mov bx, [_current_filehandle]
980 jnc .read_data_succeeded
982 mov dx, error_file_read_failed
984 .read_data_succeeded:
992 ;; Copy the file data just read in to high memory
1008 sub dword [_current_size], 32768
1013 ;; Read in the tailing part of the file data
1016 mov eax, [_current_size]
1019 mov bx, [_current_filehandle]
1024 jnc .read_last_data_succeeded
1026 mov dx, error_file_read_failed
1028 .read_last_data_succeeded:
1032 mov bx, [_current_filehandle]
1042 ;; Copy the tailing part to high memory
1045 mov ecx, [_current_size]
1058 mov edx, [_mb_bss_end_addr]
1071 mov bx, [_multiboot_mods_count]
1072 imul bx, bx, multiboot_module_size
1073 add bx, _multiboot_modules
1075 mov edx, [next_load_base]
1076 mov [bx + mbm_mod_start], edx
1077 mov [bx + mbm_mod_end], edi
1078 mov [next_load_base], edi
1079 mov dword [bx + mbm_reserved], 0
1081 inc dword [_multiboot_mods_count]
1088 ;; On error print a message and return zero
1097 ;; Copy to high memory
1099 ;; ESI = Source address
1100 ;; EDI = Destination address
1103 ;; EDI = End of the destination region
1115 cli ; No interrupts during pmode
1117 mov eax, cr0 ; Entered protected mode
1121 jmp .l1 ; Flush prefetch queue
1124 mov eax, KERNEL_DS ; Load DS with a suitable selector
1132 ; mov al, [esi] ; Copy the data
1140 mov eax, cr0 ; Leave protected mode
1156 loading_msg db 'Loading: ',0
1159 ;; Next free address in high memory
1164 ; Needed for enabling the a20 address line
1187 ;; Our initial stack
1189 real_stack times 1024 db 0
1193 ;; DOS commandline buffer
1195 dos_cmdline times 256 db 0
1196 dos_cmdline_end dw 0
1199 ;; Boot information structure
1201 _multiboot_info_base:
1207 _multiboot_mem_lower:
1209 _multiboot_mem_upper:
1211 _multiboot_boot_device:
1215 _multiboot_mods_count:
1217 _multiboot_mods_addr:
1221 _multiboot_mmap_length:
1223 _multiboot_mmap_addr:
1225 _multiboot_drives_count:
1227 _multiboot_drives_addr:
1229 _multiboot_config_table:
1231 _multiboot_boot_loader_name:
1233 _multiboot_apm_table:
1237 times (64*multiboot_module_size) db 0
1238 _multiboot_module_strings:
1241 _multiboot_address_range_descriptor_size dd 0
1243 _multiboot_address_ranges:
1244 times (64*multiboot_address_range_size) db 0
1246 _multiboot_kernel_cmdline:
1247 db 'multi(0)disk(0)rdisk(0)partition(1)\reactos'
1248 times 255-($-_multiboot_kernel_cmdline) db 0
1251 ;; Global descriptor table
1254 dw 0x0 ; Zero descriptor
1259 dw 0xffff ; Kernel code descriptor
1264 dw 0xffff ; Kernel data descriptor
1269 dw 0xffff ; Loader code descriptor
1270 _loader_code_base_0_15:
1272 _loader_code_base_16_23:
1277 dw 0xffff ; Loader data descriptor
1278 _loader_data_base_0_15:
1280 _loader_data_base_16_23:
1285 error_pmode_already:
1286 db 'Error: The processor is already in protected mode'
1288 error_file_open_failed:
1289 db 'Error: Failed to open file'
1291 error_file_seek_failed:
1292 db 'Error: File seek failed'
1294 error_file_read_failed:
1295 db 'Error: File read failed'
1297 error_coff_load_failed:
1298 db 'Error: Failed to load COFF file'
1301 db 'Error: Bad DOS EXE magic'