Preparations for checked/free like builds (CPRINT == DbgPrint when DBG is defined).
[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, _multiboot_kernel_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 [end_cmd_line], 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 .pe_copy
239 cmp byte [bx-4],'s'
240 jne .pe_copy
241 cmp byte [bx-3],'y'
242 jne .pe_copy
243 cmp byte [bx-2],'m'
244 jne .pe_copy
245
246 call sym_load_module
247 jmp .after_copy
248 .pe_copy:
249 call pe_load_module
250 .after_copy:
251 pop di
252 cmp eax, 0
253 jne .load_success
254 jmp .exit
255 .load_success:
256 mov ah, 02h
257 mov dl, 0dh
258 int 021h
259 mov ah, 02h
260 mov dl, 0ah
261 int 021h
262
263 ;;
264 ;; Move onto the next module name in the command line
265 ;;
266 .next_module
267 cmp di, [end_cmd_line]
268 je .done_loading
269 cmp byte [di], 0
270 je .found_module_name
271 inc di
272 jmp .next_module
273 .found_module_name
274 inc di
275 mov dx, di
276 jmp .start_loading
277
278 .done_loading:
279
280 ;;
281 ;; Initialize the multiboot information
282 ;;
283 mov eax, 0
284 mov ax, ds
285 shl eax, 4
286
287 mov [_multiboot_info_base], eax
288 add dword [_multiboot_info_base], _multiboot_info
289
290 mov dword [_multiboot_flags], 0xc
291
292 mov [_multiboot_cmdline], eax
293 add dword [_multiboot_cmdline], _multiboot_kernel_cmdline
294
295 ;;
296 ;; Hide the kernel's entry in the list of modules
297 ;;
298 mov [_multiboot_mods_addr], eax
299 mov ebx, _multiboot_modules
300 add ebx, multiboot_module_size
301 add dword [_multiboot_mods_addr], ebx
302 dec dword [_multiboot_mods_count]
303
304 ;;
305 ;; get extended memory size in KB
306 ;;
307 push ebx
308 xor ebx,ebx
309 mov [_multiboot_mem_upper],ebx
310 mov [_multiboot_mem_lower],ebx
311
312 mov ax, 0xe801
313 int 015h
314 jc .oldstylemem
315
316 cmp ax, 0
317 je .cmem
318
319 and ebx, 0xffff
320 shl ebx,6
321 mov [_multiboot_mem_upper],ebx
322 and eax,0xffff
323 add dword [_multiboot_mem_upper],eax
324 jmp .done_mem
325
326 .cmem:
327 cmp cx, 0
328 je .oldstylemem
329
330 and edx, 0xFFFF
331 shl edx, 6
332 mov [_multiboot_mem_upper], edx
333 and ecx, 0xFFFF
334 add dword [_multiboot_mem_upper], ecx
335 jmp .done_mem
336
337 .oldstylemem:
338 ;; int 15h opt e801 don't work , try int 15h, option 88h
339 mov ah, 088h
340 int 015h
341 cmp ax, 0
342 je .cmosmem
343 mov [_multiboot_mem_upper],ax
344 jmp .done_mem
345 .cmosmem:
346 ;; int 15h opt 88h don't work , try read cmos
347 xor eax,eax
348 mov al, 0x31
349 out 0x70, al
350 in al, 0x71
351 and eax, 0xffff ; clear carry
352 shl eax,8
353 mov [_multiboot_mem_upper],eax
354 xor eax,eax
355 mov al, 0x30
356 out 0x70, al
357 in al, 0x71
358 and eax, 0xffff ; clear carry
359 add [_multiboot_mem_lower],eax
360
361 .done_mem:
362
363 ;;
364 ;; Retrieve BIOS memory map if available
365 ;;
366 xor ebx,ebx
367 mov edi, _multiboot_address_ranges
368
369 .mmap_next:
370
371 mov edx, 'PAMS'
372 mov ecx, multiboot_address_range_size
373 mov eax, 0E820h
374 int 15h
375 jc .done_mmap
376
377 cmp eax, 'PAMS'
378 jne .done_mmap
379
380 add edi, multiboot_address_range_size
381
382 cmp ebx, 0
383 jne .mmap_next
384
385 ;;
386 ;; Prepare multiboot memory map structures
387 ;;
388
389 ;; Fill in the address descriptor size field
390 mov dword [_multiboot_address_range_descriptor_size], multiboot_address_range_size
391
392 ;; Set flag and base address and length of memory map
393 or dword [_multiboot_flags], 40h
394 mov eax, edi
395 sub eax, _multiboot_address_ranges
396 mov dword [_multiboot_mmap_length], eax
397
398 xor eax, eax
399 mov ax, ds
400 shl eax, 4
401 mov [_multiboot_mmap_addr], eax
402 add dword [_multiboot_mmap_addr], _multiboot_address_ranges
403
404 .done_mmap:
405
406 pop ebx
407
408 ;;
409 ;; Begin the pmode initalization
410 ;;
411
412 ;;
413 ;; Save cursor position
414 ;;
415 mov ax, 3 ;! Reset video mode
416 int 10h
417
418 mov bl, 10
419 mov ah, 12
420 int 10h
421
422 mov ax, 1112h ;! Use 8x8 font
423 xor bl, bl
424 int 10h
425 mov ax, 1200h ;! Use alternate print screen
426 mov bl, 20h
427 int 10h
428 mov ah, 1h ;! Define cursor (scan lines 6 to 7)
429 mov cx, 0607h
430 int 10h
431
432 mov ah, 1
433 mov cx, 0600h
434 int 10h
435
436 mov ah, 6 ; Scroll active page up
437 mov al, 32h ; Clear 50 lines
438 mov cx, 0 ; Upper left of scroll
439 mov dx, 314fh ; Lower right of scroll
440 mov bh, 1*10h+1 ; Use normal attribute on blanked lines
441 int 10h
442
443 mov dx, 0
444 mov dh, 0
445
446 mov ah, 2
447 mov bh, 0
448 int 10h
449
450 mov dx, 0
451 mov dh, 0
452
453 mov ah, 2
454 mov bh, 0
455 int 10h
456
457 mov ah, 3
458 mov bh, 0
459 int 10h
460 movzx eax, dl
461 ; mov [_cursorx], eax
462 movzx eax, dh
463 ; mov [_cursory], eax
464
465 cli
466
467 ;;
468 ;; Load the absolute address of the multiboot information structure
469 ;;
470 mov ebx, [_multiboot_info_base]
471
472 ;;
473 ;; Enter pmode and clear prefetch queue
474 ;;
475 mov eax,cr0
476 or eax,0x10001
477 mov cr0,eax
478 jmp .next
479 .next:
480 ;;
481 ;; NOTE: This must be position independant (no references to
482 ;; non absolute variables)
483 ;;
484
485 ;;
486 ;; Initalize segment registers
487 ;;
488 mov ax,KERNEL_DS
489 mov ds,ax
490 mov ss,ax
491 mov es,ax
492 mov fs,ax
493 mov gs,ax
494
495 ;;
496 ;; Initalize eflags
497 ;;
498 push dword 0
499 popf
500
501 ;;
502 ;; Load the multiboot magic value into eax
503 ;;
504 mov eax, 0x2badb002
505
506 ;;
507 ;; Jump to start of the kernel
508 ;;
509 jmp dword KERNEL_CS:(LOAD_BASE+0x1000)
510
511 ;;
512 ;; Never get here
513 ;;
514
515 .exit:
516 mov ax,04c00h
517 int 21h
518
519 end_cmd_line dw 0
520
521 ;
522 ; Print string in DS:DI
523 ;
524 print_string:
525 push ebp
526 mov bp, sp
527 push eax
528 push edx
529 push edi
530
531 mov ax, 0x0200
532 .loop:
533 mov dl, [di]
534 cmp dl, 0
535 je .end_loop
536 cmp dl, '%'
537 jne .print_char
538 inc di
539 mov dl, [di]
540 cmp dl, 'a'
541 jne .not_ax
542 push eax
543 mov eax, [ss:bp - 4]
544 call print_ax
545 pop eax
546 jmp .next_char
547
548 .not_ax:
549 cmp dl, 'A'
550 jne .not_eax
551 push eax
552 mov eax, [ss:bp - 4]
553 call print_eax
554 pop eax
555 jmp .next_char
556
557 .not_eax:
558 cmp dl, 'c'
559 jne .not_cx
560 push ax
561 mov ax, cx
562 call print_ax
563 pop ax
564 jmp .next_char
565
566 .not_cx:
567
568 .print_char:
569 int 0x21
570
571 .next_char:
572 inc di
573 jmp .loop
574
575 .end_loop:
576 pop edi
577 pop edx
578 pop eax
579 pop ebp
580 ret
581
582 ;
583 ; print_ax - print the number in the ax register
584 ;
585
586 print_ax:
587 push ax
588 push bx
589 push cx
590 push dx
591
592 mov bx, ax
593 mov ax, 0x0200
594 mov cx, 4
595 .loop:
596 mov dx, bx
597 shr dx, 12
598 and dl, 0x0f
599 cmp dl, 0x0a
600 jge .hex_val
601 add dl, '0'
602 jmp .not_hex
603
604 .hex_val:
605 add dl, 'a' - 10
606
607 .not_hex:
608 int 0x21
609 shl bx, 4
610 dec cx
611 jnz .loop
612
613 pop dx
614 pop cx
615 pop bx
616 pop ax
617 ret
618
619 print_eax:
620 push eax
621 push ebx
622 push ecx
623 push edx
624
625 mov ebx, eax
626 mov ax, 0x0200
627 mov cx, 8
628 .loop:
629 mov edx, ebx
630 shr edx, 28
631 and dl, 0x0f
632 cmp dl, 0x0a
633 jge .hex_val
634 add dl, '0'
635 jmp .not_hex
636
637 .hex_val:
638 add dl, 'a' - 10
639
640 .not_hex:
641 int 0x21
642 shl ebx, 4
643 dec cx
644 jnz .loop
645
646 pop edx
647 pop ecx
648 pop ebx
649 pop eax
650 ret
651
652 STRUC pe_doshdr
653 e_magic: resw 1
654 e_cblp: resw 1
655 e_cp: resw 1
656 e_crlc: resw 1
657 e_cparhdr: resw 1
658 e_minalloc: resw 1
659 e_maxalloc: resw 1
660 e_ss: resw 1
661 e_sp: resw 1
662 e_csum: resw 1
663 e_ip: resw 1
664 e_cs: resw 1
665 e_lfarlc: resw 1
666 e_ovno: resw 1
667 e_res: resw 4
668 e_oemid: resw 1
669 e_oeminfo: resw 1
670 e_res2: resw 10
671 e_lfanew: resd 1
672 ENDSTRUC
673
674
675 _mb_magic:
676 dd 0
677 _mb_flags:
678 dd 0
679 _mb_checksum:
680 dd 0
681 _mb_header_addr:
682 dd 0
683 _mb_load_addr:
684 dd 0
685 _mb_load_end_addr:
686 dd 0
687 _mb_bss_end_addr:
688 dd 0
689 _mb_entry_addr:
690 dd 0
691
692 _cpe_doshdr:
693 times pe_doshdr_size db 0
694 _current_filehandle:
695 dw 0
696 _current_size:
697 dd 0
698 _current_file_size:
699 dd 0
700
701 ;;
702 ;; Load a SYM file
703 ;; DS:DX = Filename
704 ;;
705 sym_load_module:
706 call load_module1
707 call load_module2
708 mov edi, [next_load_base]
709 add edi, [_current_file_size]
710
711 mov eax, edi
712 test di, 0xfff
713 jz .sym_no_round
714 and di, 0xf000
715 add edi, 0x1000
716
717 ;;
718 ;; Clear unused space in the last page
719 ;;
720 mov esi, edi
721 mov ecx, edi
722 sub ecx, eax
723 .sym_clear:
724 mov byte [esi],0
725 inc esi
726 loop .sym_clear
727 .sym_no_round:
728
729 call load_module3
730 ret
731
732 ;;
733 ;; Load a PE file
734 ;; DS:DX = Filename
735 ;;
736 pe_load_module:
737 call load_module1
738
739 ;;
740 ;; Read in the DOS EXE header
741 ;;
742 mov ah, 0x3f
743 mov bx, [_current_filehandle]
744 mov cx, pe_doshdr_size
745 mov dx, _cpe_doshdr
746 int 0x21
747 jnc .header_read
748 mov dx, error_file_read_failed
749 jmp error
750 .header_read
751
752 ;;
753 ;; Check the DOS EXE magic
754 ;;
755 mov ax, word [_cpe_doshdr + e_magic]
756 cmp ax, 'MZ'
757 je .mz_hdr_good
758 mov dx, error_bad_mz
759 jmp error
760 .mz_hdr_good
761
762 ;;
763 ;; Find the BSS size
764 ;;
765 mov ebx, dword [_multiboot_mods_count]
766 cmp ebx, 0
767 jne .not_first
768
769 mov edx, 0
770 mov ax, 0x4200
771 mov cx, 0
772 mov dx, 0x1004
773 mov bx, [_current_filehandle]
774 int 0x21
775 jnc .start_seek1
776 mov dx, error_file_seek_failed
777 jmp error
778 .start_seek1:
779 mov ah, 0x3F
780 mov bx, [_current_filehandle]
781 mov cx, 32
782 mov dx, _mb_magic
783 int 0x21
784 jnc .mb_header_read
785 mov dx, error_file_read_failed
786 jmp error
787 .mb_header_read:
788 jmp .first
789
790 .not_first:
791 mov dword [_mb_bss_end_addr], 0
792 .first:
793
794 call load_module2
795 call load_module3
796 ret
797
798 load_module1:
799 ;;
800 ;; Open file
801 ;;
802 mov ax, 0x3d00
803 int 0x21
804 jnc .file_opened
805 mov dx, error_file_open_failed
806 jmp error
807 .file_opened:
808
809 ;;
810 ;; Save the file handle
811 ;;
812 mov [_current_filehandle], ax
813
814 ;;
815 ;; Print space
816 ;;
817 mov ah,02h
818 mov dl,' '
819 int 021h
820
821 ;;
822 ;; Seek to the start of the file
823 ;;
824 mov ax, 0x4200
825 mov bx, [_current_filehandle]
826 mov cx, 0
827 mov dx, 0
828 int 0x21
829 jnc .seek_start
830 mov dx, error_file_seek_failed
831 jmp error
832 .seek_start:
833 ret
834
835 load_module2:
836 ;;
837 ;; Seek to the end of the file to get the file size
838 ;;
839 mov edx, 0
840 mov ax, 0x4202
841 mov dx, 0
842 mov cx, 0
843 mov bx, [_current_filehandle]
844 int 0x21
845 jnc .start_end
846 mov dx, error_file_seek_failed
847 jmp error
848 .start_end
849 shl edx, 16
850 mov dx, ax
851 mov [_current_size], edx
852 mov [_current_file_size], edx
853
854 mov edx, 0
855 mov ax, 0x4200
856 mov dx, 0
857 mov cx, 0
858 mov bx, [_current_filehandle]
859 int 0x21
860 jnc .start_seek
861 mov dx, error_file_seek_failed
862 jmp error
863 .start_seek
864
865 mov edi, [next_load_base]
866
867 .read_next:
868 cmp dword [_current_size], 32768
869 jle .read_tail
870
871 ;;
872 ;; Read in the file data
873 ;;
874 push ds
875 mov ah, 0x3f
876 mov bx, [_current_filehandle]
877 mov cx, 32768
878 mov dx, 0x9000
879 mov ds, dx
880 mov dx, 0
881 int 0x21
882 jnc .read_data_succeeded
883 pop ds
884 mov dx, error_file_read_failed
885 jmp error
886 .read_data_succeeded:
887 %ifndef NDEBUG
888 mov ah,02h
889 mov dl,'#'
890 int 021h
891 %endif
892
893 ;;
894 ;; Copy the file data just read in to high memory
895 ;;
896 pop ds
897 mov esi, 0x90000
898 mov ecx, 32768
899 call _himem_copy
900 %ifndef NDEBUG
901 mov ah,02h
902 mov dl,'$'
903 int 021h
904 %else
905 mov ah,02h
906 mov dl,'.'
907 int 021h
908 %endif
909
910 sub dword [_current_size], 32768
911 jmp .read_next
912
913 .read_tail
914 ;;
915 ;; Read in the tailing part of the file data
916 ;;
917 push ds
918 mov eax, [_current_size]
919 mov cx, ax
920 mov ah, 0x3f
921 mov bx, [_current_filehandle]
922 mov dx, 0x9000
923 mov ds, dx
924 mov dx, 0
925 int 0x21
926 jnc .read_last_data_succeeded
927 pop ds
928 mov dx, error_file_read_failed
929 jmp error
930 .read_last_data_succeeded:
931 %ifndef NDEBUG
932 mov ah,02h
933 mov dl,'#'
934 int 021h
935 %endif
936
937 ;;
938 ;; Copy the tailing part to high memory
939 ;;
940 pop ds
941 mov ecx, [_current_size]
942 mov esi, 0x90000
943 call _himem_copy
944 %ifndef NDEBUG
945 mov ah,02h
946 mov dl,'$'
947 int 021h
948 %else
949 mov ah,02h
950 mov dl,'.'
951 int 021h
952 %endif
953
954 mov edx, [_mb_bss_end_addr]
955 cmp edx, 0
956 je .no_bss
957 mov edi, edx
958 .no_bss:
959 test di, 0xfff
960 jz .no_round
961 and di, 0xf000
962 add edi, 0x1000
963 .no_round:
964 ret
965
966 load_module3:
967 mov bx, [_multiboot_mods_count]
968 imul bx, bx, multiboot_module_size
969 add bx, _multiboot_modules
970
971 mov edx, [next_load_base]
972 mov [bx + mbm_mod_start], edx
973 mov [bx + mbm_mod_end], edi
974 mov [next_load_base], edi
975 mov dword [bx + mbm_reserved], 0
976
977 inc dword [_multiboot_mods_count]
978
979 mov eax, 1
980
981 ret
982
983 ;;
984 ;; On error print a message and return zero
985 ;;
986 error:
987 mov ah, 0x9
988 int 0x21
989 mov eax, 0
990 ret
991
992 ;;
993 ;; Copy to high memory
994 ;; ARGUMENTS
995 ;; ESI = Source address
996 ;; EDI = Destination address
997 ;; ECX = Byte count
998 ;; RETURNS
999 ;; EDI = End of the destination region
1000 ;; ECX = 0
1001 ;;
1002 _himem_copy:
1003 push ds ; Save DS
1004 push es ; Save ES
1005 push eax
1006 push esi
1007
1008 cmp eax, 0
1009 je .l3
1010
1011 cli ; No interrupts during pmode
1012
1013 mov eax, cr0 ; Entered protected mode
1014 or eax, 0x1
1015 mov cr0, eax
1016
1017 jmp .l1 ; Flush prefetch queue
1018 .l1:
1019
1020 mov eax, KERNEL_DS ; Load DS with a suitable selector
1021 mov ds, ax
1022 mov eax, KERNEL_DS
1023 mov es, ax
1024
1025 cld
1026 a32 rep movsb
1027 ;.l2:
1028 ; mov al, [esi] ; Copy the data
1029 ; mov [edi], al
1030 ; dec ecx
1031 ; inc esi
1032 ; inc edi
1033 ; cmp ecx, 0
1034 ; jne .l2
1035
1036 mov eax, cr0 ; Leave protected mode
1037 and eax, 0xfffffffe
1038 mov cr0, eax
1039
1040 jmp .l3
1041 .l3:
1042 sti
1043 pop esi
1044 pop eax
1045 pop es
1046 pop ds
1047 ret
1048
1049 ;
1050 ; Loading message
1051 ;
1052 loading_msg db 'Loading: ',0
1053
1054 ;;
1055 ;; Next free address in high memory
1056 ;;
1057 next_load_base dd 0
1058
1059 ;
1060 ; Needed for enabling the a20 address line
1061 ;
1062 empty_8042:
1063 jmp $+3
1064 jmp $+3
1065 in al,064h
1066 test al,02h
1067 jnz empty_8042
1068 ret
1069
1070 ;
1071 ; GDT descriptor
1072 ;
1073 align 8
1074 gdt_descr:
1075 gdt_limit:
1076 dw (5*8)-1
1077 gdt_base:
1078 dd _gdt
1079
1080 ;;
1081 ;; Our initial stack
1082 ;;
1083 real_stack times 1024 db 0
1084 real_stack_end:
1085
1086 ;;
1087 ;; Boot information structure
1088 ;;
1089 _multiboot_info_base:
1090 dd 0x0
1091
1092 _multiboot_info:
1093 _multiboot_flags:
1094 dd 0x0
1095 _multiboot_mem_lower:
1096 dd 0x0
1097 _multiboot_mem_upper:
1098 dd 0x0
1099 _multiboot_boot_device:
1100 dd 0x0
1101 _multiboot_cmdline:
1102 dd 0x0
1103 _multiboot_mods_count:
1104 dd 0x0
1105 _multiboot_mods_addr:
1106 dd 0x0
1107 _multiboot_syms:
1108 times 12 db 0
1109 _multiboot_mmap_length:
1110 dd 0x0
1111 _multiboot_mmap_addr:
1112 dd 0x0
1113 _multiboot_drives_count:
1114 dd 0x0
1115 _multiboot_drives_addr:
1116 dd 0x0
1117 _multiboot_config_table:
1118 dd 0x0
1119 _multiboot_boot_loader_name:
1120 dd 0x0
1121 _multiboot_apm_table:
1122 dd 0x0
1123
1124 _multiboot_modules:
1125 times (64*multiboot_module_size) db 0
1126 _multiboot_module_strings:
1127 times (64*256) db 0
1128
1129 _multiboot_address_range_descriptor_size dd 0
1130
1131 _multiboot_address_ranges:
1132 times (64*multiboot_address_range_size) db 0
1133
1134 _multiboot_kernel_cmdline:
1135 times 255 db 0
1136
1137 ;;
1138 ;; Global descriptor table
1139 ;;
1140 _gdt:
1141 dw 0x0 ; Zero descriptor
1142 dw 0x0
1143 dw 0x0
1144 dw 0x0
1145
1146 dw 0xffff ; Kernel code descriptor
1147 dw 0x0000
1148 dw 0x9a00
1149 dw 0x00cf
1150
1151 dw 0xffff ; Kernel data descriptor
1152 dw 0x0000
1153 dw 0x9200
1154 dw 0x00cf
1155
1156 dw 0xffff ; Loader code descriptor
1157 _loader_code_base_0_15:
1158 dw 0x0000
1159 _loader_code_base_16_23:
1160 db 0x00
1161 db 0x9a
1162 dw 0x0000
1163
1164 dw 0xffff ; Loader data descriptor
1165 _loader_data_base_0_15:
1166 dw 0x0000
1167 _loader_data_base_16_23:
1168 db 0x00
1169 db 0x92
1170 dw 0x0000
1171
1172 error_pmode_already:
1173 db 'Error: The processor is already in protected mode'
1174 db 0xa, 0xd, '$'
1175 error_file_open_failed:
1176 db 'Error: Failed to open file'
1177 db 0xa, 0xd, '$'
1178 error_file_seek_failed:
1179 db 'Error: File seek failed'
1180 db 0xa, 0xd, '$'
1181 error_file_read_failed:
1182 db 'Error: File read failed'
1183 db 0xa, 0xd, '$'
1184 error_coff_load_failed:
1185 db 'Error: Failed to load COFF file'
1186 db 0xa, 0xd, '$'
1187 error_bad_mz:
1188 db 'Error: Bad DOS EXE magic'
1189 db 0xa, 0xd, '$'