[source navigation] [diff markup] [identifier search] [freetext search] [file search]

Oldlinux Cross Reference
Linux/boot/setup.s

Version: [1.0] [0.99.11] [0.99] [0.98] [0.97] [0.96a] [0.95] [0.12] [0.11] [0.01]
Architecture: [i386]

  1 !
  2 !       setup.s         (C) 1991 Linus Torvalds
  3 !
  4 ! setup.s is responsible for getting the system data from the BIOS,
  5 ! and putting them into the appropriate places in system memory.
  6 ! both setup.s and system has been loaded by the bootblock.
  7 !
  8 ! This code asks the bios for memory/disk/other parameters, and
  9 ! puts them in a "safe" place: 0x90000-0x901FF, ie where the
 10 ! boot-block used to be. It is then up to the protected mode
 11 ! system to read them from there before the area is overwritten
 12 ! for buffer-blocks.
 13 !
 14 
 15 ! NOTE! These had better be the same as in bootsect.s!
 16 
 17 INITSEG  = 0x9000       ! we move boot here - out of the way
 18 SYSSEG   = 0x1000       ! system loaded at 0x10000 (65536).
 19 SETUPSEG = 0x9020       ! this is the current segment
 20 
 21 .globl begtext, begdata, begbss, endtext, enddata, endbss
 22 .text
 23 begtext:
 24 .data
 25 begdata:
 26 .bss
 27 begbss:
 28 .text
 29 
 30 entry start
 31 start:
 32 
 33 ! ok, the read went well so we get current cursor position and save it for
 34 ! posterity.
 35 
 36         mov     ax,#INITSEG     ! this is done in bootsect already, but...
 37         mov     ds,ax
 38         mov     ah,#0x03        ! read cursor pos
 39         xor     bh,bh
 40         int     0x10            ! save it in known place, con_init fetches
 41         mov     [0],dx          ! it from 0x90000.
 42 
 43 ! Get memory size (extended mem, kB)
 44 
 45         mov     ah,#0x88
 46         int     0x15
 47         mov     [2],ax
 48 
 49 ! Get video-card data:
 50 
 51         mov     ah,#0x0f
 52         int     0x10
 53         mov     [4],bx          ! bh = display page
 54         mov     [6],ax          ! al = video mode, ah = window width
 55 
 56 ! check for EGA/VGA and some config parameters
 57 
 58         mov     ah,#0x12
 59         mov     bl,#0x10
 60         int     0x10
 61         mov     [8],ax
 62         mov     [10],bx
 63         mov     [12],cx
 64 
 65 ! Get hd0 data
 66 
 67         mov     ax,#0x0000
 68         mov     ds,ax
 69         lds     si,[4*0x41]
 70         mov     ax,#INITSEG
 71         mov     es,ax
 72         mov     di,#0x0080
 73         mov     cx,#0x10
 74         rep
 75         movsb
 76 
 77 ! Get hd1 data
 78 
 79         mov     ax,#0x0000
 80         mov     ds,ax
 81         lds     si,[4*0x46]
 82         mov     ax,#INITSEG
 83         mov     es,ax
 84         mov     di,#0x0090
 85         mov     cx,#0x10
 86         rep
 87         movsb
 88 
 89 ! Check that there IS a hd1 :-)
 90 
 91         mov     ax,#0x01500
 92         mov     dl,#0x81
 93         int     0x13
 94         jc      no_disk1
 95         cmp     ah,#3
 96         je      is_disk1
 97 no_disk1:
 98         mov     ax,#INITSEG
 99         mov     es,ax
