Began seperation of machine-dependant/independant sections of memory
[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 _end_boot_param_struct
838
839 ;
840 ; Needed for enabling the a20 address line
841 ;
842 empty_8042:
843 jmp $+3
844 jmp $+3
845 in al,064h
846 test al,02h
847 jnz empty_8042
848 ret
849
850 ;
851 ; GDT descriptor
852 ;
853 align 8
854 gdt_descr:
855 gdt_limit:
856 dw (3*8)-1
857 gdt_base:
858 dd gdt
859
860
861 _to_pmode:
862 ;
863 ; Setup kernel parameters
864 ;
865 mov dword [_magic],0xdeadbeef
866
867 ;
868 ; Save cursor position
869 ;
870 mov ax,3 ;! Reset video mode
871 int 10h
872
873
874 mov bl,10
875 mov ah,12
876 int 10h
877
878 mov ax,1112h ;! Use 8x8 font
879 xor bl,bl
880 int 10h
881 mov ax,1200h ;! Use alternate print screen
882 mov bl,20h
883 int 10h
884 mov ah,1h ;! Define cursor (scan lines 6 to 7)
885 mov cx,0607h
886 int 10h
887
888 mov ah,1
889 mov cx,0600h
890 int 10h
891
892 MOV AH,6 ;SCROLL ACTIVE PAGE UP
893 MOV AL,32H ;CLEAR 25 LINES
894 MOV CX,0H ;UPPER LEFT OF SCROLL
895 MOV DX,314FH ;LOWER RIGHT OF SCROLL
896 MOV BH,1*10h+1 ;USE NORMAL ATTRIBUTE ON BLANKED LINE
897 INT 10H ;VIDEO-IO
898
899
900 mov dx,0
901 mov dh,0
902
903 mov ah,02h
904 mov bh,0
905 int 10h
906
907 mov dx,0
908 mov dh,0
909
910 mov ah,02h
911 mov bh,0
912 int 010h
913
914 mov ah,03h
915 mov bh,0h
916 int 010h
917 movzx eax,dl
918 mov [_cursorx],eax
919 movzx eax,dh
920 mov [_cursory],eax
921
922 mov bx,ds
923 movzx eax,bx
924 shl eax,4
925 add eax,_boot_param_struct
926 mov [boot_param_struct_base],eax
927
928 cli
929
930 ;
931 ; Zero out the kernel page directory
932 ;
933 ;
934 mov edi,[kernel_page_directory_base]
935 call convert_to_seg
936
937 mov cx,1024
938 l10:
939 mov dword [fs:di],0
940 add di,4
941 loop l10
942
943 ;
944 ; Map in the lowmem page table (and reuse it for the identity map)
945 ;
946 mov edi,[kernel_page_directory_base]
947 call convert_to_seg
948
949 mov eax,[lowmem_page_table_base]
950 add eax,07h
951 mov [fs:di],eax
952 mov [fs:di+(0xd0000000/(1024*1024))],eax
953
954 ;
955 ; Map the page tables from the page table
956 ;
957 mov eax,[kernel_page_directory_base]
958 add eax,07h
959 mov [fs:di+(0xf0000000/(1024*1024))],eax
960
961 ;
962 ; Map in the kernel page table
963 ;
964 mov eax,[system_page_table_base]
965 add eax,07h
966 mov [fs:di+3072],eax
967
968 ;
969 ; Setup the lowmem page table
970 ;
971 mov edi,[lowmem_page_table_base]
972 call convert_to_seg
973
974 mov ebx,0
975 l9:
976 mov eax,ebx
977 shl eax,12 ; ebx = ebx * 4096
978 add eax,07h ; user, rw, present
979 mov [fs:edi+ebx*4],eax
980 inc ebx
981 cmp ebx,1024
982 jl l9
983
984 ;
985 ; Setup the system page table
986 ;
987 mov edi,[system_page_table_base]
988 call convert_to_seg
989
990 mov eax,07h
991 l8:
992 mov edx,eax
993 add edx,[_start_kernel]
994 mov [fs:edi],edx
995 add edi,4
996 add eax,1000h
997 cmp eax,100007h
998 jl l8
999
1000 ;
1001 ; Load the page directory into cr3
1002 ;
1003 mov eax,[kernel_page_directory_base]
1004 mov cr3,eax
1005
1006 ;
1007 ; Setup various variables
1008 ;
1009 mov bx,ds
1010 movzx eax,bx
1011 shl eax,4
1012 add [gdt_base],eax
1013
1014 ;
1015 ; Enable the A20 address line (to allow access to over 1mb)
1016 ;
1017 call empty_8042
1018 mov al,0D1h ; command write
1019 out 064h,al
1020 call empty_8042
1021 mov al,0DFh ; A20 on
1022 out 060h,al
1023 call empty_8042
1024
1025 ;
1026 ; Reprogram the PIC because they overlap the Intel defined
1027 ; exceptions
1028 ;
1029 mov al,011h ; initialization sequence
1030 out 020h,al ; send it to 8259A-1
1031 dw 0x00eb,0x00eb ; jmp $+2, jmp $+2
1032 out 0A0h,al ; and to 8259A-2
1033 dw 0x00eb,0x00eb
1034 mov al,040h ; start of hardware int's (0x20)
1035 out 021h,al
1036 dw 0x00eb,0x00eb
1037 mov al,048h ; start of hardware int's 2 (0x28)
1038 out 0A1h,al
1039 dw 0x00eb,0x00eb
1040 mov al,04h ; 8259-1 is master
1041 out 021h,al
1042 dw 0x00eb,0x00eb
1043 mov al,002h ; 8259-2 is slave
1044 out 0A1h,al
1045 dw 0x00eb,0x00eb
1046 mov al,01h ; 8086 mode for both
1047 out 021h,al
1048 dw 0x00eb,0x00eb
1049 out 0A1h,al
1050 dw 0x00eb,0x00eb
1051 mov al,0FFh ; mask off all interrupts for now
1052 out 021h,al
1053 dw 0x00eb,0x00eb
1054 out 0A1h,al
1055
1056 ;
1057 ; Load stack
1058 ;
1059 mov bx,ds
1060 movzx eax,bx
1061 shl eax,4
1062 add eax,real_stack_end
1063 mov [real_stack_base],eax
1064 mov esp,[real_stack_base]
1065 mov edx,[boot_param_struct_base]
1066
1067 ;
1068 ; load gdt
1069 ;
1070 lgdt [gdt_descr]
1071
1072 ;
1073 ; Enter pmode and clear prefetch queue
1074 ;
1075 mov eax,cr0
1076 or eax,0x80010001
1077 mov cr0,eax
1078 jmp next
1079 next:
1080 ;
1081 ; NOTE: This must be position independant (no references to
1082 ; non absolute variables)
1083 ;
1084
1085 ;
1086 ; Initalize segment registers
1087 ;
1088 mov ax,KERNEL_DS
1089 mov ds,ax
1090 mov ss,ax
1091 mov es,ax
1092 mov fs,ax
1093 mov gs,ax
1094
1095 ;
1096 ; Initalize eflags
1097 ;
1098 push dword 0
1099 popf
1100
1101 ;
1102 ; Jump to start of 32 bit code at c0000000
1103 ;
1104 push edx
1105 push dword 0
1106 jmp dword KERNEL_CS:(KERNEL_BASE+0x1000)
1107
1108
1109 ;
1110 ; Our initial stack
1111 ;
1112 real_stack times 1024 db 0
1113 real_stack_end:
1114
1115 real_stack_base dd 0
1116
1117
1118 ;
1119 ; Global descriptor table
1120 ;
1121 align 8
1122 gdt:
1123 dw 0 ; Zero descriptor
1124 dw 0
1125 dw 0
1126 dw 0
1127
1128 ;dw 00000h ; User code descriptor
1129 ;dw 00000h ; base: 0h limit: 3gb
1130 ;dw 0fa00h
1131 ;dw 000cch
1132
1133 ;dw 00000h ; User data descriptor
1134 ;dw 00000h ; base: 0h limit: 3gb
1135 ;dw 0f200h
1136 ;dw 000cch
1137
1138 ;dw 00000h
1139 ;dw 00000h
1140 ;dw 00000h
1141 ;dw 00000h
1142
1143 dw 0ffffh ; Kernel code descriptor
1144 dw 00000h ;
1145 dw 09a00h ; base 0h limit 4gb
1146 dw 000cfh
1147
1148 dw 0ffffh ; Kernel data descriptor
1149 dw 00000h ;
1150 dw 09200h ; base 0h limit 4gb
1151 dw 000cfh
1152
1153
1154 ;times NR_TASKS*8 db 0
1155
1156 _end:
1157
1158
1159