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 for a module list file
320 mov bx,_lst_name_local
342 ;; We are here because the terminator was encountered
343 mov byte [bx],0 ; Zero terminate
346 mov [dos_cmdline_end],bx ; Put in cmd_line_length
347 mov dx,_lst_name_local; Put this address in di
348 mov di,dx ; This, too, at the start of the
372 ;; Move onto the next module name in the command line
375 cmp di, [dos_cmdline_end]
378 je .found_module_name
389 ;; Initialize the multiboot information
395 mov [_multiboot_info_base], eax
396 add dword [_multiboot_info_base], _multiboot_info
398 mov dword [_multiboot_flags], 0xc
400 mov [_multiboot_cmdline], eax
401 add dword [_multiboot_cmdline], _multiboot_kernel_cmdline
404 ;; Hide the kernel's entry in the list of modules
406 mov [_multiboot_mods_addr], eax
407 mov ebx, _multiboot_modules
408 add ebx, multiboot_module_size
409 add dword [_multiboot_mods_addr], ebx
410 dec dword [_multiboot_mods_count]
413 ;; get extended memory size in KB
417 mov [_multiboot_mem_upper],ebx
418 mov [_multiboot_mem_lower],ebx
429 mov [_multiboot_mem_upper],ebx
431 add dword [_multiboot_mem_upper],eax
440 mov [_multiboot_mem_upper], edx
442 add dword [_multiboot_mem_upper], ecx
446 ;; int 15h opt e801 don't work , try int 15h, option 88h
451 mov [_multiboot_mem_upper],ax
454 ;; int 15h opt 88h don't work , try read cmos
459 and eax, 0xffff ; clear carry
461 mov [_multiboot_mem_upper],eax
466 and eax, 0xffff ; clear carry
467 add [_multiboot_mem_lower],eax
472 ;; Retrieve BIOS memory map if available
475 mov edi, _multiboot_address_ranges
480 mov ecx, multiboot_address_range_size
488 add edi, multiboot_address_range_size
494 ;; Prepare multiboot memory map structures
497 ;; Fill in the address descriptor size field
498 mov dword [_multiboot_address_range_descriptor_size], multiboot_address_range_size
500 ;; Set flag and base address and length of memory map
501 or dword [_multiboot_flags], 40h
503 sub eax, _multiboot_address_ranges
504 mov dword [_multiboot_mmap_length], eax
509 mov [_multiboot_mmap_addr], eax
510 add dword [_multiboot_mmap_addr], _multiboot_address_ranges
517 ;; Begin the pmode initalization
521 ;; Save cursor position
523 mov ax, 3 ;! Reset video mode
530 mov ax, 1112h ;! Use 8x8 font
533 mov ax, 1200h ;! Use alternate print screen
536 mov ah, 1h ;! Define cursor (scan lines 6 to 7)
544 mov ah, 6 ; Scroll active page up
545 mov al, 32h ; Clear 50 lines
546 mov cx, 0 ; Upper left of scroll
547 mov dx, 314fh ; Lower right of scroll
548 mov bh, 1*10h+1 ; Use normal attribute on blanked lines
569 ; mov [_cursorx], eax
571 ; mov [_cursory], eax
576 ;; Load the absolute address of the multiboot information structure
578 mov ebx, [_multiboot_info_base]
581 ;; Enter pmode and clear prefetch queue
589 ;; NOTE: This must be position independant (no references to
590 ;; non absolute variables)
594 ;; Initalize segment registers
610 ;; Load the multiboot magic value into eax
615 ;; Jump to start of the kernel
617 jmp dword KERNEL_CS:(LOAD_BASE+0x1000)
629 ; Print string in DS:DI
690 ; print_ax - print the number in the ax register
800 times pe_doshdr_size db 0
818 mov edi, [next_load_base]
819 add edi, [_current_file_size]
828 ;; Clear unused space in the last page
852 ;; Read in the DOS EXE header
855 mov bx, [_current_filehandle]
856 mov cx, pe_doshdr_size
860 mov di, error_file_read_failed
865 ;; Check the DOS EXE magic
867 mov ax, word [_cpe_doshdr + e_magic]
877 mov ebx, dword [_multiboot_mods_count]
885 mov bx, [_current_filehandle]
888 mov di, error_file_seek_failed
892 mov bx, [_current_filehandle]
897 mov di, error_file_read_failed
903 mov dword [_mb_bss_end_addr], 0
917 mov di, error_file_open_failed
922 ;; Save the file handle
924 mov [_current_filehandle], ax
934 ;; Seek to the start of the file
937 mov bx, [_current_filehandle]
942 mov di, error_file_seek_failed
949 ;; Seek to the end of the file to get the file size
955 mov bx, [_current_filehandle]
958 mov di, error_file_seek_failed
963 mov [_current_size], edx
964 mov [_current_file_size], edx
970 mov bx, [_current_filehandle]
973 mov di, error_file_seek_failed
977 mov edi, [next_load_base]
980 cmp dword [_current_size], 32768
984 ;; Read in the file data
988 mov bx, [_current_filehandle]
994 jnc .read_data_succeeded
996 mov di, error_file_read_failed
998 .read_data_succeeded:
1006 ;; Copy the file data just read in to high memory
1022 sub dword [_current_size], 32768
1027 ;; Read in the tailing part of the file data
1030 mov eax, [_current_size]
1033 mov bx, [_current_filehandle]
1038 jnc .read_last_data_succeeded
1040 mov di, error_file_read_failed
1042 .read_last_data_succeeded:
1046 mov bx, [_current_filehandle]
1056 ;; Copy the tailing part to high memory
1059 mov ecx, [_current_size]
1072 mov edx, [_mb_bss_end_addr]
1085 mov bx, [_multiboot_mods_count]
1086 imul bx, bx, multiboot_module_size
1087 add bx, _multiboot_modules
1089 mov edx, [next_load_base]
1090 mov [bx + mbm_mod_start], edx
1091 mov [bx + mbm_mod_end], edi
1092 mov [next_load_base], edi
1093 mov dword [bx + mbm_reserved], 0
1095 inc dword [_multiboot_mods_count]
1102 ;; On error print a message and return zero
1110 ;; Copy to high memory
1112 ;; ESI = Source address
1113 ;; EDI = Destination address
1116 ;; EDI = End of the destination region
1128 cli ; No interrupts during pmode
1130 mov eax, cr0 ; Entered protected mode
1134 jmp .l1 ; Flush prefetch queue
1137 mov eax, KERNEL_DS ; Load DS with a suitable selector
1145 ; mov al, [esi] ; Copy the data
1153 mov eax, cr0 ; Leave protected mode
1169 loading_msg db 'Loading: ',0
1172 ;; Next free address in high memory
1177 ; Needed for enabling the a20 address line
1200 ;; Our initial stack
1202 real_stack times 1024 db 0
1206 ;; DOS commandline buffer
1208 dos_cmdline times 256 db 0
1209 dos_cmdline_end dw 0
1212 ;; Boot information structure
1214 _multiboot_info_base:
1220 _multiboot_mem_lower:
1222 _multiboot_mem_upper:
1224 _multiboot_boot_device:
1228 _multiboot_mods_count:
1230 _multiboot_mods_addr:
1234 _multiboot_mmap_length:
1236 _multiboot_mmap_addr:
1238 _multiboot_drives_count:
1240 _multiboot_drives_addr:
1242 _multiboot_config_table:
1244 _multiboot_boot_loader_name:
1246 _multiboot_apm_table:
1250 times (64*multiboot_module_size) db 0
1251 _multiboot_module_strings:
1254 _multiboot_address_range_descriptor_size dd 0
1256 _multiboot_address_ranges:
1257 times (64*multiboot_address_range_size) db 0
1259 _multiboot_kernel_cmdline:
1260 db 'multi(0)disk(0)rdisk(0)partition(1)\reactos'
1261 times 255-($-_multiboot_kernel_cmdline) db 0
1264 ;; Global descriptor table
1267 dw 0x0 ; Zero descriptor
1272 dw 0xffff ; Kernel code descriptor
1277 dw 0xffff ; Kernel data descriptor
1282 dw 0xffff ; Loader code descriptor
1283 _loader_code_base_0_15:
1285 _loader_code_base_16_23:
1290 dw 0xffff ; Loader data descriptor
1291 _loader_data_base_0_15:
1293 _loader_data_base_16_23:
1298 error_pmode_already:
1300 db 'Error: The processor is already in protected mode'
1302 error_file_open_failed:
1304 db 'Error: Failed to open file (code 0x%a)'
1306 error_file_seek_failed:
1308 db 'Error: File seek failed (code 0x%a)'
1310 error_file_read_failed:
1312 db 'Error: File read failed (code 0x%a)'
1316 db 'Error: Bad DOS EXE magic'