|
|
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.
1.1.1.2 root 31: *
1.1.1.3 ! root 32: * asbootblk.c,v 1.3 1993/05/22 08:02:07 cgd Exp
1.1 root 33: */
34:
35: #include "param.h"
36: #include "disklabel.h"
37: #include "i386/isa/asreg.h"
38:
39: /* RELOC should be defined with a -D flag to cc */
40:
41: #define SECOND_LEVEL_BOOT_START (RELOC + 0x400)
42: #define READ_SIZE 8192
43:
44: #define as_port 0x330
45: #define target 0
46:
47:
48: #define NBLOCKS (READ_SIZE / 512) /* how many logical blocks to read */
49:
50:
51: /* These are the parameters to pass to the second level boot */
52: #define dev 4 /* major device number of as driver in
53: i386/stand/conf.c and i386/i386/conf.c */
54: #define unit 0 /* partition number of root file system */
55: #define off 0 /* block offset of root file system */
56:
57: /* inline i/o borrowed from Roell X server */
58: static __inline__ void
59: outb(port, val)
60: short port;
61: char val;
62: {
63: __asm__ volatile("outb %%al, %1" : :"a" (val), "d" (port));
64: }
65:
66: static __inline__ unsigned int
67: inb(port)
68: short port;
69: {
70: unsigned int ret;
71: __asm__ volatile("xorl %%eax, %%eax; inb %1, %%al"
72: : "=a" (ret) : "d" (port));
73: return ret;
74: }
75:
76: /* this code is linked at 0x7c00 and is loaded there by the BIOS */
77:
78: asm ("
79: /* we're running in 16 real mode, so normal assembly doesn't work */
80: bootbase:
81: /* interrupts off */
82: cli
83:
84: /* load gdt */
85: .byte 0x2e,0x0f,0x01,0x16 /* lgdt %cs:$imm */
86: .word _gdtarg + 2
87:
88: /* turn on protected mode */
89: smsw %ax
90: orb $1,%al
91: lmsw %ax
92:
93: /* flush prefetch queue and reload %cs */
94: .byte 0xea /* ljmp $8, flush */
95: .word flush
96: .word 8
97:
98: flush:
99: /* now running in 32 bit mode */
100: movl $0x10,%eax
101: movl %ax,%ds
102: movl %ax,%es
103: movl %ax,%ss
104: movl $0x7c00,%esp
105: call _main
106: "); /* end of asm */
107:
108: const char gdt[] = {
109: 0, 0, 0, 0, 0, 0, 0, 0,
110: 0xff, 0xff, 0, 0, 0, 0x9f, 0xcf, 0, /* code segment */
111: 0xff, 0xff, 0, 0, 0, 0x93, 0xcf, 0, /* data segment */
112: };
113:
114: const struct {
115: short filler;
116: short size;
117: const char *gdt;
118: } gdtarg = { 0, sizeof gdt - 1, gdt };
119:
120: #define CRTBASE ((char *)0xb8000)
121: #define CHECKPOINT(x) (CRTBASE[0] = x)
122:
123: volatile struct mailbox_entry mailbox[2];
124: const char ccb[] = {
1.1.1.2 root 125: 0, /* opcode: normal read/write */
1.1 root 126: (target << 5) | 8, /* target num and read flag */
127: 10, /* scsi cmd len */
128: 1, /* no automatic request for sense */
129: READ_SIZE >> 16, /* data length */
130: READ_SIZE >> 8,
131: READ_SIZE,
132: RELOC >> 16, /* data pointer */
133: RELOC >> 8,
134: RELOC,
135: 0, 0, 0, /* link pointer */
136: 0, /* link id */
137: 0, /* host status */
138: 0, /* target status */
139: 0, 0, /* reserved */
140:
141: /* scsi cdb */
142: 0x28, /* read opcode */
143: 0, /* logical unit number */
144: 0, 0, 0, 0, /* logical block address */
145: 0, /* reserved */
146: 0, NBLOCKS, /* transfer length */
147: 0, /* link control */
148: };
149:
150: int (*f)();
151:
152: main ()
153: {
154: int i;
155: extern char edata[], end[];
156: char volatile * volatile p, *q;
157: int physaddr;
158:
159: CHECKPOINT ('a');
160:
161: /* clear bss */
162: for (p = edata; p < end; p++)
163: *p = 0;
164:
165: f = (int (*)())SECOND_LEVEL_BOOT_START;
166:
167: /* dma setup: see page 5-31 in the Adaptech manual */
168: /* this knows we are using drq 5 */
169: outb (0xd6, 0xc1);
170: outb (0xd4, 0x01);
171:
172: outb (as_port + AS_CONTROL, AS_CONTROL_SRST);
173:
174: /* delay a little */
175: inb (0x84);
176:
177: while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE))
178: ;
179:
180: CHECKPOINT ('b');
181:
182: as_put_byte (AS_CMD_MAILBOX_INIT);
183: as_put_byte (1); /* one mailbox out, one in */
184: as_put_byte ((int)mailbox >> 16);
185: as_put_byte ((int)mailbox >> 8);
186: as_put_byte ((int)mailbox);
187:
188: while (inb (as_port + AS_STATUS) & AS_STATUS_INIT)
189: ;
190:
191: CHECKPOINT ('c');
192:
193: mailbox[0].msb = (int)ccb >> 16;
194: mailbox[0].mid = (int)ccb >> 8;
195: mailbox[0].lsb = (int)ccb;
196: mailbox[0].cmd = 1;
197:
198: as_put_byte (AS_CMD_START_SCSI_COMMAND);
199:
200: /* wait for done */
201: while (mailbox[1].cmd == 0)
202: ;
203:
204: CHECKPOINT ('d');
205:
206: if (mailbox[1].cmd != 1) {
207: /* some error */
208: CHECKPOINT ('X');
209: while (1);
210: }
211:
212: CHECKPOINT ('e');
213:
214: /* the optimazation that gcc uses when it knows we are jumpping
215: * to a constant address is broken, so we have to use a variable
216: * here
217: */
218: (*f)(dev, unit, off);
219: }
220:
221: int
222: as_put_byte (val)
223: int val;
224: {
225: while (inb (as_port + AS_STATUS) & AS_STATUS_CDF)
226: ;
227: outb (as_port + AS_DATA_OUT, val);
228: }
229:
230: asm ("
231: ebootblkcode:
232: . = 510
233: .byte 0x55
234: .byte 0xaa
235: ebootblk: /* MUST BE EXACTLY 0x200 BIG FOR SURE */
236: ");
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.