6771b9947cae75ccbcac491cac8a4dd1d2d61f0e
[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 KERNEL_BASE equ 0c0000000h
10
11 ;
12 ; Segment selectors
13 ;
14 ;USER_CS equ 08h
15 ;USER_DS equ 010h
16 ;KERNEL_CS equ 020h
17 ;KERNEL_DS equ 028h
18
19 KERNEL_CS equ 08h
20 KERNEL_DS equ 010h
21
22 ;
23 ; Space reserved in the gdt for tss descriptors
24 ;
25 NR_TASKS equ 128
26
27 ;
28 ; We are a .com program
29 ;
30 org 100h
31
32 ;
33 ; 16 bit code
34 ;
35 BITS 16
36
37 %define NDEBUG 1
38
39 %macro DPRINT 1+
40 %ifndef NDEBUG
41 jmp %%end_str
42
43 %%str: db %1
44
45 %%end_str:
46 push di
47 push ds
48 push es
49 pop ds
50 mov di, %%str
51 call print_string
52 pop ds
53 pop di
54 %endif
55 %endmacro
56
57 entry:
58 ;
59 ; Load stack
60 ;
61 cli
62 push ds
63 pop ss
64 push ds
65 pop es
66 mov sp,real_stack_end
67 sti
68
69 ;
70 ; Setup the loader space
71 ;
72 mov ebx,0
73 mov eax,0
74 mov ecx,0
75 mov edx,0
76 mov esi,0
77 mov edi,0
78
79 ;
80 ; Calculate the end of this module
81 ;
82 mov ax,ds
83 movzx ebx,ax
84 shl ebx,4
85 add ebx,_end
86
87 ;
88 ; Round up to the nearest page
89 ;
90 and ebx,~0xfff
91 add ebx,01000h
92
93 ;
94 ; Set the start of the page directory
95 ;
96 mov [kernel_page_directory_base],ebx
97
98 ;
99 ; Set the start of the continuous range of physical memory
100 ; occupied by the kernel
101 ;
102 mov [_start_mem],ebx
103 add ebx,01000h
104
105 ;
106 ; Calculate the start of the system page table (0xc0000000 upwards)
107 ;
108 mov [system_page_table_base],ebx
109 add ebx,01000h
110
111 ;
112 ; Calculate the start of the page table to map the first 4mb
113 ;
114 mov [lowmem_page_table_base],ebx
115 add ebx,01000h
116
117 ;
118 ; Set the position for the first module to be loaded
119 ;
120 mov [next_load_base],ebx
121
122 ;
123 ; Set the address of the start of kernel code
124 ;
125 mov [_start_kernel],ebx
126
127 ;
128 ; Make the argument list into a c string
129 ;
130 mov di,081h
131 l1:
132 cmp byte [di],0dh
133 je l2
134 cmp byte [di],' '
135 jne l12
136 mov byte [di],0
137 l12:
138 inc di
139 jmp l1
140 l2:
141 mov byte [di],0
142 mov [end_cmd_line],di
143
144 mov dx,082h
145 l14:
146 mov bx,dx
147 cmp byte [bx],0
148 je l16
149
150 ;
151 ; Process the arguments
152 ;
153 mov di,loading_msg
154 call print_string
155 mov di,dx
156 call print_string
157 mov ah,02h
158 mov dl,0dh
159 int 021h
160 mov ah,02h
161 mov dl,0ah
162 int 021h
163
164 ;
165 ; Load the file
166 ;
167 push di
168 mov dx,di
169 ; call _load_file
170 call pe_load_module
171 pop di
172
173 ;
174 ; Move onto the next module name in the command line
175 ;
176 l15:
177 cmp di,[end_cmd_line]
178 je l16
179 cmp byte [di],0
180 je l17
181 inc di
182 jmp l15
183 l17:
184 inc di
185 mov dx,di
186 jmp l14
187 l16:
188
189 ;
190 ; Set the end of kernel memory
191 ;
192 mov eax,[next_load_base]
193 mov [_end_mem],eax
194
195 ;
196 ; Begin the pmode initalization
197 ;
198 jmp _to_pmode
199
200 exit:
201 mov ax,04c00h
202 int 21h
203
204 ;
205 ; Any errors detected jump here
206 ;
207 _error:
208 mov di,err_msg
209 call print_string
210 jmp exit
211
212 end_cmd_line dw 0
213
214 ;
215 ; In: EDI = address
216 ; Out: FS = segment
217 ; DI = base
218 ;
219 convert_to_seg:
220 push eax
221
222 mov eax,edi
223 ; shr eax,16
224 ; shl eax,12
225 ; mov fs,ax
226 shr eax, 4
227 mov fs, ax
228 and edi, 0xf
229
230 ; and edi,0ffffh
231
232 pop eax
233 ret
234
235 ;
236 ; Print string in DS:DI
237 ;
238 print_string:
239 push ebp
240 mov bp, sp
241 push eax
242 push edx
243 push edi
244
245 mov ax, 0x0200
246 .loop:
247 mov dl, [di]
248 cmp dl, 0
249 je .end_loop
250 cmp dl, '%'
251 jne .print_char
252 inc di
253 mov dl, [di]
254 cmp dl, 'a'
255 jne .not_ax
256 push eax
257 mov eax, [ss:bp - 4]
258 call print_ax
259 pop eax
260 jmp .next_char
261
262 .not_ax:
263 cmp dl, 'A'
264 jne .not_eax
265 push eax
266 mov eax, [ss:bp - 4]
267 call print_eax
268 pop eax
269 jmp .next_char
270
271 .not_eax:
272 cmp dl, 'c'
273 jne .not_cx
274 push ax
275 mov ax, cx
276 call print_ax
277 pop ax
278 jmp .next_char
279
280 .not_cx:
281
282 .print_char:
283 int 0x21
284
285 .next_char:
286 inc di
287 jmp .loop
288
289 .end_loop:
290 pop edi
291 pop edx
292 pop eax
293 pop ebp
294 ret
295
296 ;
297 ; print_ax - print the number in the ax register
298 ;
299
300 print_ax:
301 push ax
302 push bx
303 push cx
304 push dx
305
306 mov bx, ax
307 mov ax, 0x0200
308 mov cx, 4
309 .loop:
310 mov dx, bx
311 shr dx, 12
312 and dl, 0x0f
313 cmp dl, 0x0a
314 jge .hex_val
315 add dl, '0'
316 jmp .not_hex
317
318 .hex_val:
319 add dl, 'a' - 10
320
321 .not_hex:
322 int 0x21
323 shl bx, 4
324 dec cx
325 jnz .loop
326
327 pop dx
328 pop cx
329 pop bx
330 pop ax
331 ret
332
333 print_eax:
334 push eax
335 push ebx
336 push ecx
337 push edx
338
339 mov ebx, eax
340 mov ax, 0x0200
341 mov cx, 8
342 .loop:
343 mov edx, ebx
344 shr edx, 28
345 and dl, 0x0f
346 cmp dl, 0x0a
347 jge .hex_val
348 add dl, '0'
349 jmp .not_hex
350
351 .hex_val:
352 add dl, 'a' - 10
353
354 .not_hex:
355 int 0x21
356 shl ebx, 4
357 dec cx
358 jnz .loop
359
360 pop edx
361 pop ecx
362 pop ebx
363 pop eax
364 ret
365
366
367 STRUC DOS_HDR
368 e_magic: resw 1
369 e_cblp: resw 1
370 e_cp: resw 1
371 e_crlc: resw 1
372 e_cparhdr: resw 1
373 e_minalloc: resw 1
374 e_maxalloc: resw 1
375 e_ss: resw 1
376 e_sp: resw 1
377 e_csum: resw 1
378 e_ip: resw 1
379 e_cs: resw 1
380 e_lfarlc: resw 1
381 e_ovno: resw 1
382 e_res: resw 4
383 e_oemid: resw 1
384 e_oeminfo: resw 1
385 e_res2: resw 10
386 e_lfanew: resd 1
387 ENDSTRUC
388
389 STRUC NT_HDRS
390 nth_sig: resd 1
391 ntf_mach: resw 1
392 ntf_num_secs: resw 1
393 ntf_timestamp: resd 1
394 ntf_symtab_ptr: resd 1
395 ntf_num_syms: resd 1
396 ntf_opt_hdr_sz: resw 1
397 ntf_chars: resw 1
398
399 nto_magic: resw 1
400 nto_mjr_lnk_vr: resb 1
401 nto_mnr_lnk_vr: resb 1
402 nto_code_sz: resd 1
403 nto_data_sz: resd 1
404 nto_bss_sz: resd 1
405 nto_entry_offs: resd 1
406 nto_code_offs: resd 1
407 nto_data_offs: resd 1
408 nto_image_base: resd 1
409 nto_sec_align: resd 1
410 nto_file_align: resd 1
411 nto_mjr_os_ver: resw 1
412 nto_Mnr_os_ver: resw 1
413 nto_mjr_img_vr: resw 1
414 nto_Mnr_img_vr: resw 1
415 nto_mjr_subsys: resw 1
416 nto_mnr_subsys: resw 1
417 nto_w32_ver: resd 1
418 nto_image_sz: resd 1
419 nto_hdr_sz: resd 1
420 nto_chksum: resd 1
421 nto_subsys: resw 1
422 nto_dll_chars: resw 1
423 nto_stk_res_sz: resd 1
424 nto_stk_cmt_sz: resd 1
425 nto_hp_res_sz: resd 1
426 nto_hp_cmt_sz: resd 1
427 nto_ldr_flags: resd 1
428 nto_dir_cnt: resd 1
429 nto_dir_ent: resq 16
430 ENDSTRUC
431
432 STRUC DATA_DIR
433 dd_rva: resd 1
434 dd_sz: resd 1
435 ENDSTRUC
436
437 STRUC SCN_HDR
438 se_name: resb 8
439 se_vsz: resd 1
440 se_vaddr: resd 1
441 se_rawsz: resd 1
442 se_raw_ofs: resd 1
443 se_reloc_ofs: resd 1
444 se_lnum_ofs: resd 1
445 se_num_relocs: resw 1
446 se_num_lnums: resw 1
447 se_chars: resd 1
448 ENDSTRUC
449
450 ;
451 ; pe_load_module - load a PE module into memory
452 ;
453 ; DI - Filename
454 ;
455 ; [_nr_files] - total files loaded (incremented)
456 ; [next_load_base] - load base for file (updated to next loc)
457 ; [_module_lengths] - correct slot is set.
458 ;
459
460 pe_load_module:
461 push dx
462 push ds
463
464 push ds
465 pop es
466
467 mov eax, [next_load_base]
468 mov [load_base], eax
469 DPRINT 'next_load_base %A', 13, 10, 0
470
471 ;
472 ; Open the file
473 ;
474 mov ax, 0x3d00
475 mov dx, di
476 int 0x21
477 jnc .open_good
478 jmp .error
479 .open_good:
480 mov [file_handle],ax
481
482 ;
483 ; Seek to beginning of file
484 ;
485 mov ax,0x4200
486 mov bx, [file_handle]
487 mov cx, 0
488 mov dx, 0
489 int 0x21
490 jnc .rewind_good
491 jmp .error
492 .rewind_good:
493
494 ;
495 ; Compute load address for PE headers
496 ;
497 mov edi,[load_base]
498 call convert_to_seg
499 mov dx,di
500 push fs
501 pop ds
502
503 ;
504 ; Load the headers
505 ;
506 mov ax, 0x3f00
507 mov bx, [es:file_handle]
508 mov cx, 0x1000
509 int 0x21
510
511 ;
512 ; Check DOS MZ Header
513 ;
514 mov bx, dx
515 mov ax, word [bx + e_magic]
516 cmp ax, 'MZ'
517 je .mz_hdr_good
518 push es
519 pop ds
520 mov dx, bad_mz_msg
521 mov di, dx
522 call print_string
523 jmp .error
524
525 .mz_hdr_good:
526 ;
527 ; Check PE Header
528 ;
529 mov eax, dword [bx + e_lfanew]
530 DPRINT 'lfanew %A ', 0
531 add bx, ax
532 mov eax, dword [bx + nth_sig]
533 cmp eax, 0x00004550
534 je .pe_hdr_good
535 push es
536 pop ds
537 mov dx, bad_pe_msg
538 mov di, dx
539 call print_string
540 jmp .error
541
542 .pe_hdr_good:
543 ;
544 ; Get header size and bump next_load_base
545 ;
546 mov eax, [bx + nto_hdr_sz]
547 DPRINT 'header size %A ', 0
548 add dword [es:next_load_base], eax
549
550 ;
551 ; Setup section pointer
552 ;
553 mov ax, [bx + ntf_num_secs]
554 DPRINT 'num sections %a', 13, 10, 0
555 mov [es:num_sections], ax
556 add bx, NT_HDRS_size
557 mov [es:cur_section], bx
558 mov [es:cur_section + 2], ds
559 ;
560 ; Load each section or fill with zeroes
561 ;
562 .scn_loop:
563 ;
564 ; Compute size of data to load from file
565 ;
566 mov eax, [bx + se_rawsz]
567 DPRINT 'raw size %A ', 0
568 cmp eax, 0
569 jne .got_data
570 jmp .no_data
571 .got_data:
572 mov [es:size_mod_4k], ax
573 and word [es:size_mod_4k], 0x0fff
574 shr eax, 12
575 mov dword [es:size_div_4k], eax
576
577 ;
578 ; Seek to section offset
579 ;
580 mov eax, [bx + se_raw_ofs]
581 DPRINT 'raw offset %A ', 0
582 mov dx, ax
583 shr eax, 16
584 mov cx, ax
585 mov ax,0x4200
586 mov bx, [es:file_handle]
587 int 0x21
588 jnc .seek_good
589 jmp .error
590 .seek_good:
591
592 ;
593 ; Load the base pointer
594 ;
595 mov edi,[es:next_load_base]
596 call convert_to_seg
597 mov dx, di
598 push fs
599 pop ds
600
601 ;
602 ; Read data in 4k chunks
603 ;
604 .do_chunk:
605 ;
606 ; Check if we have read it all
607 ;
608 mov eax, [es:size_div_4k]
609 cmp eax, 0
610 je .chunk_done
611
612 ;
613 ; Make the call (dx was loaded above)
614 ;
615 mov ax, 0x3f00
616 mov bx, [es:file_handle]
617 mov cx, 0x1000
618 int 0x21
619 ; FIXME: should check return status and count
620
621 ;
622 ; We move onto the next pointer by altering ds
623 ;
624 mov ax, ds
625 add ax, 0x0100
626 mov ds, ax
627 dec word [es:size_div_4k]
628 jmp .do_chunk
629
630 .chunk_done:
631 ;
632 ; Read the last section
633 ;
634 mov ax, 0x3f00
635 mov bx, [es:file_handle]
636 mov cx, [es:size_mod_4k]
637 int 0x21
638 jnc .last_read_good
639 jmp .error
640 .last_read_good:
641
642 .no_data:
643 ;
644 ; Zero out uninitialized data sections
645 ;
646 lds bx, [es:cur_section]
647 mov eax, dword [bx + se_chars]
648 DPRINT 'section chars %A', 13, 10, 0
649 test dword [bx + se_chars], 0x80
650 jz .no_fill
651
652 ;
653 ; Compute size of section to zero fill
654 ;
655 mov eax, [bx + se_vsz]
656 cmp eax, 0
657 je .no_fill
658 mov [es:size_mod_4k], ax
659 and word [es:size_mod_4k], 0x0fff
660 shr eax, 12
661 mov [size_div_4k], eax
662
663 ;
664 ; Load the base pointer
665 ;
666 mov edi,[es:next_load_base]
667 call convert_to_seg
668 mov dx, di
669 push fs
670 pop ds
671
672 .do_fill:
673 ;
674 ; Check if we have read it all
675 ;
676 mov eax, [es:size_div_4k]
677 cmp eax, 0
678 je .fill_done
679
680 ;
681 ; Zero out a chunk
682 ;
683 mov ax, 0x0000
684 mov cx, 0x1000
685 push di
686 push es
687 push ds
688 pop es
689 rep stosb
690 pop es
691 pop di
692
693 ;
694 ; We move onto the next pointer by altering ds
695 ;
696 mov ax, ds
697 add ax, 0x0100
698 mov ds, ax
699 dec word [es:size_div_4k]
700 jmp .do_fill
701
702 .fill_done:
703 ;
704 ; Read the last section
705 ;
706 mov ax, 0x0000
707 mov cx, [es:size_mod_4k]
708 push di
709 push es
710 push ds
711 pop es
712 rep stosb
713 pop es
714 pop di
715
716 .no_fill:
717
718 ;
719 ; Update raw data offset in section header
720 ;
721 lds bx, [es:cur_section]
722 mov eax, [es:next_load_base]
723 sub eax, [es:load_base]
724 DPRINT 'new raw offset %A ', 0
725 mov [bx + se_raw_ofs], eax
726
727 ;
728 ; Update next_load_base
729 ;
730 mov eax, [bx + se_vsz]
731 DPRINT 'scn virtual sz %A ', 0
732 and eax, 0xfffff000
733 add dword [es:next_load_base], eax
734 test dword [bx + se_vsz], 0xfff
735 jz .even_scn
736 add dword [es:next_load_base], 0x1000
737
738 .even_scn:
739 mov eax, [es:next_load_base]
740 DPRINT 'next load base %A', 13, 10, 0
741
742 ;
743 ; Setup for next section or exit loop
744 ;
745 dec word [es:num_sections]
746 jz .scn_done
747 add bx, SCN_HDR_size
748 mov [es:cur_section], bx
749 jmp .scn_loop
750
751 .scn_done:
752 ;
753 ; Update module_length
754 ;
755 mov eax, [es:next_load_base]
756 sub eax, [es:load_base]
757 mov esi, [es:_nr_files]
758 mov [es:_module_lengths + esi * 4], eax
759
760 inc dword [es:_nr_files]
761
762 pop ds
763 pop dx
764 ret
765
766 .error:
767 push es
768 pop ds
769 mov di, err_msg
770 call print_string
771 jmp exit
772
773 ;
774 ; Handle of the currently open file
775 ;
776 file_handle dw 0
777
778 ;
779 ; Size of the current file mod 4k
780 ;
781 size_mod_4k dw 0
782
783 ;
784 ; Size of the current file divided by 4k
785 ;
786 size_div_4k dd 0
787
788 load_base dd 0
789 num_sections dw 0
790 cur_section dd 0
791
792 ;
793 ;
794 ;
795 last_addr dw 0
796
797 ;
798 ; Generic error message
799 ;
800 err_msg db 'Error during operation',10, 13, 0
801 bad_mz_msg db 'Module has bad MZ header', 10, 13, 0
802 bad_pe_msg db 'Module has bad PE header', 10, 13, 0
803 rostitle db '',0
804 loading_msg db 'Loading: ',0
805 death_msg db 'death', 0
806
807 filelength_lo dw 0
808 filelength_hi dw 0
809
810 kernel_page_directory_base dd 0
811 system_page_table_base dd 0
812 lowmem_page_table_base dd 0
813 next_load_base dd 0
814 _start_kernel dd 0
815
816 boot_param_struct_base dd 0
817
818 ;
819 ; These variables are passed to the kernel (as a structure)
820 ;
821 align 4
822 _boot_param_struct:
823 _magic:
824 dd 0
825 _cursorx:
826 dd 0
827 _cursory:
828 dd 0
829 _nr_files:
830 dd 0
831 _start_mem:
832 dd 0
833 _end_mem:
834 dd 0
835 _module_lengths:
836 times 64 dd 0
837 _kernel_parameters:
838 times 256 db 0
839 _end_boot_param_struct
840
841 ;
842 ; Needed for enabling the a20 address line
843 ;
844 empty_8042:
845 jmp $+3
846 jmp $+3
847 in al,064h
848 test al,02h
849 jnz empty_8042
850 ret
851
852 ;
853 ; GDT descriptor
854 ;
855 align 8
856 gdt_descr:
857 gdt_limit:
858 dw (3*8)-1
859 gdt_base:
860 dd gdt
861
862
863 _to_pmode:
864 ;
865 ; Setup kernel parameters
866 ;
867 mov dword [_magic],0xdeadbeef
868
869 ;
870 ; Save cursor position
871 ;
872 mov ax,3 ;! Reset video mode
873 int 10h
874
875
876 mov bl,10
877 mov ah,12
878 int 10h
879
880 mov ax,1112h ;! Use 8x8 font
881 xor bl,bl
882 int 10h
883 mov ax,1200h ;! Use alternate print screen
884 mov bl,20h
885 int 10h
886 mov ah,1h ;! Define cursor (scan lines 6 to 7)
887 mov cx,0607h
888 int 10h
889
890 mov ah,1
891 mov cx,0600h
892 int 10h
893
894 MOV AH,6 ;SCROLL ACTIVE PAGE UP
895 MOV AL,32H ;CLEAR 25 LINES
896 MOV CX,0H ;UPPER LEFT OF SCROLL
897 MOV DX,314FH ;LOWER RIGHT OF SCROLL
898 MOV BH,1*10h+1 ;USE NORMAL ATTRIBUTE ON BLANKED LINE
899 INT 10H ;VIDEO-IO
900
901
902 mov dx,0
903 mov dh,0
904
905 mov ah,02h
906 mov bh,0
907 int 10h
908
909 mov dx,0
910 mov dh,0
911
912 mov ah,02h
913 mov bh,0
914 int 010h
915
916 mov ah,03h
917 mov bh,0h
918 int 010h
919 movzx eax,dl
920 mov [_cursorx],eax
921 movzx eax,dh
922 mov [_cursory],eax
923
924 mov bx,ds
925 movzx eax,bx
926 shl eax,4
927 add eax,_boot_param_struct
928 mov [boot_param_struct_base],eax
929
930 cli
931
932 ;
933 ; Zero out the kernel page directory
934 ;
935 ;
936 mov edi,[kernel_page_directory_base]
937 call convert_to_seg
938
939 mov cx,1024
940 l10:
941 mov dword [fs:di],0
942 add di,4
943 loop l10
944
945 ;
946 ; Map in the lowmem page table (and reuse it for the identity map)
947 ;
948 mov edi,[kernel_page_directory_base]
949 call convert_to_seg
950
951 mov eax,[lowmem_page_table_base]
952 add eax,07h
953 mov [fs:di],eax
954 mov [fs:di+(0xd0000000/(1024*1024))],eax
955
956 ;
957 ; Map the page tables from the page table
958 ;
959 mov eax,[kernel_page_directory_base]
960 add eax,07h
961 mov [fs:di+(0xf0000000/(1024*1024))],eax
962
963 ;
964 ; Map in the kernel page table
965 ;
966 mov eax,[system_page_table_base]
967 add eax,07h
968 mov [fs:di+3072],eax
969
970 ;
971 ; Setup the lowmem page table
972 ;
973 mov edi,[lowmem_page_table_base]
974 call convert_to_seg
975
976 mov ebx,0
977 l9:
978 mov eax,ebx
979 shl eax,12 ; ebx = ebx * 4096
980 add eax,07h ; user, rw, present
981 mov [fs:edi+ebx*4],eax
982 inc ebx
983 cmp ebx,1024
984 jl l9
985
986 ;
987 ; Setup the system page table
988 ;
989 mov edi,[system_page_table_base]
990 call convert_to_seg
991
992 mov eax,07h
993 l8:
994 mov edx,eax
995 add edx,[_start_kernel]
996 mov [fs:edi],edx
997 add edi,4
998 add eax,1000h
999 cmp eax,100007h
1000 jl l8
1001
1002 ;
1003 ; Load the page directory into cr3
1004 ;
1005 mov eax,[kernel_page_directory_base]
1006 mov cr3,eax
1007
1008 ;
1009 ; Setup various variables
1010 ;
1011 mov bx,ds
1012 movzx eax,bx
1013 shl eax,4
1014 add [gdt_base],eax
1015
1016 ;
1017 ; Enable the A20 address line (to allow access to over 1mb)
1018 ;
1019 call empty_8042
1020 mov al,0D1h ; command write
1021 out 064h,al
1022 call empty_8042
1023 mov al,0DFh ; A20 on
1024 out 060h,al
1025 call empty_8042
1026
1027 ;
1028 ; Reprogram the PIC because they overlap the Intel defined
1029 ; exceptions
1030 ;
1031 mov al,011h ; initialization sequence
1032 out 020h,al ; send it to 8259A-1
1033 dw 0x00eb,0x00eb ; jmp $+2, jmp $+2
1034 out 0A0h,al ; and to 8259A-2
1035 dw 0x00eb,0x00eb
1036 mov al,040h ; start of hardware int's (0x20)
1037 out 021h,al
1038 dw 0x00eb,0x00eb
1039 mov al,048h ; start of hardware int's 2 (0x28)
1040 out 0A1h,al
1041 dw 0x00eb,0x00eb
1042 mov al,04h ; 8259-1 is master
1043 out 021h,al
1044 dw 0x00eb,0x00eb
1045 mov al,002h ; 8259-2 is slave
1046 out 0A1h,al
1047 dw 0x00eb,0x00eb
1048 mov al,01h ; 8086 mode for both
1049 out 021h,al
1050 dw 0x00eb,0x00eb
1051 out 0A1h,al
1052 dw 0x00eb,0x00eb
1053 mov al,0FFh ; mask off all interrupts for now
1054 out 021h,al
1055 dw 0x00eb,0x00eb
1056 out 0A1h,al
1057
1058 ;
1059 ; Load stack
1060 ;
1061 mov bx,ds
1062 movzx eax,bx
1063 shl eax,4
1064 add eax,real_stack_end
1065 mov [real_stack_base],eax
1066 mov esp,[real_stack_base]
1067 mov edx,[boot_param_struct_base]
1068
1069 ;
1070 ; load gdt
1071 ;
1072 lgdt [gdt_descr]
1073
1074 ;
1075 ; Enter pmode and clear prefetch queue
1076 ;
1077 mov eax,cr0
1078 or eax,0x80010001
1079 mov cr0,eax
1080 jmp next
1081 next:
1082 ;
1083 ; NOTE: This must be position independant (no references to
1084 ; non absolute variables)
1085 ;
1086
1087 ;
1088 ; Initalize segment registers
1089 ;
1090 mov ax,KERNEL_DS
1091 mov ds,ax
1092 mov ss,ax
1093 mov es,ax
1094 mov fs,ax
1095 mov gs,ax
1096
1097 ;
1098 ; Initalize eflags
1099 ;
1100 push dword 0
1101 popf
1102
1103 ;
1104 ; Jump to start of 32 bit code at c0000000
1105 ;
1106 push edx
1107 push dword 0
1108 jmp dword KERNEL_CS:(KERNEL_BASE+0x1000)
1109
1110
1111 ;
1112 ; Our initial stack
1113 ;
1114 real_stack times 1024 db 0
1115 real_stack_end:
1116
1117 real_stack_base dd 0
1118
1119
1120 ;
1121 ; Global descriptor table
1122 ;
1123 align 8
1124 gdt:
1125 dw 0 ; Zero descriptor
1126 dw 0
1127 dw 0
1128 dw 0
1129
1130 ;dw 00000h ; User code descriptor
1131 ;dw 00000h ; base: 0h limit: 3gb
1132 ;dw 0fa00h
1133 ;dw 000cch
1134
1135 ;dw 00000h ; User data descriptor
1136 ;dw 00000h ; base: 0h limit: 3gb
1137 ;dw 0f200h
1138 ;dw 000cch
1139
1140 ;dw 00000h
1141 ;dw 00000h
1142 ;dw 00000h
1143 ;dw 00000h
1144
1145 dw 0ffffh ; Kernel code descriptor
1146 dw 00000h ;
1147 dw 09a00h ; base 0h limit 4gb
1148 dw 000cfh
1149
1150 dw 0ffffh ; Kernel data descriptor
1151 dw 00000h ;
1152 dw 09200h ; base 0h limit 4gb
1153 dw 000cfh
1154
1155
1156 ;times NR_TASKS*8 db 0
1157
1158 _end:
1159
1160
1161