Annotation of Net2/arch/i386/stand/asbootblk.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * sys/i386/stand/asbootblk.c
        !             3:  *
        !             4:  * Boot block for Adaptech 1542 SCSI
        !             5:  *
        !             6:  * April 10, 1992
        !             7:  * Pace Willisson
        !             8:  * [email protected]
        !             9:  *
        !            10:  * Placed in the public domain with NO WARRANTIES, not even the
        !            11:  * implied warranties for MERCHANTABILITY or FITNESS FOR A 
        !            12:  * PARTICULAR PURPOSE.
        !            13:  *
        !            14:  * To compile:
        !            15:  *
        !            16:  *     cc -O -c -DRELOC=0x70000 asbootblk.c
        !            17:  *     ld -N -T 7c00 asbootblk.o
        !            18:  *
        !            19:  * This should result in a file with 512 bytes of text and no initialized 
        !            20:  * data.  Strip the 32 bit header and place in block 0.
        !            21:  *
        !            22:  * When run, this program copies at least the first 8 blocks of SCSI
        !            23:  * target 0 to the address specified by RELOC, then jumps to the
        !            24:  * address RELOC+1024 (skipping the boot block and disk label).  Usually,
        !            25:  * disks have 512 bytes per block, but I don't think they ever have
        !            26:  * less, and it wont hurt if they are bigger, as long as RELOC + 8*SIZE
        !            27:  * is less than 0xa0000.
        !            28:  *
        !            29:  * This bootblock does not support fdisk partitions, and can only be used
        !            30:  * as the master boot block.
        !            31:  */
        !            32: 
        !            33: #include "param.h"
        !            34: #include "disklabel.h"
        !            35: #include "i386/isa/asreg.h"
        !            36: 
        !            37: /* RELOC should be defined with a -D flag to cc */
        !            38: 
        !            39: #define SECOND_LEVEL_BOOT_START (RELOC + 0x400)
        !            40: #define READ_SIZE 8192
        !            41: 
        !            42: #define as_port 0x330
        !            43: #define target 0
        !            44: 
        !            45: 
        !            46: #define NBLOCKS (READ_SIZE / 512) /* how many logical blocks to read */
        !            47: 
        !            48: 
        !            49: /* These are the parameters to pass to the second level boot */
        !            50: #define dev 4 /* major device number of as driver in
        !            51:                 i386/stand/conf.c and i386/i386/conf.c */
        !            52: #define unit 0 /* partition number of root file system */
        !            53: #define off 0 /* block offset of root file system */
        !            54: 
        !            55: /* inline i/o borrowed from Roell X server */
        !            56: static __inline__ void
        !            57: outb(port, val)
        !            58: short port;
        !            59: char val;
        !            60: {
        !            61:    __asm__ volatile("outb %%al, %1" : :"a" (val), "d" (port));
        !            62: }
        !            63: 
        !            64: static __inline__ unsigned int
        !            65: inb(port)
        !            66: short port;
        !            67: {
        !            68:    unsigned int ret;
        !            69:    __asm__ volatile("xorl %%eax, %%eax; inb %1, %%al"
        !            70:                    : "=a" (ret) : "d" (port));
        !            71:    return ret;
        !            72: }
        !            73: 
        !            74: /* this code is linked at 0x7c00 and is loaded there by the BIOS */
        !            75: 
        !            76: asm ("
        !            77:        /* we're running in 16 real mode, so normal assembly doesn't work */
        !            78: bootbase:
        !            79:        /* interrupts off */
        !            80:        cli
        !            81: 
        !            82:        /* load gdt */
        !            83:        .byte 0x2e,0x0f,0x01,0x16 /* lgdt %cs:$imm */
        !            84:        .word _gdtarg + 2
        !            85: 
        !            86:        /* turn on protected mode */
        !            87:        smsw    %ax
        !            88:        orb     $1,%al
        !            89:        lmsw    %ax
        !            90: 
        !            91:        /* flush prefetch queue and reload %cs */
        !            92:        .byte 0xea /* ljmp $8, flush */
        !            93:        .word flush
        !            94:        .word 8
        !            95: 
        !            96: flush:
        !            97:        /* now running in 32 bit mode */
        !            98:        movl    $0x10,%eax
        !            99:        movl    %ax,%ds
        !           100:        movl    %ax,%es
        !           101:        movl    %ax,%ss
        !           102:        movl    $0x7c00,%esp
        !           103:        call    _main
        !           104: "); /* end of asm */
        !           105: 
        !           106: const char gdt[] = {
        !           107:        0, 0, 0, 0, 0, 0, 0, 0,
        !           108:        0xff, 0xff, 0, 0, 0, 0x9f, 0xcf, 0, /* code segment */
        !           109:        0xff, 0xff, 0, 0, 0, 0x93, 0xcf, 0, /* data segment */
        !           110: };
        !           111: 
        !           112: const struct {
        !           113:        short filler;
        !           114:        short size;
        !           115:        const char *gdt;
        !           116: } gdtarg = { 0, sizeof gdt - 1, gdt };
        !           117: 
        !           118: #define CRTBASE ((char *)0xb8000)
        !           119: #define CHECKPOINT(x) (CRTBASE[0] = x)
        !           120: 
        !           121: volatile struct mailbox_entry mailbox[2];
        !           122: const char ccb[] = {
        !           123:        3, /* opcode: normal read/write */
        !           124:        (target << 5) | 8, /* target num and read flag */
        !           125:        10, /* scsi cmd len */
        !           126:        1, /* no automatic request for sense */
        !           127:        READ_SIZE >> 16, /* data length */
        !           128:        READ_SIZE >> 8,
        !           129:        READ_SIZE,
        !           130:        RELOC >> 16, /* data pointer */
        !           131:        RELOC >> 8,
        !           132:        RELOC,
        !           133:        0, 0, 0, /* link pointer */
        !           134:        0, /* link id */
        !           135:        0, /* host status */
        !           136:        0, /* target status */
        !           137:        0, 0, /* reserved */
        !           138: 
        !           139:        /* scsi cdb */
        !           140:        0x28, /* read opcode */
        !           141:        0, /* logical unit number */
        !           142:        0, 0, 0, 0, /* logical block address */
        !           143:        0,      /* reserved */
        !           144:        0, NBLOCKS, /* transfer length */
        !           145:        0, /* link control */
        !           146: };
        !           147: 
        !           148: int (*f)();
        !           149: 
        !           150: main ()
        !           151: {
        !           152:        int i;
        !           153:        extern char edata[], end[];
        !           154:        char volatile * volatile p, *q;
        !           155:        int physaddr;
        !           156: 
        !           157:        CHECKPOINT ('a');
        !           158: 
        !           159:        /* clear bss */
        !           160:        for (p = edata; p < end; p++)
        !           161:                *p = 0;
        !           162: 
        !           163:        f = (int (*)())SECOND_LEVEL_BOOT_START;
        !           164: 
        !           165:        /* dma setup: see page 5-31 in the Adaptech manual */
        !           166:        /* this knows we are using drq 5 */
        !           167:        outb (0xd6, 0xc1);
        !           168:        outb (0xd4, 0x01);
        !           169: 
        !           170:        outb (as_port + AS_CONTROL, AS_CONTROL_SRST);
        !           171: 
        !           172:        /* delay a little */
        !           173:        inb (0x84);
        !           174:        
        !           175:        while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE))
        !           176:                ;
        !           177: 
        !           178:        CHECKPOINT ('b');
        !           179: 
        !           180:        as_put_byte (AS_CMD_MAILBOX_INIT);
        !           181:        as_put_byte (1); /* one mailbox out, one in */
        !           182:        as_put_byte ((int)mailbox >> 16);
        !           183:        as_put_byte ((int)mailbox >> 8);
        !           184:        as_put_byte ((int)mailbox);
        !           185: 
        !           186:        while (inb (as_port + AS_STATUS) & AS_STATUS_INIT)
        !           187:                ;
        !           188: 
        !           189:        CHECKPOINT ('c');
        !           190: 
        !           191:        mailbox[0].msb = (int)ccb >> 16;
        !           192:        mailbox[0].mid = (int)ccb >> 8;
        !           193:        mailbox[0].lsb = (int)ccb;
        !           194:        mailbox[0].cmd = 1;
        !           195: 
        !           196:        as_put_byte (AS_CMD_START_SCSI_COMMAND);
        !           197: 
        !           198:        /* wait for done */
        !           199:        while (mailbox[1].cmd == 0)
        !           200:                ;
        !           201: 
        !           202:        CHECKPOINT ('d');
        !           203: 
        !           204:        if (mailbox[1].cmd != 1) {
        !           205:                /* some error */
        !           206:                CHECKPOINT ('X');
        !           207:                while (1);
        !           208:        }
        !           209: 
        !           210:        CHECKPOINT ('e');
        !           211: 
        !           212:        /* the optimazation that gcc uses when it knows we are jumpping
        !           213:         * to a constant address is broken, so we have to use a variable 
        !           214:         * here
        !           215:         */
        !           216:        (*f)(dev, unit, off);
        !           217: }
        !           218: 
        !           219: int
        !           220: as_put_byte (val)
        !           221: int val;
        !           222: {
        !           223:        while (inb (as_port + AS_STATUS) & AS_STATUS_CDF)
        !           224:                ;
        !           225:        outb (as_port + AS_DATA_OUT, val);
        !           226: }
        !           227: 
        !           228: asm ("
        !           229: ebootblkcode:
        !           230:        . = 510
        !           231:        .byte 0x55
        !           232:        .byte 0xaa
        !           233: ebootblk:                      /* MUST BE EXACTLY 0x200 BIG FOR SURE */
        !           234: ");

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.