OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [i386/] [boot/] [bootsect.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
!
2
! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
3
! 0x7F00 is 0x7F000 bytes = 508kB, more than enough for current
4
! versions of linux which compress the kernel
5
!
6
#include 
7
SYSSIZE = DEF_SYSSIZE
8
!
9
!       bootsect.s              Copyright (C) 1991, 1992 Linus Torvalds
10
!       modified by Drew Eckhardt
11
!       modified by Bruce Evans (bde)
12
!
13
! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
14
! itself out of the way to address 0x90000, and jumps there.
15
!
16
! bde - should not jump blindly, there may be systems with only 512K low
17
! memory.  Use int 0x12 to get the top of memory, etc.
18
!
19
! It then loads 'setup' directly after itself (0x90200), and the system
20
! at 0x10000, using BIOS interrupts.
21
!
22
! NOTE! currently system is at most (8*65536-4096) bytes long. This should
23
! be no problem, even in the future. I want to keep it simple. This 508 kB
24
! kernel size should be enough, especially as this doesn't contain the
25
! buffer cache as in minix (and especially now that the kernel is
26
! compressed :-)
27
!
28
! The loader has been made as simple as possible, and continuous
29
! read errors will result in a unbreakable loop. Reboot by hand. It
30
! loads pretty fast by getting whole tracks at a time whenever possible.
31
 
32
.text
33
 
34
SETUPSECS = 4                           ! nr of setup-sectors
35
BOOTSEG   = 0x07C0                      ! original address of boot-sector
36
INITSEG   = DEF_INITSEG                 ! we move boot here - out of the way
37
SETUPSEG  = DEF_SETUPSEG                ! setup starts here
38
SYSSEG    = DEF_SYSSEG                  ! system loaded at 0x10000 (65536).
39
 
40
! ROOT_DEV & SWAP_DEV are now written by "build".
41
ROOT_DEV = 0
42
SWAP_DEV = 0
43
#ifndef SVGA_MODE
44
#define SVGA_MODE ASK_VGA
45
#endif
46
#ifndef RAMDISK
47
#define RAMDISK 0
48
#endif
49
#ifndef CONFIG_ROOT_RDONLY
50
#define CONFIG_ROOT_RDONLY 1
51
#endif
52
 
53
! ld86 requires an entry symbol. This may as well be the usual one.
54
.globl  _main
55
_main:
56
#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
57
        int     3
58
#endif
59
        mov     ax,#BOOTSEG
60
        mov     ds,ax
61
        mov     ax,#INITSEG
62
        mov     es,ax
63
        mov     cx,#256
64
        sub     si,si
65
        sub     di,di
66
        cld
67
        rep
68
        movsw
69
        jmpi    go,INITSEG
70
 
71
! ax and es already contain INITSEG
72
 
73
go:     mov     di,#0x4000-12   ! 0x4000 is arbitrary value >= length of
74
                                ! bootsect + length of setup + room for stack
75
                                ! 12 is disk parm size
76
 
77
! bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde).  We
78
! wouldn't have to worry about this if we checked the top of memory.  Also
79
! my BIOS can be configured to put the wini drive tables in high memory
80
! instead of in the vector table.  The old stack might have clobbered the
81
! drive table.
82
 
83
        mov     ds,ax
84
        mov     ss,ax           ! put stack at INITSEG:0x4000-12.
85
        mov     sp,di
86
/*
87
 *      Many BIOS's default disk parameter tables will not
88
 *      recognize multi-sector reads beyond the maximum sector number
89
 *      specified in the default diskette parameter tables - this may
90
 *      mean 7 sectors in some cases.
91
 *
92
 *      Since single sector reads are slow and out of the question,
93
 *      we must take care of this by creating new parameter tables
94
 *      (for the first disk) in RAM.  We will set the maximum sector
95
 *      count to 36 - the most we will encounter on an ED 2.88.
96
 *
97
 *      High doesn't hurt.  Low does.
98
 *
99
 *      Segments are as follows: ds=es=ss=cs - INITSEG,
100
 *              fs = 0, gs is unused.
101
 */
102
 
103
! cx contains 0 from rep movsw above
104
 
105
        mov     fs,cx
106
        mov     bx,#0x78                ! fs:bx is parameter table address
107
        push    ds
108
        seg fs
109
        lds     si,(bx)                 ! ds:si is source
110
 
111
        mov     cl,#6                   ! copy 12 bytes
112
        cld
113
        push    di
114
 
115
        rep
116
        movsw
117
 
118
        pop     di
119
        pop     ds
120
 
121
        movb    4(di),*36               ! patch sector count
122
 
123
        seg fs
124
        mov     (bx),di
125
        seg fs
126
        mov     2(bx),es
127
 
128
! load the setup-sectors directly after the bootblock.
129
! Note that 'es' is already set up.
130
! Also cx is 0 from rep movsw above.
131
 
132
load_setup:
133
        xor     ah,ah                   ! reset FDC
134
        xor     dl,dl
135
        int     0x13
136
 
137
        xor     dx, dx                  ! drive 0, head 0
