|
|
1.1.1.2 ! root 1: ! ! 2: ! setup.s (C) 1991 Linus Torvalds ! 3: ! ! 4: ! setup.s is responsible for getting the system data from the BIOS, ! 5: ! and putting them into the appropriate places in system memory. ! 6: ! both setup.s and system has been loaded by the bootblock. ! 7: ! ! 8: ! This code asks the bios for memory/disk/other parameters, and ! 9: ! puts them in a "safe" place: 0x90000-0x901FF, ie where the ! 10: ! boot-block used to be. It is then up to the protected mode ! 11: ! system to read them from there before the area is overwritten ! 12: ! for buffer-blocks. ! 13: ! ! 14: ! 15: ! NOTE! These had better be the same as in bootsect.s! ! 16: ! 17: INITSEG = 0x9000 ! we move boot here - out of the way ! 18: SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). ! 19: SETUPSEG = 0x9020 ! this is the current segment 1.1 root 20: 21: .globl begtext, begdata, begbss, endtext, enddata, endbss 22: .text 23: begtext: 24: .data 25: begdata: 26: .bss 27: begbss: 28: .text 29: 30: entry start 31: start: 32: 1.1.1.2 ! root 33: ! ok, the read went well so we get current cursor position and save it for ! 34: ! posterity. 1.1 root 35: 1.1.1.2 ! root 36: mov ax,#INITSEG ! this is done in bootsect already, but... 1.1 root 37: mov ds,ax 1.1.1.2 ! root 38: mov ah,#0x03 ! read cursor pos 1.1 root 39: xor bh,bh 1.1.1.2 ! root 40: int 0x10 ! save it in known place, con_init fetches ! 41: mov [0],dx ! it from 0x90000. 1.1 root 42: 1.1.1.2 ! root 43: ! Get memory size (extended mem, kB) 1.1 root 44: 45: mov ah,#0x88 46: int 0x15 47: mov [2],ax 48: 1.1.1.2 ! root 49: ! Get video-card data: ! 50: ! 51: mov ah,#0x0f ! 52: int 0x10 ! 53: mov [4],bx ! bh = display page ! 54: mov [6],ax ! al = video mode, ah = window width ! 55: ! 56: ! check for EGA/VGA and some config parameters ! 57: ! 58: mov ah,#0x12 ! 59: mov bl,#0x10 ! 60: int 0x10 ! 61: mov [8],ax ! 62: mov [10],bx ! 63: mov [12],cx ! 64: ! 65: ! Get hd0 data 1.1 root 66: 67: mov ax,#0x0000 68: mov ds,ax 69: lds si,[4*0x41] 70: mov ax,#INITSEG 71: mov es,ax 72: mov di,#0x0080 73: mov cx,#0x10 74: rep 75: movsb 76: 1.1.1.2 ! root 77: ! Get hd1 data 1.1 root 78: 79: mov ax,#0x0000 80: mov ds,ax 81: lds si,[4*0x46] 82: mov ax,#INITSEG 83: mov es,ax 84: mov di,#0x0090 85: mov cx,#0x10 86: rep 87: movsb 88: 1.1.1.2 ! root 89: ! Check that there IS a hd1 :-) 1.1 root 90: 91: mov ax,#0x01500 92: mov dl,#0x81 93: int 0x13 94: jc no_disk1 95: cmp ah,#3 96: je is_disk1 97: no_disk1: 98: mov ax,#INITSEG 99: mov es,ax 100: mov di,#0x0090 101: mov cx,#0x10 102: mov ax,#0x00 103: rep 104: stosb 105: is_disk1: 106: 1.1.1.2 ! root 107: ! now we want to move to protected mode ... 1.1 root 108: 1.1.1.2 ! root 109: cli ! no interrupts allowed ! 1.1 root 110: 1.1.1.2 ! root 111: ! first we move the system to it's rightful place 1.1 root 112: 113: mov ax,#0x0000 1.1.1.2 ! root 114: cld ! 'direction'=0, movs moves forward 1.1 root 115: do_move: 1.1.1.2 ! root 116: mov es,ax ! destination segment 1.1 root 117: add ax,#0x1000 118: cmp ax,#0x9000 119: jz end_move 1.1.1.2 ! root 120: mov ds,ax ! source segment 1.1 root 121: sub di,di 122: sub si,si 123: mov cx,#0x8000 124: rep 125: movsw 126: jmp do_move 127: 1.1.1.2 ! root 128: ! then we load the segment descriptors 1.1 root 129: 130: end_move: 1.1.1.2 ! root 131: mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-) 1.1 root 132: mov ds,ax 1.1.1.2 ! root 133: lidt idt_48 ! load idt with 0,0 ! 134: lgdt gdt_48 ! load gdt with whatever appropriate 1.1 root 135: 1.1.1.2 ! root 136: ! that was painless, now we enable A20 1.1 root 137: 138: call empty_8042 1.1.1.2 ! root 139: mov al,#0xD1 ! command write 1.1 root 140: out #0x64,al 141: call empty_8042 1.1.1.2 ! root 142: mov al,#0xDF ! A20 on 1.1 root 143: out #0x60,al 144: call empty_8042 145: 1.1.1.2 ! root 146: ! well, that went ok, I hope. Now we have to reprogram the interrupts :-( ! 147: ! we put them right after the intel-reserved hardware interrupts, at ! 148: ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really ! 149: ! messed this up with the original PC, and they haven't been able to ! 150: ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f, ! 151: ! which is used for the internal hardware interrupts as well. We just ! 152: ! have to reprogram the 8259's, and it isn't fun. ! 153: ! 154: mov al,#0x11 ! initialization sequence ! 155: out #0x20,al ! send it to 8259A-1 ! 156: .word 0x00eb,0x00eb ! jmp $+2, jmp $+2 ! 157: out #0xA0,al ! and to 8259A-2 1.1 root 158: .word 0x00eb,0x00eb 1.1.1.2 ! root 159: mov al,#0x20 ! start of hardware int's (0x20) 1.1 root 160: out #0x21,al 161: .word 0x00eb,0x00eb 1.1.1.2 ! root 162: mov al,#0x28 ! start of hardware int's 2 (0x28) 1.1 root 163: out #0xA1,al 164: .word 0x00eb,0x00eb 1.1.1.2 ! root 165: mov al,#0x04 ! 8259-1 is master 1.1 root 166: out #0x21,al 167: .word 0x00eb,0x00eb 1.1.1.2 ! root 168: mov al,#0x02 ! 8259-2 is slave 1.1 root 169: out #0xA1,al 170: .word 0x00eb,0x00eb 1.1.1.2 ! root 171: mov al,#0x01 ! 8086 mode for both 1.1 root 172: out #0x21,al 173: .word 0x00eb,0x00eb 174: out #0xA1,al 175: .word 0x00eb,0x00eb 1.1.1.2 ! root 176: mov al,#0xFF ! mask off all interrupts for now 1.1 root 177: out #0x21,al 178: .word 0x00eb,0x00eb 179: out #0xA1,al 180: 1.1.1.2 ! root 181: ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't ! 182: ! need no steenking BIOS anyway (except for the initial loading :-). ! 183: ! The BIOS-routine wants lots of unnecessary data, and it's less ! 184: ! "interesting" anyway. This is how REAL programmers do it. ! 185: ! ! 186: ! Well, now's the time to actually move into protected mode. To make ! 187: ! things as simple as possible, we do no register set-up or anything, ! 188: ! we let the gnu-compiled 32-bit programs do that. We just jump to ! 189: ! absolute address 0x00000, in 32-bit protected mode. ! 190: ! 191: mov ax,#0x0001 ! protected mode (PE) bit ! 192: lmsw ax ! This is it! ! 193: jmpi 0,8 ! jmp offset 0 of segment 8 (cs) ! 194: ! 195: ! This routine checks that the keyboard command queue is empty ! 196: ! No timeout is used - if this hangs there is something wrong with ! 197: ! the machine, and we probably couldn't proceed anyway. 1.1 root 198: empty_8042: 199: .word 0x00eb,0x00eb 1.1.1.2 ! root 200: in al,#0x64 ! 8042 status port ! 201: test al,#2 ! is input buffer full? ! 202: jnz empty_8042 ! yes - loop 1.1 root 203: ret 204: 205: gdt: 1.1.1.2 ! root 206: .word 0,0,0,0 ! dummy 1.1 root 207: 1.1.1.2 ! root 208: .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) ! 209: .word 0x0000 ! base address=0 ! 210: .word 0x9A00 ! code read/exec ! 211: .word 0x00C0 ! granularity=4096, 386 ! 212: ! 213: .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) ! 214: .word 0x0000 ! base address=0 ! 215: .word 0x9200 ! data read/write ! 216: .word 0x00C0 ! granularity=4096, 386 1.1 root 217: 218: idt_48: 1.1.1.2 ! root 219: .word 0 ! idt limit=0 ! 220: .word 0,0 ! idt base=0L 1.1 root 221: 222: gdt_48: 1.1.1.2 ! root 223: .word 0x800 ! gdt limit=2048, 256 GDT entries ! 224: .word 512+gdt,0x9 ! gdt base = 0X9xxxx 1.1 root 225: 226: .text 227: endtext: 228: .data 229: enddata: 230: .bss 231: endbss:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.