e6933c9ffb538ac6a249ced3ae0433aa8711c3d5
[reactos.git] / reactos / loaders / dos / loadros.asm
1 ;
2 ; Pmode setup stub
3 ; (A20 enable code and PIC reprogram from linux bootsector)
4 ;
5
6 ;
7 ; Base address of the kernel
8 ;
9 LOAD_BASE equ 0200000h
10
11 ;
12 ; Segment selectors
13 ;
14 %define KERNEL_CS (0x8)
15 %define KERNEL_DS (0x10)
16 %define LOADER_CS (0x18)
17 %define LOADER_DS (0x20)
18
19 struc multiboot_module
20 mbm_mod_start: resd 1
21 mbm_mod_end: resd 1
22 mbm_string: resd 1
23 mbm_reserved: resd 1
24 endstruc
25
26 struc multiboot_address_range
27 mar_baselow: resd 1
28 mar_basehigh: resd 1
29 mar_lengthlow: resd 1
30 mar_lengthhigh: resd 1
31 mar_type: resd 1
32 mar_reserved: resd 3
33 endstruc
34
35 ;
36 ; We are a .com program
37 ;
38 org 100h
39
40 ;
41 ; 16 bit code
42 ;
43 BITS 16
44
45 %define NDEBUG 1
46
47 %macro DPRINT 1+
48 %ifndef NDEBUG
49 jmp %%end_str
50
51 %%str: db %1
52
53 %%end_str:
54 push di
55 push ds
56 push es
57 pop ds
58 mov di, %%str
59 call print_string
60 pop ds
61 pop di
62 %endif
63 %endmacro
64
65 entry:
66 ;;
67 ;; Load stack
68 ;;
69 cli
70 push ds
71 pop ss
72 push ds
73 pop es
74 mov sp, real_stack_end
75 sti
76
77 ;;
78 ;; Setup the 32-bit registers
79 ;;
80 mov ebx, 0
81 mov eax, 0
82 mov ecx, 0
83 mov edx, 0
84 mov esi, 0
85 mov edi, 0
86
87 ;;
88 ;; Set the position for the first module to be loaded
89 ;;
90 mov dword [next_load_base], LOAD_BASE
91
92 ;;
93 ;; Setup various variables
94 ;;
95 mov bx, ds
96 movzx eax, bx
97 shl eax, 4
98 add [gdt_base], eax
99
100 ;;
101 ;; Setup the loader code and data segments
102 ;;
103 mov eax, 0
104 mov ax, cs
105 shl eax, 4
106 mov [_loader_code_base_0_15], ax
107 shr eax, 16
108 mov byte [_loader_code_base_16_23], al
109
110 mov eax, 0
111 mov ax, ds
112 shl eax, 4
113 mov [_loader_data_base_0_15], ax
114 shr eax, 16
115 mov byte [_loader_data_base_16_23], al
116
117 ;;
118 ;; load gdt
119 ;;
120 lgdt [gdt_descr]
121
122 ;;
123 ;; Enable the A20 address line (to allow access to over 1mb)
124 ;;
125 call empty_8042
126 mov al, 0D1h ; command write
127 out 064h, al
128 call empty_8042
129 mov al, 0DFh ; A20 on
130 out 060h, al
131 call empty_8042
132
133 ;;
134 ;; Make the argument list into a c string
135 ;;
136 mov di, 081h
137 mov si, dos_cmdline
138 .next_char
139 mov al, [di]
140 mov [si], al
141 cmp byte [di], 0dh
142 je .end_of_command_line
143 inc di
144 inc si
145 jmp .next_char
146
147 .end_of_command_line:
148 mov byte [di], 0
149 mov byte [si], 0
150 mov [dos_cmdline_end], di
151
152 ;;
153 ;; Make the argument list into a c string
154 ;;
155 mov di, 081h
156 .next_char2
157 cmp byte [di], 0
158 je .end_of_command_line2
159 cmp byte [di], ' '
160 jne .not_space
161 mov byte [di], 0
162 .not_space
163 inc di
164 jmp .next_char2
165 .end_of_command_line2
166
167 ;;
168 ;; Check if we want to skip the first character
169 ;;
170 cmp byte [081h], 0
171 jne .first_char_is_zero
172 mov dx, 082h
173 jmp .start_loading
174 .first_char_is_zero
175 mov dx, 081h
176
177 ;;
178 ;; Check if we have reached the end of the string
179 ;;
180 .start_loading
181 mov bx, dx
182 cmp byte [bx], 0
183 jne .more_modules
184 jmp .done_loading
185
186 .more_modules
187 ;;
188 ;; Process the arguments
189 ;;
190 cmp byte [di], '/'
191 jne .no_next_module
192 jmp .next_module
193 .no_next_module:
194
195 ;;
196 ;; Display a message saying we are loading the module
197 ;;
198 mov di, loading_msg
199 call print_string
200 mov di, dx
201 call print_string
202
203 ;;
204 ;; Save the filename
205 ;;
206 mov si, di
207 mov edx, 0
208
209 mov dx, [_multiboot_mods_count]
210 shl dx, 8
211 add dx, _multiboot_module_strings
212 mov bx, [_multiboot_mods_count]
213 imul bx, bx, multiboot_module_size
214 add bx, _multiboot_modules
215 mov eax, 0
216 mov ax, ds
217 shl eax, 4
218 add eax, edx
219 mov [bx + mbm_string], eax
220
221 mov bx, dx
222 .copy_next_char
223 mov al, [si]
224 mov [bx], al
225 inc si
226 inc bx
227 cmp al, 0
228 jne .copy_next_char
229
230 ;;
231 ;; Load the file
232 ;;
233 push di
234 mov dx, di
235
236 ; Check if it is a symbol file
237 cmp byte [bx-5],'.'
238 jne .checkForHive
239 cmp byte [bx-4],'s'
240 jne .checkForHive
241 cmp byte [bx-3],'y'
242 jne .checkForHive
243 cmp byte [bx-2],'m'
244 jne .checkForHive
245
246 call sym_load_module
247 jmp .after_copy
248
249 .checkForHive:
250 ; Check if it is a symbol file
251 cmp byte [bx-5],'.'
252 jne .lst_copy
253 cmp byte [bx-4],'h'
254 jne .lst_copy
255 cmp byte [bx-3],'i'
256 jne .lst_copy
257 cmp byte [bx-2],'v'
258 jne .lst_copy
259
260 call sym_load_module
261 jmp .after_copy
262
263 .lst_copy:
264 ;; Check for a module list file
265 cmp byte [bx-5],'.'
266 jne .pe_copy
267 cmp byte [bx-4],'l'
268 jne .pe_copy
269 cmp byte [bx-3],'s'
270 jne .pe_copy
271 cmp byte [bx-2],'t'
272 jne .pe_copy
273
274 call sym_load_module
275
276 push es
277 mov bx,0x9000
278 push bx
279 pop es
280 xor edi,edi
281
282 .lst_copy_bytes:
283 mov bx,_lst_name_local
284
285 .lst_byte:
286 mov al,[es:di]
287 inc di
288 cmp al,' '
289 jg .lst_not_space
290 mov byte [bx],0
291 inc bx
292 .lst_space:
293 mov al,[es:di]
294 inc di
295 cmp al,' '
296 jle .lst_space
297 .lst_not_space:
298 cmp al,'*'
299 je .lst_end
300 mov [bx],al
301 inc bx
302 jmp .lst_byte
303
304 .lst_end:
305 ;; We are here because the terminator was encountered
306 mov byte [bx],0 ; Zero terminate
307 inc bx
308 mov byte [bx],0
309 mov [dos_cmdline_end],bx ; Put in cmd_line_length
310 mov dx,_lst_name_local; Put this address in di
311 mov di,dx ; This, too, at the start of the
312 ; string
313
314 pop es
315
316 jmp .start_loading
317
318 .pe_copy:
319 call pe_load_module
320
321 .after_copy:
322 pop di
323 cmp eax, 0
324 jne .load_success
325 jmp .exit
326 .load_success:
327 mov ah, 02h
328 mov dl, 0dh
329 int 021h
330 mov ah, 02h
331 mov dl, 0ah
332 int 021h
333
334 ;;
335 ;; Move onto the next module name in the command line
336 ;;
337 .next_module
338 cmp di, [dos_cmdline_end]
339 je .done_loading
340 cmp byte [di], 0
341 je .found_module_name
342 inc di
343 jmp .next_module
344 .found_module_name
345 inc di
346 mov dx, di
347 jmp .start_loading
348
349 .done_loading
350
351 ;;
352 ;; Initialize the multiboot information
353 ;;
354 mov eax, 0
355 mov ax, ds
356 shl eax, 4
357
358 mov [_multiboot_info_base], eax
359 add dword [_multiboot_info_base], _multiboot_info
360
361 mov dword [_multiboot_flags], 0xc
362
363 mov [_multiboot_cmdline], eax
364 add dword [_multiboot_cmdline], _multiboot_kernel_cmdline
365
366 ;;
367 ;; Hide the kernel's entry in the list of modules
368 ;;
369 mov [_multiboot_mods_addr], eax
370 mov ebx, _multiboot_modules
371 add ebx, multiboot_module_size
372 add dword [_multiboot_mods_addr], ebx
373 dec dword [_multiboot_mods_count]
374
375 ;;
376 ;; get extended memory size in KB
377 ;;
378 push ebx
379 xor ebx,ebx
380 mov [_multiboot_mem_upper],ebx
381 mov [_multiboot_mem_lower],ebx
382
383 mov ax, 0xe801
384 int 015h
385 jc .oldstylemem
386
387 cmp ax, 0
388 je .cmem
389
390 and ebx, 0xffff
391 shl ebx,6
392 mov [_multiboot_mem_upper],ebx
393 and eax,0xffff
394 add dword [_multiboot_mem_upper],eax
395 jmp .done_mem
396
397 .cmem:
398 cmp cx, 0
399 je .oldstylemem
400
401 and edx, 0xFFFF
402 shl edx, 6
403 mov [_multiboot_mem_upper], edx
404 and ecx, 0xFFFF
405 add dword [_multiboot_mem_upper], ecx
406 jmp .done_mem
407
408 .oldstylemem:
409 ;; int 15h opt e801 don't work , try int 15h, option 88h
410 mov ah, 088h
411 int 015h
412 cmp ax, 0
413 je .cmosmem
414 mov [_multiboot_mem_upper],ax
415 jmp .done_mem
416 .cmosmem:
417 ;; int 15h opt 88h don't work , try read cmos
418 xor eax,eax
419 mov al, 0x31
420 out 0x70, al
421 in al, 0x71
422 and eax, 0xffff ; clear carry
423 shl eax,8
424 mov [_multiboot_mem_upper],eax
425 xor eax,eax
426 mov al, 0x30
427 out 0x70, al
428 in al, 0x71
429 and eax, 0xffff ; clear carry
430 add [_multiboot_mem_lower],eax
431
432 .done_mem:
433
434 ;;
435 ;; Retrieve BIOS memory map if available
436 ;;
437 xor ebx,ebx
438 mov edi, _multiboot_address_ranges
439
440 .mmap_next:
441
442 mov edx, 'PAMS'
443 mov ecx, multiboot_address_range_size
444 mov eax, 0E820h
445 int 15h
446 jc .done_mmap
447
448 cmp eax, 'PAMS'
449 jne .done_mmap
450
451 add edi, multiboot_address_range_size
452
453 cmp ebx, 0
454 jne .mmap_next
455
456 ;;
457 ;; Prepare multiboot memory map structures
458 ;;
459
460 ;; Fill in the address descriptor size field
461 mov dword [_multiboot_address_range_descriptor_size], multiboot_address_range_size
462
463 ;; Set flag and base address and length of memory map
464 or dword [_multiboot_flags], 40h
465 mov eax, edi
466 sub eax, _multiboot_address_ranges
467 mov dword [_multiboot_mmap_length], eax
468
469 xor eax, eax
470 mov ax, ds
471 shl eax, 4
472 mov [_multiboot_mmap_addr], eax
473 add dword [_multiboot_mmap_addr], _multiboot_address_ranges
474
475 .done_mmap:
476
477 pop ebx
478
479 ;;
480 ;; Begin the pmode initalization
481 ;;
482
483 ;;
484 ;; Save cursor position
485 ;;
486 mov ax, 3 ;! Reset video mode
487 int 10h
488
489 mov bl, 10
490 mov ah, 12
491 int 10h
492
493 mov ax, 1112h ;! Use 8x8 font
494 xor bl, bl
495 int 10h
496 mov ax, 1200h ;! Use alternate print screen
497 mov bl, 20h
498 int 10h
499 mov ah, 1h ;! Define cursor (scan lines 6 to 7)
500 mov cx, 0607h
501 int 10h
502
503 mov ah, 1
504 mov cx, 0600h
505 int 10h
506
507 mov ah, 6 ; Scroll active page up
508 mov al, 32h ; Clear 50 lines
509 mov cx, 0 ; Upper left of scroll
510 mov dx, 314fh ; Lower right of scroll
511 mov bh, 1*10h+1 ; Use normal attribute on blanked lines
512 int 10h
513
514 mov dx, 0
515 mov dh, 0
516
517 mov ah, 2
518 mov bh, 0
519 int 10h
520
521 mov dx, 0
522 mov dh, 0
523
524 mov ah, 2
525 mov bh, 0
526 int 10h
527
528 mov ah, 3
529 mov bh, 0
530 int 10h
531 movzx eax, dl
532 ; mov [_cursorx], eax
533 movzx eax, dh
534 ; mov [_cursory], eax
535
536 cli
537
538 ;;
539 ;; Load the absolute address of the multiboot information structure
540 ;;
541 mov ebx, [_multiboot_info_base]
542
543 ;;
544 ;; Enter pmode and clear prefetch queue
545 ;;
546 mov eax,cr0
547 or eax,0x10001
548 mov cr0,eax
549 jmp .next
550 .next:
551 ;;
552 ;; NOTE: This must be position independant (no references to
553 ;; non absolute variables)
554 ;;
555
556 ;;
557 ;; Initalize segment registers
558 ;;
559 mov ax,KERNEL_DS
560 mov ds,ax
561 mov ss,ax
562 mov es,ax
563 mov fs,ax
564 mov gs,ax
565
566 ;;
567 ;; Initalize eflags
568 ;;
569 push dword 0
570 popf
571
572 ;;
573 ;; Load the multiboot magic value into eax
574 ;;
575 mov eax, 0x2badb002
576
577 ;;
578 ;; Jump to start of the kernel
579 ;;
580 jmp dword KERNEL_CS:(LOAD_BASE+0x1000)
581
582 ;;
583 ;; Never get here
584 ;;
585
586 .exit:
587 mov ax,04c00h
588 int 21h
589
590
591 ;
592 ; Print string in DS:DI
593 ;
594 print_string:
595 push ebp
596 mov bp, sp
597 push eax
598 push edx
599 push edi
600
601 mov ax, 0x0200
602 .loop:
603 mov dl, [di]
604 cmp dl, 0
605 je .end_loop
606 cmp dl, '%'
607 jne .print_char
608 inc di
609 mov dl, [di]
610 cmp dl, 'a'
611 jne .not_ax
612 push eax
613 mov eax, [ss:bp - 4]
614 call print_ax
615 pop eax
616 jmp .next_char
617
618 .not_ax:
619 cmp dl, 'A'
620 jne .not_eax
621 push eax
622 mov eax, [ss:bp - 4]
623 call print_eax
624 pop eax
625 jmp .next_char
626
627 .not_eax:
628 cmp dl, 'c'
629 jne .not_cx
630 push ax
631 mov ax, cx
632 call print_ax
633 pop ax
634 jmp .next_char
635
636 .not_cx:
637
638 .print_char:
639 int 0x21
640
641 .next_char:
642 inc di
643 jmp .loop
644
645 .end_loop:
646 pop edi
647 pop edx
648 pop eax
649 pop ebp
650 ret
651
652 ;
653 ; print_ax - print the number in the ax register
654 ;
655
656 print_ax:
657 push ax
658 push bx
659 push cx
660 push dx
661
662 mov bx, ax
663 mov ax, 0x0200
664 mov cx, 4
665 .loop:
666 mov dx, bx
667 shr dx, 12
668 and dl, 0x0f
669 cmp dl, 0x0a
670 jge .hex_val
671 add dl, '0'
672 jmp .not_hex
673
674 .hex_val:
675 add dl, 'a' - 10
676
677 .not_hex:
678 int 0x21
679 shl bx, 4
680 dec cx
681 jnz .loop
682
683 pop dx
684 pop cx
685 pop bx
686 pop ax
687 ret
688
689 print_eax:
690 push eax
691 push ebx
692 push ecx
693 push edx
694
695 mov ebx, eax
696 mov ax, 0x0200
697 mov cx, 8
698 .loop:
699 mov edx, ebx
700 shr edx, 28
701 and dl, 0x0f
702 cmp dl, 0x0a
703 jge .hex_val
704 add dl, '0'
705 jmp .not_hex
706
707 .hex_val:
708 add dl, 'a' - 10
709
710 .not_hex:
711 int 0x21
712 shl ebx, 4
713 dec cx
714 jnz .loop
715
716 pop edx
717 pop ecx
718 pop ebx
719 pop eax
720 ret
721
722 STRUC pe_doshdr
723 e_magic: resw 1
724 e_cblp: resw 1
725 e_cp: resw 1
726 e_crlc: resw 1
727 e_cparhdr: resw 1
728 e_minalloc: resw 1
729 e_maxalloc: resw 1
730 e_ss: resw 1
731 e_sp: resw 1
732 e_csum: resw 1
733 e_ip: resw 1
734 e_cs: resw 1
735 e_lfarlc: resw 1
736 e_ovno: resw 1
737 e_res: resw 4
738 e_oemid: resw 1
739 e_oeminfo: resw 1
740 e_res2: resw 10
741 e_lfanew: resd 1
742 ENDSTRUC
743
744
745 _mb_magic:
746 dd 0
747 _mb_flags:
748 dd 0
749 _mb_checksum:
750 dd 0
751 _mb_header_addr:
752 dd 0
753 _mb_load_addr:
754 dd 0
755 _mb_load_end_addr:
756 dd 0
757 _mb_bss_end_addr:
758 dd 0
759 _mb_entry_addr:
760 dd 0
761
762 _cpe_doshdr:
763 times pe_doshdr_size db 0
764 _current_filehandle:
765 dw 0
766 _current_size:
767 dd 0
768 _current_file_size:
769 dd 0
770
771 _lst_name_local:
772 times 2048 db 0
773
774 ;;
775 ;; Load a SYM file
776 ;; DS:DX = Filename
777 ;;
778 sym_load_module:
779 call load_module1
780 call load_module2
781 mov edi, [next_load_base]
782 add edi, [_current_file_size]
783
784 mov eax, edi
785 test di, 0xfff
786 jz .sym_no_round
787 and di, 0xf000
788 add edi, 0x1000
789
790 ;;
791 ;; Clear unused space in the last page
792 ;;
793 mov esi, edi
794 mov ecx, edi
795 sub ecx, eax
796
797 .sym_clear:
798 mov byte [esi],0
799 inc esi
800 loop .sym_clear
801
802 .sym_no_round:
803
804 call load_module3
805 ret
806
807 ;;
808 ;; Load a PE file
809 ;; DS:DX = Filename
810 ;;
811 pe_load_module:
812 call load_module1
813
814 ;;
815 ;; Read in the DOS EXE header
816 ;;
817 mov ah, 0x3f
818 mov bx, [_current_filehandle]
819 mov cx, pe_doshdr_size
820 mov dx, _cpe_doshdr
821 int 0x21
822 jnc .header_read
823 mov dx, error_file_read_failed
824 jmp error
825 .header_read
826
827 ;;
828 ;; Check the DOS EXE magic
829 ;;
830 mov ax, word [_cpe_doshdr + e_magic]
831 cmp ax, 'MZ'
832 je .mz_hdr_good
833 mov dx, error_bad_mz
834 jmp error
835 .mz_hdr_good
836
837 ;;
838 ;; Find the BSS size
839 ;;
840 mov ebx, dword [_multiboot_mods_count]
841 cmp ebx, 0
842 jne .not_first
843
844 mov edx, 0
845 mov ax, 0x4200
846 mov cx, 0
847 mov dx, 0x1004
848 mov bx, [_current_filehandle]
849 int 0x21
850 jnc .start_seek1
851 mov dx, error_file_seek_failed
852 jmp error
853 .start_seek1:
854 mov ah, 0x3F
855 mov bx, [_current_filehandle]
856 mov cx, 32
857 mov dx, _mb_magic
858 int 0x21
859 jnc .mb_header_read
860 mov dx, error_file_read_failed
861 jmp error
862 .mb_header_read:
863 jmp .first
864
865 .not_first:
866 mov dword [_mb_bss_end_addr], 0
867 .first:
868
869 call load_module2
870 call load_module3
871 ret
872
873 load_module1:
874 ;;
875 ;; Open file
876 ;;
877 mov ax, 0x3d00
878 int 0x21
879 jnc .file_opened
880 mov dx, error_file_open_failed
881 jmp error
882 .file_opened:
883
884 ;;
885 ;; Save the file handle
886 ;;
887 mov [_current_filehandle], ax
888
889 ;;
890 ;; Print space
891 ;;
892 mov ah,02h
893 mov dl,' '
894 int 021h
895
896 ;;
897 ;; Seek to the start of the file
898 ;;
899 mov ax, 0x4200
900 mov bx, [_current_filehandle]
901 mov cx, 0
902 mov dx, 0
903 int 0x21
904 jnc .seek_start
905 mov dx, error_file_seek_failed
906 jmp error
907 .seek_start:
908 ret
909
910 load_module2:
911 ;;
912 ;; Seek to the end of the file to get the file size
913 ;;
914 mov edx, 0
915 mov ax, 0x4202
916 mov dx, 0
917 mov cx, 0
918 mov bx, [_current_filehandle]
919 int 0x21
920 jnc .start_end
921 mov dx, error_file_seek_failed
922 jmp error
923 .start_end
924 shl edx, 16
925 mov dx, ax
926 mov [_current_size], edx
927 mov [_current_file_size], edx
928
929 mov edx, 0
930 mov ax, 0x4200
931 mov dx, 0
932 mov cx, 0
933 mov bx, [_current_filehandle]
934 int 0x21
935 jnc .start_seek
936 mov dx, error_file_seek_failed
937 jmp error
938 .start_seek
939
940 mov edi, [next_load_base]
941
942 .read_next:
943 cmp dword [_current_size], 32768
944 jle .read_tail
945
946 ;;
947 ;; Read in the file data
948 ;;
949 push ds
950 mov ah, 0x3f
951 mov bx, [_current_filehandle]
952 mov cx, 32768
953 mov dx, 0x9000
954 mov ds, dx
955 mov dx, 0
956 int 0x21
957 jnc .read_data_succeeded
958 pop ds
959 mov dx, error_file_read_failed
960 jmp error
961 .read_data_succeeded:
962 %ifndef NDEBUG
963 mov ah,02h
964 mov dl,'#'
965 int 021h
966 %endif
967
968 ;;
969 ;; Copy the file data just read in to high memory
970 ;;
971 pop ds
972 mov esi, 0x90000
973 mov ecx, 32768
974 call _himem_copy
975 %ifndef NDEBUG
976 mov ah,02h
977 mov dl,'$'
978 int 021h
979 %else
980 mov ah,02h
981 mov dl,'.'
982 int 021h
983 %endif
984
985 sub dword [_current_size], 32768
986 jmp .read_next
987
988 .read_tail
989 ;;
990 ;; Read in the tailing part of the file data
991 ;;
992 push ds
993 mov eax, [_current_size]
994 mov cx, ax
995 mov ah, 0x3f
996 mov bx, [_current_filehandle]
997 mov dx, 0x9000
998 mov ds, dx
999 mov dx, 0
1000 int 0x21
1001 jnc .read_last_data_succeeded
1002 pop ds
1003 mov dx, error_file_read_failed
1004 jmp error
1005 .read_last_data_succeeded:
1006 %ifndef NDEBUG
1007 mov ah,02h
1008 mov dl,'#'
1009 int 021h
1010 %endif
1011
1012 ;;
1013 ;; Copy the tailing part to high memory
1014 ;;
1015 pop ds
1016 mov ecx, [_current_size]
1017 mov esi, 0x90000
1018 call _himem_copy
1019 %ifndef NDEBUG
1020 mov ah,02h
1021 mov dl,'$'
1022 int 021h
1023 %else
1024 mov ah,02h
1025 mov dl,'.'
1026 int 021h
1027 %endif
1028
1029 mov edx, [_mb_bss_end_addr]
1030 cmp edx, 0
1031 je .no_bss
1032 mov edi, edx
1033 .no_bss:
1034 test di, 0xfff
1035 jz .no_round
1036 and di, 0xf000
1037 add edi, 0x1000
1038 .no_round:
1039 ret
1040
1041 load_module3:
1042 mov bx, [_multiboot_mods_count]
1043 imul bx, bx, multiboot_module_size
1044 add bx, _multiboot_modules
1045
1046 mov edx, [next_load_base]
1047 mov [bx + mbm_mod_start], edx
1048 mov [bx + mbm_mod_end], edi
1049 mov [next_load_base], edi
1050 mov dword [bx + mbm_reserved], 0
1051
1052 inc dword [_multiboot_mods_count]
1053
1054 mov eax, 1
1055
1056 ret
1057
1058 ;;
1059 ;; On error print a message and return zero
1060 ;;
1061 error:
1062 mov ah, 0x9
1063 int 0x21
1064 mov eax, 0
1065 ret
1066
1067 ;;
1068 ;; Copy to high memory
1069 ;; ARGUMENTS
1070 ;; ESI = Source address
1071 ;; EDI = Destination address
1072 ;; ECX = Byte count
1073 ;; RETURNS
1074 ;; EDI = End of the destination region
1075 ;; ECX = 0
1076 ;;
1077 _himem_copy:
1078 push ds ; Save DS
1079 push es ; Save ES
1080 push eax
1081 push esi
1082
1083 cmp eax, 0
1084 je .l3
1085
1086 cli ; No interrupts during pmode
1087
1088 mov eax, cr0 ; Entered protected mode
1089 or eax, 0x1
1090 mov cr0, eax
1091
1092 jmp .l1 ; Flush prefetch queue
1093 .l1:
1094
1095 mov eax, KERNEL_DS ; Load DS with a suitable selector
1096 mov ds, ax
1097 mov eax, KERNEL_DS
1098 mov es, ax
1099
1100 cld
1101 a32 rep movsb
1102 ;.l2:
1103 ; mov al, [esi] ; Copy the data
1104 ; mov [edi], al
1105 ; dec ecx
1106 ; inc esi
1107 ; inc edi
1108 ; cmp ecx, 0
1109 ; jne .l2
1110
1111 mov eax, cr0 ; Leave protected mode
1112 and eax, 0xfffffffe
1113 mov cr0, eax
1114
1115 jmp .l3
1116 .l3:
1117 sti
1118 pop esi
1119 pop eax
1120 pop es
1121 pop ds
1122 ret
1123
1124 ;
1125 ; Loading message
1126 ;
1127 loading_msg db 'Loading: ',0
1128
1129 ;;
1130 ;; Next free address in high memory
1131 ;;
1132 next_load_base dd 0
1133
1134 ;
1135 ; Needed for enabling the a20 address line
1136 ;
1137 empty_8042:
1138 jmp $+3
1139 jmp $+3
1140 in al,064h
1141 test al,02h
1142 jnz empty_8042
1143 ret
1144
1145 ;
1146 ; GDT descriptor
1147 ;
1148 align 8
1149 gdt_descr:
1150 gdt_limit:
1151 dw (5*8)-1
1152 gdt_base:
1153 dd _gdt
1154
1155 ;;
1156 ;; Our initial stack
1157 ;;
1158 real_stack times 1024 db 0
1159 real_stack_end:
1160
1161 ;;
1162 ;; DOS commandline buffer
1163 ;;
1164 dos_cmdline times 256 db 0
1165 dos_cmdline_end dw 0
1166
1167 ;;
1168 ;; Boot information structure
1169 ;;
1170 _multiboot_info_base:
1171 dd 0x0
1172
1173 _multiboot_info:
1174 _multiboot_flags:
1175 dd 0x0
1176 _multiboot_mem_lower:
1177 dd 0x0
1178 _multiboot_mem_upper:
1179 dd 0x0
1180 _multiboot_boot_device:
1181 dd 0x0
1182 _multiboot_cmdline:
1183 dd 0x0
1184 _multiboot_mods_count:
1185 dd 0x0
1186 _multiboot_mods_addr:
1187 dd 0x0
1188 _multiboot_syms:
1189 times 12 db 0
1190 _multiboot_mmap_length:
1191 dd 0x0
1192 _multiboot_mmap_addr:
1193 dd 0x0
1194 _multiboot_drives_count:
1195 dd 0x0
1196 _multiboot_drives_addr:
1197 dd 0x0
1198 _multiboot_config_table:
1199 dd 0x0
1200 _multiboot_boot_loader_name:
1201 dd 0x0
1202 _multiboot_apm_table:
1203 dd 0x0
1204
1205 _multiboot_modules:
1206 times (64*multiboot_module_size) db 0
1207 _multiboot_module_strings:
1208 times (64*256) db 0
1209
1210 _multiboot_address_range_descriptor_size dd 0
1211
1212 _multiboot_address_ranges:
1213 times (64*multiboot_address_range_size) db 0
1214
1215 _multiboot_kernel_cmdline:
1216 db 'multi(0)disk(0)rdisk(0)partition(1)\reactos /DEBUGPORT=SCREEN'
1217 times 255-($-_multiboot_kernel_cmdline) db 0
1218
1219 ;;
1220 ;; Global descriptor table
1221 ;;
1222 _gdt:
1223 dw 0x0 ; Zero descriptor
1224 dw 0x0
1225 dw 0x0
1226 dw 0x0
1227
1228 dw 0xffff ; Kernel code descriptor
1229 dw 0x0000
1230 dw 0x9a00
1231 dw 0x00cf
1232
1233 dw 0xffff ; Kernel data descriptor
1234 dw 0x0000
1235 dw 0x9200
1236 dw 0x00cf
1237
1238 dw 0xffff ; Loader code descriptor
1239 _loader_code_base_0_15:
1240 dw 0x0000
1241 _loader_code_base_16_23:
1242 db 0x00
1243 db 0x9a
1244 dw 0x0000
1245
1246 dw 0xffff ; Loader data descriptor
1247 _loader_data_base_0_15:
1248 dw 0x0000
1249 _loader_data_base_16_23:
1250 db 0x00
1251 db 0x92
1252 dw 0x0000
1253
1254 error_pmode_already:
1255 db 'Error: The processor is already in protected mode'
1256 db 0xa, 0xd, '$'
1257 error_file_open_failed:
1258 db 'Error: Failed to open file'
1259 db 0xa, 0xd, '$'
1260 error_file_seek_failed:
1261 db 'Error: File seek failed'
1262 db 0xa, 0xd, '$'
1263 error_file_read_failed:
1264 db 'Error: File read failed'
1265 db 0xa, 0xd, '$'
1266 error_coff_load_failed:
1267 db 'Error: Failed to load COFF file'
1268 db 0xa, 0xd, '$'
1269 error_bad_mz:
1270 db 'Error: Bad DOS EXE magic'
1271 db 0xa, 0xd, '$'