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 binary hive file
273 ; Check if it is a symbol file
287 ; Check if it is a hive file
301 ; Check if it is a NLS file
315 ;; Check for a module list file
334 mov bx,_lst_name_local
356 ;; We are here because the terminator was encountered
357 mov byte [bx],0 ; Zero terminate
360 mov [dos_cmdline_end],bx ; Put in cmd_line_length
361 mov dx,_lst_name_local; Put this address in di
362 mov di,dx ; This, too, at the start of the
386 ;; Move onto the next module name in the command line
389 cmp di, [dos_cmdline_end]
392 je .found_module_name
403 ;; Initialize the multiboot information
409 mov [_multiboot_info_base], eax
410 add dword [_multiboot_info_base], _multiboot_info
412 mov dword [_multiboot_flags], 0xc
414 mov [_multiboot_cmdline], eax
415 add dword [_multiboot_cmdline], _multiboot_kernel_cmdline
418 ;; Hide the kernel's entry in the list of modules
420 mov [_multiboot_mods_addr], eax
421 mov ebx, _multiboot_modules
422 add ebx, multiboot_module_size
423 add dword [_multiboot_mods_addr], ebx
424 dec dword [_multiboot_mods_count]
427 ;; get extended memory size in KB
431 mov [_multiboot_mem_upper],ebx
432 mov [_multiboot_mem_lower],ebx
443 mov [_multiboot_mem_upper],ebx
445 add dword [_multiboot_mem_upper],eax
454 mov [_multiboot_mem_upper], edx
456 add dword [_multiboot_mem_upper], ecx
460 ;; int 15h opt e801 don't work , try int 15h, option 88h
465 mov [_multiboot_mem_upper],ax
468 ;; int 15h opt 88h don't work , try read cmos
473 and eax, 0xffff ; clear carry
475 mov [_multiboot_mem_upper],eax
480 and eax, 0xffff ; clear carry
481 add [_multiboot_mem_lower],eax
486 ;; Retrieve BIOS memory map if available
489 mov edi, _multiboot_address_ranges
494 mov ecx, multiboot_address_range_size
502 add edi, multiboot_address_range_size
508 ;; Prepare multiboot memory map structures
511 ;; Fill in the address descriptor size field
512 mov dword [_multiboot_address_range_descriptor_size], multiboot_address_range_size
514 ;; Set flag and base address and length of memory map
515 or dword [_multiboot_flags], 40h
517 sub eax, _multiboot_address_ranges
518 mov dword [_multiboot_mmap_length], eax
523 mov [_multiboot_mmap_addr], eax
524 add dword [_multiboot_mmap_addr], _multiboot_address_ranges
531 ;; Begin the pmode initalization
535 ;; Save cursor position
537 mov ax, 3 ;! Reset video mode
544 mov ax, 1112h ;! Use 8x8 font
547 mov ax, 1200h ;! Use alternate print screen
550 mov ah, 1h ;! Define cursor (scan lines 6 to 7)
558 mov ah, 6 ; Scroll active page up
559 mov al, 32h ; Clear 50 lines
560 mov cx, 0 ; Upper left of scroll
561 mov dx, 314fh ; Lower right of scroll
562 mov bh, 1*10h+1 ; Use normal attribute on blanked lines
583 ; mov [_cursorx], eax
585 ; mov [_cursory], eax
590 ;; Load the absolute address of the multiboot information structure
592 mov ebx, [_multiboot_info_base]
595 ;; Enter pmode and clear prefetch queue
603 ;; NOTE: This must be position independant (no references to
604 ;; non absolute variables)
608 ;; Initalize segment registers
624 ;; Load the multiboot magic value into eax
629 ;; Jump to start of the kernel
631 jmp dword KERNEL_CS:(LOAD_BASE+0x1000)
643 ; Print string in DS:DI
704 ; print_ax - print the number in the ax register
814 times pe_doshdr_size db 0
832 mov edi, [next_load_base]
833 add edi, [_current_file_size]
842 ;; Clear unused space in the last page
866 ;; Read in the DOS EXE header
869 mov bx, [_current_filehandle]
870 mov cx, pe_doshdr_size
874 mov di, error_file_read_failed
879 ;; Check the DOS EXE magic
881 mov ax, word [_cpe_doshdr + e_magic]
891 mov ebx, dword [_multiboot_mods_count]
899 mov bx, [_current_filehandle]
902 mov di, error_file_seek_failed
906 mov bx, [_current_filehandle]
911 mov di, error_file_read_failed
917 mov dword [_mb_bss_end_addr], 0
931 mov di, error_file_open_failed
936 ;; Save the file handle
938 mov [_current_filehandle], ax
948 ;; Seek to the start of the file
951 mov bx, [_current_filehandle]
956 mov di, error_file_seek_failed
963 ;; Seek to the end of the file to get the file size
969 mov bx, [_current_filehandle]
972 mov di, error_file_seek_failed
977 mov [_current_size], edx
978 mov [_current_file_size], edx
984 mov bx, [_current_filehandle]
987 mov di, error_file_seek_failed
991 mov edi, [next_load_base]
994 cmp dword [_current_size], 32768
998 ;; Read in the file data
1002 mov bx, [_current_filehandle]
1008 jnc .read_data_succeeded
1010 mov di, error_file_read_failed
1012 .read_data_succeeded:
1020 ;; Copy the file data just read in to high memory
1036 sub dword [_current_size], 32768
1041 ;; Read in the tailing part of the file data
1044 mov eax, [_current_size]
1047 mov bx, [_current_filehandle]
1052 jnc .read_last_data_succeeded
1054 mov di, error_file_read_failed
1056 .read_last_data_succeeded:
1061 mov bx, [_current_filehandle]
1071 ;; Copy the tailing part to high memory
1073 mov ecx, [_current_size]
1086 mov edx, [_mb_bss_end_addr]
1099 mov bx, [_multiboot_mods_count]
1100 imul bx, bx, multiboot_module_size
1101 add bx, _multiboot_modules
1103 mov edx, [next_load_base]
1104 mov [bx + mbm_mod_start], edx
1105 mov [bx + mbm_mod_end], edi
1106 mov [next_load_base], edi
1107 mov dword [bx + mbm_reserved], 0
1109 inc dword [_multiboot_mods_count]
1116 ;; On error print a message and return zero
1124 ;; Copy to high memory
1126 ;; ESI = Source address
1127 ;; EDI = Destination address
1130 ;; EDI = End of the destination region
1142 cli ; No interrupts during pmode
1144 mov eax, cr0 ; Entered protected mode
1148 jmp .l1 ; Flush prefetch queue
1151 mov eax, KERNEL_DS ; Load DS with a suitable selector
1159 ; mov al, [esi] ; Copy the data
1167 mov eax, cr0 ; Leave protected mode
1183 loading_msg db 'Loading: ',0
1186 ;; Next free address in high memory
1191 ; Needed for enabling the a20 address line
1214 ;; Our initial stack
1216 real_stack times 1024 db 0
1220 ;; DOS commandline buffer
1222 dos_cmdline times 256 db 0
1223 dos_cmdline_end dw 0
1226 ;; Boot information structure
1228 _multiboot_info_base:
1234 _multiboot_mem_lower:
1236 _multiboot_mem_upper:
1238 _multiboot_boot_device:
1242 _multiboot_mods_count:
1244 _multiboot_mods_addr:
1248 _multiboot_mmap_length:
1250 _multiboot_mmap_addr:
1252 _multiboot_drives_count:
1254 _multiboot_drives_addr:
1256 _multiboot_config_table:
1258 _multiboot_boot_loader_name:
1260 _multiboot_apm_table:
1264 times (64*multiboot_module_size) db 0
1265 _multiboot_module_strings:
1268 _multiboot_address_range_descriptor_size dd 0
1270 _multiboot_address_ranges:
1271 times (64*multiboot_address_range_size) db 0
1273 _multiboot_kernel_cmdline:
1274 db 'multi(0)disk(0)rdisk(0)partition(1)\reactos'
1275 times 255-($-_multiboot_kernel_cmdline) db 0
1278 ;; Global descriptor table
1281 dw 0x0 ; Zero descriptor
1286 dw 0xffff ; Kernel code descriptor
1291 dw 0xffff ; Kernel data descriptor
1296 dw 0xffff ; Loader code descriptor
1297 _loader_code_base_0_15:
1299 _loader_code_base_16_23:
1304 dw 0xffff ; Loader data descriptor
1305 _loader_data_base_0_15:
1307 _loader_data_base_16_23:
1312 error_pmode_already:
1314 db 'Error: The processor is already in protected mode'
1316 error_file_open_failed:
1318 db 'Error: Failed to open file (code 0x%a)'
1320 error_file_seek_failed:
1322 db 'Error: File seek failed (code 0x%a)'
1324 error_file_read_failed:
1326 db 'Error: File read failed (code 0x%a)'
1330 db 'Error: Bad DOS EXE magic'