您的位置:首页 > 运维架构 > Linux

Linux/boot/bootsect.S

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