1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)fdbootblk.c 7.2 (Berkeley) 05/04/91 11 */ 12 13 /* 14 * fdbootblk.s: 15 * Written 10/6/90 by William F. Jolitz 16 * Initial block boot for AT/386 with typical stupid NEC controller 17 * Works only with 3.5 inch diskettes that have 16 or greater sectors/side 18 * 19 * Goal is to read in sucessive 7.5Kbytes of bootstrap to 20 * execute. 21 * 22 * No attempt is made to handle disk errors. 23 */ 24 /*#include "/sys/i386/isa/isa.h" 25 #include "/sys/i386/isa/fdreg.h"*/ 26 #define NOP jmp 1f ; nop ; 1: 27 #define BIOSRELOC 0x7c00 28 #define start 0x70400 29 30 /* step 0 force descriptors to bottom of address space */ 31 32 .byte 0xfa,0xb8,0x30,0x00,0x8e,0xd0,0xbc,0x00,0x01 #ll fb 33 34 xorl %eax,%eax 35 movl %ax,%ds 36 movl %ax,%es 37 38 /* step 1 load new descriptor table */ 39 40 .byte 0x2E,0x0F,1,0x16 41 .word BIOSRELOC+0x4a #GDTptr 42 # word aword cs lgdt GDTptr 43 44 /* step 2 turn on protected mode */ 45 46 smsw %ax 47 orb $1,%al 48 lmsw %ax 49 jmp 1f 50 nop 51 52 /* step 3 reload segment descriptors */ 53 54 1: 55 xorl %eax,%eax 56 movb $0x10,%al 57 movl %ax,%ds 58 movl %ax,%es 59 movl %ax,%ss 60 word 61 ljmp $0x8,$ BIOSRELOC+0x59 /* would be nice if .-RELOC+0x7c00 worked */ 62 63 /* Global Descriptor Table contains three descriptors: 64 * 0x00: Null: not used 65 * 0x08: Code: code segment starts at 0 and extents for 4 gigabytes 66 * 0x10: Data: data segment starts at 0 and extends for 4 gigabytes 67 * (overlays code) 68 */ 69 GDT: 70 NullDesc: .word 0,0,0,0 # null descriptor - not used 71 CodeDesc: .word 0xFFFF # limit at maximum: (bits 15:0) 72 .byte 0,0,0 # base at 0: (bits 23:0) 73 .byte 0x9f # present/priv level 0/code/conforming/readable 74 .byte 0xcf # page granular/default 32-bit/limit(bits 19:16) 75 .byte 0 # base at 0: (bits 31:24) 76 DataDesc: .word 0xFFFF # limit at maximum: (bits 15:0) 77 .byte 0,0,0 # base at 0: (bits 23:0) 78 .byte 0x93 # present/priv level 0/data/expand-up/writeable 79 .byte 0xcf # page granular/default 32-bit/limit(bits 19:16) 80 .byte 0 # base at 0: (bits 31:24) 81 82 /* Global Descriptor Table pointer 83 * contains 6-byte pointer information for LGDT 84 */ 85 GDTptr: .word 0x17 # limit to three 8 byte selectors(null,code,data) 86 .long BIOSRELOC+0x32 # GDT -- arrgh, gas again! 87 readcmd: .byte 0xe6,0,0,0,0,2,18,0x1b,0xff 88 89 /* step 4 relocate to final bootstrap address. */ 90 reloc: 91 movl $ BIOSRELOC,%esi 92 movl $ RELOC,%edi 93 movl $512,%ecx 94 rep 95 movsb 96 pushl $dodisk 97 ret 98 99 /* step 5 load remaining 15 sectors off disk */ 100 dodisk: 101 movl $0x70200,%edi 102 xorl %ebx,%ebx 103 incb %bl 104 incb %bl 105 movb $0x20,%al # do a eoi 106 outb %al,$0x20 107 108 NOP 109 movb $0x07,%al 110 outb %al,$0x21 111 NOP 112 8: 113 movb %bl,readcmd+4 114 movl %edi,%ecx 115 116 /* Set read/write bytes */ 117 xorl %edx,%edx 118 movb $0x0c,%dl # outb(0xC,0x46); outb(0xB,0x46); 119 movb $0x46,%al 120 outb %al,%dx 121 NOP 122 decb %dx 123 outb %al,%dx 124 125 /* Send start address */ 126 movb $0x04,%dl # outb(0x4, addr); 127 movb %cl,%al 128 outb %al,%dx 129 NOP 130 movb %ch,%al # outb(0x4, addr>>8); 131 outb %al,%dx 132 NOP 133 rorl $8,%ecx # outb(0x81, addr>>16); 134 movb %ch,%al 135 outb %al,$0x81 136 NOP 137 138 /* Send count */ 139 movb $0x05,%dl # outb(0x5, 0); 140 xorl %eax,%eax 141 outb %al,%dx 142 NOP 143 movb $2,%al # outb(0x5,2); 144 outb %al,%dx 145 NOP 146 147 /* set channel 2 */ 148 # movb $2,%al # outb(0x0A,2); 149 outb %al,$0x0A 150 NOP 151 152 /* issue read command to fdc */ 153 movw $0x3f4,%dx 154 movl $readcmd,%esi 155 xorl %ecx,%ecx 156 movb $9,%cl 157 158 2: inb %dx,%al 159 NOP 160 testb $0x80,%al 161 jz 2b 162 163 incb %dx 164 movl (%esi),%al 165 outb %al,%dx 166 NOP 167 incl %esi 168 decb %dx 169 loop 2b 170 171 /* watch the icu looking for an interrupt signalling completion */ 172 xorl %edx,%edx 173 movb $0x20,%dl 174 2: movb $0xc,%al 175 outb %al,%dx 176 NOP 177 inb %dx,%al 178 NOP 179 andb $0x7f,%al 180 cmpb $6,%al 181 jne 2b 182 movb $0x20,%al # do a eoi 183 outb %al,%dx 184 NOP 185 186 movl $0x3f4,%edx 187 xorl %ecx,%ecx 188 movb $7,%cl 189 2: inb %dx,%al 190 NOP 191 andb $0xC0,%al 192 cmpb $0xc0,%al 193 jne 2b 194 incb %dx 195 inb %dx,%al 196 decb %dx 197 loop 2b 198 199 /* extract the status bytes after the read. must we do this? */ 200 addw $0x200,%edi # next addr to load to 201 incb %bl 202 cmpb $16,%bl 203 jle 8b 204 205 /* for clever bootstrap, dig out boot unit and cylinder */ 206 pushl $0 207 pushl $0 208 209 /* fd controller is major device 2 */ 210 pushl $2 /* dev */ 211 212 /* sorry, no flags at this point! */ 213 214 pushl $ start 215 ret /* main (dev, unit, off) */ 216 217 ebootblkcode: 218 219 /* remaining space usable for a disk label */ 220 221 .space 510-310 /* would be nice if .space 512-2-. worked */ 222 .word 0xaa55 /* signature -- used by BIOS ROM */ 223 224 ebootblk: /* MUST BE EXACTLY 0x200 BIG FOR SURE */ 225