138
        mov     cl,#0x02                ! sector 2, track 0
139
        mov     bx,#0x0200              ! address = 512, in INITSEG
140
        mov     ah,#0x02                ! service 2, nr of sectors
141
        mov     al,setup_sects          ! (assume all on head 0, track 0)
142
        int     0x13                    ! read it
143
        jnc     ok_load_setup           ! ok - continue
144
 
145
        push    ax                      ! dump error code
146
        call    print_nl
147
        mov     bp, sp
148
        call    print_hex
149
        pop     ax
150
 
151
        jmp     load_setup
152
 
153
ok_load_setup:
154
 
155
! Get disk drive parameters, specifically nr of sectors/track
156
 
157
#if 0
158
 
159
! bde - the Phoenix BIOS manual says function 0x08 only works for fixed
160
! disks.  It doesn't work for one of my BIOS's (1987 Award).  It was
161
! fatal not to check the error code.
162
 
163
        xor     dl,dl
164
        mov     ah,#0x08                ! AH=8 is get drive parameters
165
        int     0x13
166
        xor     ch,ch
167
#else
168
 
169
! It seems that there is no BIOS call to get the number of sectors.  Guess
170
! 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
171
! 15 if sector 15 can be read.  Otherwise guess 9.
172
 
173
        mov     si,#disksizes           ! table of sizes to try
174
 
175
probe_loop:
176
        lodsb
177
        cbw                             ! extend to word
178
        mov     sectors, ax
179
        cmp     si,#disksizes+4
180
        jae     got_sectors             ! if all else fails, try 9
181
        xchg    ax, cx                  ! cx = track and sector
182
        xor     dx, dx                  ! drive 0, head 0
183
        xor     bl, bl
184
        mov     bh,setup_sects
185
        inc     bh
186
        shl     bh,#1                   ! address after setup (es = cs)
187
        mov     ax,#0x0201              ! service 2, 1 sector
188
        int     0x13
189
        jc      probe_loop              ! try next value
190
 
191
#endif
192
 
193
got_sectors:
194
 
195
! Restore es
196
 
197
        mov     ax,#INITSEG
198
        mov     es,ax
199
 
200
! Print some inane message
201
 
202
        mov     ah,#0x03                ! read cursor pos
203
        xor     bh,bh
204
        int     0x10
205
 
206
        mov     cx,#9
207
        mov     bx,#0x0007              ! page 0, attribute 7 (normal)
208
        mov     bp,#msg1
209
        mov     ax,#0x1301              ! write string, move cursor
210
        int     0x10
211
 
212
! ok, we've written the message, now
213
! we want to load the system (at 0x10000)
214
 
215
        mov     ax,#SYSSEG
216
        mov     es,ax           ! segment of 0x010000
217
        call    read_it
218
        call    kill_motor
219
        call    print_nl
220
 
221
! After that we check which root-device to use. If the device is
222
! defined (!= 0), nothing is done and the given device is used.
223
! Otherwise, one of /dev/fd0H2880 (2,32) or /dev/PS0 (2,28) or /dev/at0 (2,8),
224
! depending on the number of sectors we pretend to know we have.
225
 
226
        seg cs
227
        mov     ax,root_dev
228
        or      ax,ax
229
        jne     root_defined
230
        seg cs
231
        mov     bx,sectors
232
        mov     ax,#0x0208              ! /dev/ps0 - 1.2Mb
233
        cmp     bx,#15
234
        je      root_defined
235
        mov     al,#0x1c                ! /dev/PS0 - 1.44Mb
236
        cmp     bx,#18
237
        je      root_defined
238
        mov     al,#0x20                ! /dev/fd0H2880 - 2.88Mb
239
        cmp     bx,#36
240
        je      root_defined
241
        mov     al,#0                   ! /dev/fd0 - autodetect
242
root_defined:
243
        seg cs
244
        mov     root_dev,ax
245
 
246
! after that (everything loaded), we jump to
247
! the setup-routine loaded directly after
248
! the bootblock:
249
 
250
        jmpi    0,SETUPSEG
251
 
252
! This routine loads the system at address 0x10000, making sure
253
! no 64kB boundaries are crossed. We try to load it as fast as
254
! possible, loading whole tracks whenever we can.
255
!
256
! in:   es - starting address segment (normally 0x1000)
257
!
258
sread:  .word 0                 ! sectors read of current track
259
head:   .word 0                 ! current head
260
track:  .word 0                 ! current track
261
 
262
read_it:
263
        mov     al,setup_sects
264
        inc     al
265
        mov     sread,al
266
        mov ax,es
267
        test ax,#0x0fff
268
die:    jne die                 ! es must be at 64kB boundary
269
        xor bx,bx               ! bx is starting address within segment
270
rp_read:
271
#ifdef __BIG_KERNEL__
272
#define CALL_HIGHLOAD_KLUDGE .word 0x1eff,0x220 ! call far * bootsect_kludge
273
                                ! NOTE: as86 can't assemble this
274
        CALL_HIGHLOAD_KLUDGE    ! this is within setup.S
