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