|
|
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: ");
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.