Minor fix in Chapter 3 - PMode
[thunix.git] / boot / bootsect.s
blob2f39994a33bf38d992601d197b410d5c3843bd1b
1 ##*******************************************************************************
2 ## The first job of OS that load the bootsector of flopy is done here. *
3 ## Nothing speciall here,BIOS will auto load the first sector called *
4 ## *
5 ## bootsector, and then the loaded sector will load our OS kernel that *
6 ## just behined the bootsector at address 0x10000. *
7 ## *
8 ## After that's been done, we move the kernel again to physic address *
9 ## 0x0000, the start address of memory, 'cause we don't need BIOS any more. *
10 ## But that's a litter unsafe, we haven't finished our interrupt handler *
11 ## yet. But this will be done just later, and now we just block all of the *
12 ## interrupts by cli. Wish GOD bless us. :) *
13 ## *
14 ## And will move the GDT base to specified address,too. *
15 ## After that's all been done, it's the time switch into PM now. *
16 ## We do it first by enable A20 line, so that we call access lagre memory *
17 ## here is 4G. Then load GDT structer, set the PM flag of CR0 register, and *
18 ## last do a far jump to Protect Mode. *
19 ## *
20 ## Copyright (C) 2007-2008 Aleaxander *
21 ## Email: Aleaxander@gmail.com *
22 ##*******************************************************************************
23 .text
24 .globl start
25 .include "kernel.inc"
26 .code16
27 start:
28 jmpl $0x0, $code
29 gdt:
30 .quad 0x0000000000000000 # null descriptor
31 .quad 0x00cf9a000000ffff # cs
32 .quad 0x00cf92000000ffff # ds
33 .quad 0x0000000000000000 # sys
34 .quad 0x0000000000000000 # reserved for tss0
35 .quad 0x0000000000000000 # reserved for ldt0
36 .quad 0x0000000000000000 # reserved for tss1
37 .quad 0x0000000000000000 # reserved for ldt1
38 .quad 0x0000000000000000 # reserved for tss2
39 .quad 0x0000000000000000 # reserved for ldt2
40 .fill 22,8,0
41 gdt_48:
42 .word .-gdt-1
43 .long GDT_ADDR
44 code:
45 xorw %ax, %ax
46 movw %ax, %ds # ds = 0x0000
47 movw %ax, %ss # stack segment = 0x0000
48 movw $0x1000,%sp # arbitrary value
49 # used before pmode
51 ## read rest of kernel to 0x10000
52 movw $0x1000,%ax
53 movw %ax, %es
54 xorw %bx, %bx # es:bs destination address
55 movw $KERNEL_SECT,%cx
56 movw $1, %si # 0 is boot sector
57 rd_kern:
58 call read_sect
59 addw $512, %bx
60 incw %si
61 loop rd_kern
63 cli
65 ## move first 512 bytes of kernel to 0x0000
66 ## it will move rest of kernel to 0x0200,
67 ## that is, next to this sector
68 cld
69 movw $0x1000,%ax
70 movw %ax, %ds
71 movw $0x0000,%ax
72 movw %ax, %es
73 xorw %si, %si
74 xorw %di, %di
75 movw $512>>2,%cx
76 rep
77 movsl
81 xorw %ax, %ax
82 movw %ax, %ds # reset ds to 0x0000
83 ## move gdt
84 movw $GDT_ADDR>>4,%ax
85 movw %ax, %es
86 movw $gdt, %si
87 xorw %di, %di
88 movw $GDT_SIZE>>2,%cx
89 rep
90 movsl
92 enable_a20:
93 inb $0x64, %al
94 testb $0x2, %al
95 jnz enable_a20
96 movb $0xdf, %al
97 outb %al, $0x64
99 lgdt gdt_48
101 ## enter pmode
102 movl %cr0, %eax
103 orl $0x1, %eax
104 movl %eax, %cr0
108 ljmp $CODE_SEL, $0x0
110 ## in: ax: LBA address, starts from 0
111 ## es:bx address for reading sector
112 read_sect:
113 pushw %ax
114 pushw %cx
115 pushw %dx
116 pushw %bx
118 movw %si, %ax
119 xorw %dx, %dx
120 movw $18, %bx # 18 sectors per track
121 # for floppy disk
122 divw %bx
123 incw %dx
124 movb %dl, %cl # cl=sector number
125 xorw %dx, %dx
126 movw $2, %bx # 2 headers per track
127 # for floppy disk
128 divw %bx
130 movb %dl, %dh # head
131 xorb %dl, %dl # driver
132 movb %al, %ch # cylinder
133 popw %bx # save to es:bx
134 rp_read:
135 movb $0x1, %al # read 1 sector
136 movb $0x2, %ah
137 int $0x13
138 jc rp_read
139 popw %dx
140 popw %cx
141 popw %ax
144 .org 0x1fe, 0x90
145 .word 0xaa55 # bootsector flag