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