275
#else
276
        mov ax,es
277
        sub ax,#SYSSEG
278
#endif
279
        cmp ax,syssize          ! have we loaded all yet?
280
        jbe ok1_read
281
        ret
282
ok1_read:
283
        mov ax,sectors
284
        sub ax,sread
285
        mov cx,ax
286
        shl cx,#9
287
        add cx,bx
288
        jnc ok2_read
289
        je ok2_read
290
        xor ax,ax
291
        sub ax,bx
292
        shr ax,#9
293
ok2_read:
294
        call read_track
295
        mov cx,ax
296
        add ax,sread
297
        cmp ax,sectors
298
        jne ok3_read
299
        mov ax,#1
300
        sub ax,head
301
        jne ok4_read
302
        inc track
303
ok4_read:
304
        mov head,ax
305
        xor ax,ax
306
ok3_read:
307
        mov sread,ax
308
        shl cx,#9
309
        add bx,cx
310
        jnc rp_read
311
        mov ax,es
312
        add ah,#0x10
313
        mov es,ax
314
        xor bx,bx
315
        jmp rp_read
316
 
317
read_track:
318
        pusha
319
        pusha
320
        mov     ax, #0xe2e      ! loading... message 2e = .
321
        mov     bx, #7
322
        int     0x10
323
        popa
324
 
325
        mov     dx,track
326
        mov     cx,sread
327
        inc     cx
328
        mov     ch,dl
329
        mov     dx,head
330
        mov     dh,dl
331
        and     dx,#0x0100
332
        mov     ah,#2
333
 
334
        push    dx                              ! save for error dump
335
        push    cx
336
        push    bx
337
        push    ax
338
 
339
        int     0x13
340
        jc      bad_rt
341
        add     sp, #8
342
        popa
343
        ret
344
 
345
bad_rt: push    ax                              ! save error code
346
        call    print_all                       ! ah = error, al = read
347
 
348
 
349
        xor ah,ah
350
        xor dl,dl
351
        int 0x13
352
 
353
 
354
        add     sp, #10
355
        popa
356
        jmp read_track
357
 
358
/*
359
 *      print_all is for debugging purposes.
360
 *      It will print out all of the registers.  The assumption is that this is
361
 *      called from a routine, with a stack frame like
362
 *      dx
363
 *      cx
364
 *      bx
365
 *      ax
366
 *      error
367
 *      ret <- sp
368
 *
369
*/
370
 
371
print_all:
372
        mov     cx, #5          ! error code + 4 registers
373
        mov     bp, sp
374
 
375
print_loop:
376
        push    cx              ! save count left
377
        call    print_nl        ! nl for readability
378
 
379
        cmp     cl, #5
380
        jae     no_reg          ! see if register name is needed
381
 
382
        mov     ax, #0xe05 + 'A - 1
383
        sub     al, cl
384
        int     0x10
385
 
386
        mov     al, #'X
387
        int     0x10
388
 
389
        mov     al, #':
390
        int     0x10
391
 
392
no_reg:
393
        add     bp, #2          ! next register
394
        call    print_hex       ! print it
395
        pop     cx
396
        loop    print_loop
397
        ret
398
 
399
print_nl:
400
        mov     ax, #0xe0d      ! CR
401
        int     0x10
402
        mov     al, #0xa        ! LF
403
        int     0x10
404
        ret
405
 
406
/*
407
 *      print_hex is for debugging purposes, and prints the word
408
 *      pointed to by ss:bp in hexadecimal.
409
*/
410
 
411
print_hex:
412
        mov     cx, #4          ! 4 hex digits
413
        mov     dx, (bp)        ! load word into dx
414
print_digit:
415
        rol     dx, #4          ! rotate so that lowest 4 bits are used
416
        mov     ax, #0xe0f      ! ah = request, al = mask for nybble
417
        and     al, dl
418
        add     al, #0x90       ! convert al to ascii hex (four instructions)
419
        daa
420
        adc     al, #0x40
421
        daa
422
        int     0x10
423
        loop    print_digit
424
        ret
425
 
426
 
427
/*
428
 * This procedure turns off the floppy drive motor, so
429
 * that we enter the kernel in a known state, and
430
 * don't have to worry about it later.
431
 */
432
kill_motor:
433
        push dx
434
        mov dx,#0x3f2
435
        xor al, al
436
        outb
437
        pop dx
438
        ret
439
 
440
sectors:
441
        .word 0
442
 
443
disksizes:
444
        .byte 36,18,15,9
445
 
446
msg1:
447
        .byte 13,10
448
        .ascii "Loading"
449
 
450
.org 497
451
setup_sects:
452
        .byte SETUPSECS
453
root_flags:
454
        .word CONFIG_ROOT_RDONLY
455
syssize:
456
        .word SYSSIZE
457
swap_dev:
458
        .word SWAP_DEV
459
ram_size:
460
        .word RAMDISK
461
vid_mode:
462
        .word SVGA_MODE
463
root_dev:
464
        .word ROOT_DEV
465
boot_flag:
466
        .word 0xAA55

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.