100         mov     di,#0x0090
101         mov     cx,#0x10
102         mov     ax,#0x00
103         rep
104         stosb
105 is_disk1:
106 
107 ! now we want to move to protected mode ...
108 
109         cli                     ! no interrupts allowed !
110 
111 ! first we move the system to it's rightful place
112 
113         mov     ax,#0x0000
114         cld                     ! 'direction'=0, movs moves forward
115 do_move:
116         mov     es,ax           ! destination segment
117         add     ax,#0x1000
118         cmp     ax,#0x9000
119         jz      end_move
120         mov     ds,ax           ! source segment
121         sub     di,di
122         sub     si,si
123         mov     cx,#0x8000
124         rep
125         movsw
126         jmp     do_move
127 
128 ! then we load the segment descriptors
129 
130 end_move:
131         mov     ax,#SETUPSEG    ! right, forgot this at first. didn't work :-)
132         mov     ds,ax
133         lidt    idt_48          ! load idt with 0,0
134         lgdt    gdt_48          ! load gdt with whatever appropriate
135 
136 ! that was painless, now we enable A20
137 
138         call    empty_8042
139         mov     al,#0xD1                ! command write
140         out     #0x64,al
141         call    empty_8042
142         mov     al,#0xDF                ! A20 on
143         out     #0x60,al
144         call    empty_8042
145 
146 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
147 ! we put them right after the intel-reserved hardware interrupts, at
148 ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
149 ! messed this up with the original PC, and they haven't been able to
150 ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
151 ! which is used for the internal hardware interrupts as well. We just
152 ! have to reprogram the 8259's, and it isn't fun.
153 
154         mov     al,#0x11                ! initialization sequence
155         out     #0x20,al                ! send it to 8259A-1
156         .word   0x00eb,0x00eb           ! jmp $+2, jmp $+2
157         out     #0xA0,al                ! and to 8259A-2
158         .word   0x00eb,0x00eb
159         mov     al,#0x20                ! start of hardware int's (0x20)
160         out     #0x21,al
161         .word   0x00eb,0x00eb
162         mov     al,#0x28                ! start of hardware int's 2 (0x28)
163         out     #0xA1,al
164         .word   0x00eb,0x00eb
165         mov     al,#0x04                ! 8259-1 is master
166         out     #0x21,al
167         .word   0x00eb,0x00eb
168         mov     al,#0x02                ! 8259-2 is slave
169         out     #0xA1,al
170         .word   0x00eb,0x00eb
171         mov     al,#0x01                ! 8086 mode for both
172         out     #0x21,al
173         .word   0x00eb,0x00eb
174         out     #0xA1,al
175         .word   0x00eb,0x00eb
176         mov     al,#0xFF                ! mask off all interrupts for now
177         out     #0x21,al
178         .word   0x00eb,0x00eb
179         out     #0xA1,al
180 
181 ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
182 ! need no steenking BIOS anyway (except for the initial loading :-).
183 ! The BIOS-routine wants lots of unnecessary data, and it's less
184 ! "interesting" anyway. This is how REAL programmers do it.
185 !
186 ! Well, now's the time to actually move into protected mode. To make
187 ! things as simple as possible, we do no register set-up or anything,
188 ! we let the gnu-compiled 32-bit programs do that. We just jump to
189 ! absolute address 0x00000, in 32-bit protected mode.
190 
191         mov     ax,#0x0001      ! protected mode (PE) bit
192         lmsw    ax              ! This is it!
193         jmpi    0,8             ! jmp offset 0 of segment 8 (cs)
194 
195 ! This routine checks that the keyboard command queue is empty
196 ! No timeout is used - if this hangs there is something wrong with
197 ! the machine, and we probably couldn't proceed anyway.
198 empty_8042:
199         .word   0x00eb,0x00eb
200         in      al,#0x64        ! 8042 status port
201         test    al,#2           ! is input buffer full?
202         jnz     empty_8042      ! yes - loop
203         ret
204 
205 gdt:
206         .word   0,0,0,0         ! dummy
207 
208         .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
209         .word   0x0000          ! base address=0
210         .word   0x9A00          ! code read/exec
211         .word   0x00C0          ! granularity=4096, 386
212 
213         .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
214         .word   0x0000          ! base address=0
215         .word   0x9200          ! data read/write
216         .word   0x00C0          ! granularity=4096, 386
217 
218 idt_48:
219         .word   0                       ! idt limit=0
220         .word   0,0                     ! idt base=0L
221 
222 gdt_48:
223         .word   0x800           ! gdt limit=2048, 256 GDT entries
224         .word   512+gdt,0x9     ! gdt base = 0X9xxxx
225         
226 .text
227 endtext:
228 .data
229 enddata:
230 .bss
231 endbss:

[source navigation] [diff markup] [identifier search] [freetext search] [file search]

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.