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