1 ; ----------------------------------------------------------------------- 2 ; 3 ; Copyright 2010-2015 Gene Cumm 4 ; 5 ; Portions from diskstart.inc: 6 ; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved 7 ; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin 8 ; 9 ; This program is free software; you can redistribute it and/or modify 10 ; it under the terms of the GNU General Public License as published by 11 ; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 12 ; Boston MA 02110-1301, USA; either version 2 of the License, or 13 ; (at your option) any later version; incorporated herein by reference. 14 ; 15 ; ----------------------------------------------------------------------- 16 17 ; 18 ; geodsp1s.asm 19 ; 20 ; Display geometry translation info for diagnosing misconceptions 21 ; 1 sector variant 22 ; 23 ; nasm -Ox -f bin -o geodsp.bin -l geodsp.lst geodsp.asm 24 ; 25 ; nasm -Ox -f elf -o geodsp.o -l geodsp.lst geodsp.asm 26 ; ld -m elf_i386 -T syslinux.ld -M -o geodsp.elf geodsp.o > geodsp.map 27 ; objcopy -O binary geodsp.elf geodsp.raw 28 ; 29 ; # OF=/dev/sdb 30 ; # dd if=core/geodsp.bin of=$OF 31 ; # dd skip=1 seek=1 if=../dbg/lba-img/lba-img.bin of=$OF 32 ; # eject $OF 33 ; # dd count=$() if=/dev/zero of=$OF 34 ; 35 ; # OF=geo-2.255.63.i 36 ; # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((2*255*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF 37 ; # OF=geo-20.16.63.i 38 ; # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((40*16*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF 39 ; 40 41 %include "macros.inc" 1 <1> ;; ----------------------------------------------------------------------- 2 <1> ;; 3 <1> ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved 4 <1> ;; Copyright 2009 Intel Corporation; author: H. Peter Anvin 5 <1> ;; 6 <1> ;; This program is free software; you can redistribute it and/or modify 7 <1> ;; it under the terms of the GNU General Public License as published by 8 <1> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, 9 <1> ;; Boston MA 02111-1307, USA; either version 2 of the License, or 10 <1> ;; (at your option) any later version; incorporated herein by reference. 11 <1> ;; 12 <1> ;; ----------------------------------------------------------------------- 13 <1> 14 <1> ;; 15 <1> ;; macros.inc 16 <1> ;; 17 <1> ;; Convenient macros 18 <1> ;; 19 <1> 20 <1> %ifndef _MACROS_INC 21 <1> %define _MACROS_INC 22 <1> 23 <1> ; 24 <1> ; Identify the module we're compiling; the "correct" should be defined 25 <1> ; in the module itself to 1 26 <1> ; 27 <1> %ifdef IS_SYSLINUX 28 <1> %define MY_NAME 'SYSLINUX' 29 <1> %else 30 <1> %define IS_SYSLINUX 0 31 <1> %endif 32 <1> %ifdef IS_PXELINUX 33 <1> %define MY_NAME 'PXELINUX' 34 <1> %if IS_LPXELINUX > 0 35 <1> %define MY_TYPE 'lwIP' 36 <1> %else 37 <1> %define MY_TYPE 'PXE' 38 <1> %endif 39 <1> %else 40 <1> %define IS_PXELINUX 0 41 <1> %endif 42 <1> %ifdef IS_ISOLINUX 43 <1> %define MY_NAME 'ISOLINUX' 44 <1> %else 45 <1> %define IS_ISOLINUX 0 46 <1> %endif 47 <1> %ifdef IS_EXTLINUX 48 <1> %define MY_NAME 'EXTLINUX' 49 <1> %else 50 <1> %define IS_EXTLINUX 0 51 <1> %endif 52 <1> 53 <1> ; 54 <1> ; Macros similar to res[bwd], but which works in the code segment (after 55 <1> ; section .text16) or the data segment (section .data16) 56 <1> ; 57 <1> %macro zb 1.nolist 58 <1> times %1 db 0 59 <1> %endmacro 60 <1> 61 <1> %macro zw 1.nolist 62 <1> times %1 dw 0 63 <1> %endmacro 64 <1> 65 <1> %macro zd 1.nolist 66 <1> times %1 dd 0 67 <1> %endmacro 68 <1> 69 <1> ; 70 <1> ; Align with zero bytes in a progbits segment 71 <1> ; 72 <1> %macro alignz 1.nolist 73 <1> times (((%1) - (($-$$) % (%1))) % (%1)) db 0 74 <1> %endmacro 75 <1> 76 <1> ; 77 <1> ; Macro to emit an unsigned decimal number as a string 78 <1> ; 79 <1> %macro asciidec 1.nolist 80 <1> %ifndef DEPEND ; Not safe for "depend" 81 <1> %push asciidec 82 <1> %assign %$v %1 83 <1> %if %$v == 0 84 <1> db '0' 85 <1> %else 86 <1> %assign %$dcount 0 87 <1> %assign %$n %$v 88 <1> %assign %$d 1 89 <1> %rep 20 90 <1> %if %$n != 0 91 <1> %assign %$dcount %$dcount + 1 92 <1> %assign %$n %$n / 10 93 <1> %assign %$d %$d * 10 94 <1> %endif 95 <1> %endrep 96 <1> %rep %$dcount 97 <1> %assign %$d %$d / 10 98 <1> db ((%$v / %$d) % 10) + '0' 99 <1> %endrep 100 <1> %endif 101 <1> %pop 102 <1> %endif 103 <1> %endmacro 104 <1> 105 <1> ; 106 <1> ; Macros for network byte order of constants 107 <1> ; 108 <1> %define htons(x) ( ( ((x) & 0FFh) << 8 ) + ( ((x) & 0FF00h) >> 8 ) ) 109 <1> %define ntohs(x) htons(x) 110 <1> %define htonl(x) ( ( ((x) & 0FFh) << 24) + ( ((x) & 0FF00h) << 8 ) + ( ((x) & 0FF0000h) >> 8 ) + ( ((x) & 0FF000000h) >> 24) ) 111 <1> %define ntohl(x) htonl(x) 112 <1> 113 <1> ; 114 <1> ; ASCII 115 <1> ; 116 <1> CR equ 13 ; Carriage Return 117 <1> LF equ 10 ; Line Feed 118 <1> FF equ 12 ; Form Feed 119 <1> BS equ 8 ; Backspace 120 <1> 121 <1> %endif ; _MACROS_INC 42 ; %include "layout.inc" 43 44 ; global STACK_LEN, STACK_TOP, STACK_BASE 45 ; STACK_LEN equ 4096 46 STACK_TOP equ 7c00h 47 ; STACK_BASE equ STACK_TOP - STACK_LEN 48 49 StackBuf equ STACK_TOP-44-92 ; Start the stack here (grow down - 4K) 50 DriveNumber equ StackBuf-4 ; Drive number 51 m_CHS0 equ 00534843h ;'CHS',0 52 m_EDD0 equ 00444445h ;'EDD',0 53 m_EDD_SP equ 20444445h ;'EDD ' 54 retry_count equ 16 55 dbuf equ 8000h 56 int13_ret equ 7e00h 57 58 ; Uncomment to test EDD 59 %define TEST_EDD 1 60 ; Uncomment to show errors (while it still continues) 61 %define SHOW_ERR 1 62 ; Uncomment to have room for a partition table 63 %define HAVE_PTABLE 1 64 ; Uncomment to force DL == 80h 65 ; %define FORCE_80 1 66 67 ; extern real_mode_seg 68 ; section .real_mode write nobits align=65536 69 ; global core_real_mode 70 ; core_real_mode resb 65536 71 ; extern xfer_buf_seg 72 ; section .xfer_buf write nobits align=65536 73 ; global core_xfer_buf 74 ; core_xfer_buf resb 65536 75 76 section .text 77 org STACK_TOP 78 79 80 global _start 81 bootsec equ $ 82 _start: 83 ; In case we want to pull more of the standard diskstart stuff in 84 ; jmp short start ; 2 bytes 85 ; nop ; 1 byte 86 start: 87 00000000 FA cli 88 00000001 FC cld 89 00000002 31C9 xor cx,cx 90 00000004 8ED1 mov ss,cx 91 00000006 BC767B mov sp,StackBuf-2 ; Just below BSS (-2 for alignment) 92 %ifdef FORCE_80 93 mov dl,80h ; Should encode as B2h 80h 94 %else 95 00000009 90 nop ; Reserve the space for forcing DL 96 0000000A 90 nop ; Should encode as 90h 90h 97 %endif ; FORCE_80 98 0000000B 52 push dx ; Save drive number (in DL) 99 ; Kill everything else and let the BIOS sort it out later 100 0000000C 8EC1 mov es,cx 101 0000000E 8ED9 mov ds,cx 102 00000010 FB sti 103 ; clc ; just in case it's not clear 104 105 write_drivenum: 106 ; mov al,[DriveNumber] 107 00000011 88D0 mov al,dl 108 00000013 E85401 call writehex2 109 110 get_geo: ; DL and ES ready 111 00000016 B408 mov ah,08h 112 00000018 BF0000 mov di,0 113 0000001B CD13 int 13h 114 write_geo: 115 0000001D 7306 jnc .ok_geo 116 %ifdef SHOW_ERR 117 0000001F B021 mov al,'!' 118 00000021 E83A01 call writechr 119 %endif ; SHOW_ERR 120 00000024 F8 clc 121 .ok_geo: 122 00000025 BE[AA01] mov si,s_chs 123 00000028 E82401 call writestr_early 124 0000002B E8D800 call write_chs 125 0000002E BE[BA01] mov si,s_crlf 126 00000031 E81B01 call writestr_early 127 ; jmp short .done 128 ; .bad_geo: 129 .done: 130 131 00000034 BB0080 mov bx,dbuf 132 get_h1c: ; 0,1,1 133 00000037 B90100 mov cx,0001h 134 0000003A B601 mov dh,01h 135 0000003C E88D00 call getonesec_chs 136 0000003F E8B700 call write_chs_lba 137 get_c1c: ; 1,0,1 138 00000042 B90101 mov cx,0101h 139 00000045 B600 mov dh,00h 140 00000047 E88200 call getonesec_chs 141 0000004A E8AC00 call write_chs_lba 142 143 ; 144 ; Do we have EBIOS (EDD)? 145 ; 146 %ifdef TEST_EDD 147 edd: 148 .check: 149 0000004D BBAA55 mov bx,55AAh 150 00000050 B441 mov ah,41h ; EDD existence query 151 00000052 8A16747B mov dl,[DriveNumber] 152 00000056 CD13 int 13h 153 00000058 723F jc .noedd 154 0000005A 81FB55AA cmp bx,0AA55h 155 0000005E 7539 jne .noedd 156 00000060 F6C101 test cl,1 ; Extended disk access functionality set 157 00000063 7434 jz .noedd 158 ; 159 ; We have EDD support... 160 ; 161 00000065 BB0080 mov bx,dbuf 162 00000068 6631D2 xor edx,edx 163 0000006B 66C706[AA01]454444- mov dword [s_chs],m_EDD_SP 163 00000073 20 164 .get_lba63: 165 00000074 66B83F000000 mov eax,63 ; Same length as mov al,64; movzx eax,al 166 0000007A E82400 call getonesec_ebios 167 0000007D 721A jc .bad_edd ;read error 168 0000007F E8A900 call write_edd_lba 169 .get_lba16065: 170 00000082 66B8C13E0000 mov eax,16065 171 00000088 E81600 call getonesec_ebios 172 0000008B 720C jc .bad_edd ;read error 173 0000008D E89B00 call write_edd_lba 174 .good_edd: 175 00000090 66C706[B101]454444- mov dword [s_type],m_EDD0 175 00000098 00 176 .bad_edd: 177 .noedd: 178 .end: 179 %endif ; TEST_EDD 180 181 write_final_type: 182 00000099 BE[AF01] mov si,s_typespec 183 0000009C E8B000 call writestr_early 184 185 0000009F EB3E jmp short kaboom 186 187 ; 188 ; getonesec_ebios: 189 ; 190 ; getonesec implementation for EBIOS (EDD) 191 ; 192 %ifdef TEST_EDD 193 getonesec_ebios: 194 000000A1 B91000 mov cx,retry_count 195 .retry: 196 ; Form DAPA on stack 197 000000A4 6652 push edx 198 000000A6 6650 push eax 199 000000A8 06 push es 200 000000A9 53 push bx 201 000000AA 6A01 push word 1 202 000000AC 6A10 push word 16 203 000000AE 89E6 mov si,sp 204 000000B0 6660 pushad 205 000000B2 B442 mov ah,42h ; Extended Read 206 000000B4 E83800 call xint13 207 000000B7 6661 popad 208 000000B9 8D6410 lea sp,[si+16] ; Remove DAPA 209 000000BC 7201 jc .error 210 000000BE C3 ret 211 212 .error: 213 ; Some systems seem to get "stuck" in an error state when 214 ; using EBIOS. Doesn't happen when using CBIOS, which is 215 ; good, since some other systems get timeout failures 216 ; waiting for the floppy disk to spin up. 217 218 000000BF 6660 pushad ; Try resetting the device 219 000000C1 31C0 xor ax,ax 220 000000C3 E82900 call xint13 221 000000C6 6661 popad 222 000000C8 E2DA loop .retry ; CX-- and jump if not zero 223 224 ; Total failure. 225 000000CA F9 stc 226 000000CB C3 ret 227 %endif ; TEST_EDD 228 229 ; 230 ; getonesec_chs: 231 ; 232 ; CX,DH specifies CHS address 233 ; 234 getonesec_chs: ; We could use an xchg and get a loop 235 ; mov cx,retry_count 236 .retry: 237 000000CC 6660 pushad 238 000000CE B80102 mov ax,0201h ; Read one sector 239 000000D1 E81B00 call xint13 240 000000D4 6661 popad 241 000000D6 7306 jnc .no_error 242 %ifdef SHOW_ERR 243 000000D8 B021 mov al,'!' 244 000000DA E88100 call writechr 245 %endif ; SHOW_ERR 246 000000DD F8 clc 247 .no_error: 248 000000DE C3 ret 249 250 .error: 251 ; loop .retry 252 ; Fall through to disk_error 253 ; 254 ; kaboom: write a message and bail out. 255 ; 256 disk_error: 257 global kaboom 258 kaboom: 259 .patch: 260 000000DF BE[B501] mov si,bailmsg 261 000000E2 E86A00 call writestr_early 262 000000E5 6631C0 xor eax,eax 263 000000E8 CD16 .again: int 16h ; Wait for keypress 264 ; NB: replaced by int 18h if 265 ; chosen at install time.. 266 000000EA CD19 int 19h ; And try once more to boot... 267 000000EC F4 .norge: hlt ; If int 19h returned; this is the end 268 000000ED EBFD jmp short .norge 269 270 ; 271 ; INT 13h wrapper function 272 ; 273 xint13: 274 000000EF 8A16747B mov dl,[DriveNumber] 275 000000F3 CD13 int 13h 276 000000F5 A3007E mov [int13_ret],ax 277 000000F8 C3 ret 278 279 %include "geodsplib.inc" 1 <1> ; ----------------------------------------------------------------------- 2 <1> ; 3 <1> ; Copyright 2010-2015 Gene Cumm 4 <1> ; 5 <1> ; Portions from diskstart.inc: 6 <1> ; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved 7 <1> ; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin 8 <1> ; 9 <1> ; This program is free software; you can redistribute it and/or modify 10 <1> ; it under the terms of the GNU General Public License as published by 11 <1> ; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 12 <1> ; Boston MA 02110-1301, USA; either version 2 of the License, or 13 <1> ; (at your option) any later version; incorporated herein by reference. 14 <1> ; 15 <1> ; ----------------------------------------------------------------------- 16 <1> 17 <1> ; 18 <1> ; geodsplib.inc 19 <1> ; 20 <1> ; Library file for geodsp*.asm 21 <1> ; 22 <1> 23 <1> ; ES:BX points to the buffer with address 24 <1> ; DX,CX as they should be for INT13h,AH=02 25 <1> ; Should work for C>=256 26 <1> write_chs_lba: 27 <1> ; pushad 28 000000F9 BE[A901] <1> mov si,s_atchs 29 000000FC E85000 <1> call writestr_early 30 000000FF E80400 <1> call write_chs 31 00000102 E83700 <1> call write_col_val_crlf 32 <1> ; popad 33 00000105 C3 <1> ret 34 <1> 35 <1> ; DX,CX as they should be for INT13h,AH=02 36 <1> ; Should work for C>=256 37 <1> write_chs: 38 00000106 6660 <1> pushad 39 00000108 88E8 <1> mov al,ch 40 0000010A 88CC <1> mov ah,cl 41 0000010C C0EC06 <1> shr ah,6 42 0000010F E86500 <1> call writehex4 43 00000112 B02C <1> mov al,',' 44 00000114 E84700 <1> call writechr 45 00000117 88F0 <1> mov al,dh 46 00000119 E84E00 <1> call writehex2 47 0000011C B02C <1> mov al,',' 48 0000011E E83D00 <1> call writechr 49 00000121 88C8 <1> mov al,cl 50 00000123 243F <1> and al,3Fh 51 00000125 E84200 <1> call writehex2 52 00000128 6661 <1> popad 53 0000012A C3 <1> ret 54 <1> 55 <1> %ifdef TEST_EDD 56 <1> write_edd_lba: 57 0000012B 6660 <1> pushad 58 0000012D BE[A901] <1> mov si,s_atchs 59 00000130 E81C00 <1> call writestr_early 60 00000133 E84E00 <1> call writehex8 61 00000136 E80300 <1> call write_col_val_crlf 62 00000139 6661 <1> popad 63 0000013B C3 <1> ret 64 <1> %endif ; TEST_EDD 65 <1> 66 <1> write_col_val_crlf: 67 0000013C B03A <1> mov al,':' 68 0000013E E81D00 <1> call writechr 69 00000141 26668B07 <1> mov eax,[es:bx] 70 00000145 E83C00 <1> call writehex8 71 00000148 BE[BA01] <1> mov si,s_crlf 72 0000014B E80100 <1> call writestr_early 73 0000014E C3 <1> ret 74 <1> 75 <1> ; write_exc: 76 <1> ; ; push ax 77 <1> ; mov al,'!' 78 <1> ; call writechr 79 <1> ; ; pop ax 80 <1> ; ret 81 <1> 82 <1> ; crlf: 83 <1> ; push si 84 <1> ; mov si,s_crlf 85 <1> ; call writestr_early 86 <1> ; pop si 87 <1> ; ret 88 <1> 89 <1> ; 90 <1> ; 91 <1> ; writestr_early: write a null-terminated string to the console 92 <1> ; This assumes we're on page 0. This is only used for early 93 <1> ; messages, so it should be OK. 94 <1> ; 95 <1> writestr_early: 96 0000014F 6660 <1> pushad 97 00000151 AC <1> .loop: lodsb 98 00000152 20C0 <1> and al,al 99 00000154 7405 <1> jz .return 100 00000156 E80500 <1> call writechr 101 00000159 EBF6 <1> jmp short .loop 102 0000015B 6661 <1> .return: popad 103 0000015D C3 <1> ret 104 <1> 105 <1> writechr: 106 <1> writechr_early: 107 0000015E 6660 <1> pushad 108 00000160 B40E <1> mov ah,0Eh ; Write to screen as TTY 109 00000162 BB0700 <1> mov bx,0007h ; Attribute 110 00000165 CD10 <1> int 10h 111 00000167 6661 <1> popad 112 00000169 C3 <1> ret 113 <1> 114 <1> %include "writehex.inc" 1 <2> ;; ----------------------------------------------------------------------- 2 <2> ;; 3 <2> ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved 4 <2> ;; 5 <2> ;; This program is free software; you can redistribute it and/or modify 6 <2> ;; it under the terms of the GNU General Public License as published by 7 <2> ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, 8 <2> ;; Boston MA 02111-1307, USA; either version 2 of the License, or 9 <2> ;; (at your option) any later version; incorporated herein by reference. 10 <2> ;; 11 <2> ;; ----------------------------------------------------------------------- 12 <2> 13 <2> ;; 14 <2> ;; writehex.inc 15 <2> ;; 16 <2> ;; Write hexadecimal numbers to the console 17 <2> ;; 18 <2> 19 <2> ; 20 <2> ; writehex[248]: Write a hex number in (AL, AX, EAX) to the console 21 <2> ; 22 <2> writehex2: 23 0000016A 669C <2> pushfd 24 0000016C 6660 <2> pushad 25 0000016E 66C1C018 <2> rol eax,24 26 00000172 B90200 <2> mov cx,2 27 00000175 EB14 <2> jmp short writehex_common 28 <2> writehex4: 29 00000177 669C <2> pushfd 30 00000179 6660 <2> pushad 31 0000017B 66C1C010 <2> rol eax,16 32 0000017F B90400 <2> mov cx,4 33 00000182 EB07 <2> jmp short writehex_common 34 <2> writehex8: 35 00000184 669C <2> pushfd 36 00000186 6660 <2> pushad 37 00000188 B90800 <2> mov cx,8 38 <2> writehex_common: 39 0000018B 66C1C004 <2> .loop: rol eax,4 40 0000018F 6650 <2> push eax 41 00000191 240F <2> and al,0Fh 42 00000193 3C0A <2> cmp al,10 43 00000195 7304 <2> jae .high 44 00000197 0430 <2> .low: add al,'0' 45 00000199 EB02 <2> jmp short .ischar 46 0000019B 0437 <2> .high: add al,'A'-10 47 0000019D E8BEFF <2> .ischar: call writechr 48 000001A0 6658 <2> pop eax 49 000001A2 E2E7 <2> loop .loop 50 000001A4 6661 <2> popad 51 000001A6 669D <2> popfd 52 000001A8 C3 <2> ret 115 <1> 116 000001A9 40 <1> s_atchs: db '@' 117 000001AA 434853 <1> s_chs: db 'CHS' 118 000001AD 2000 <1> s_space: db ' ', 0 119 000001AF 443D <1> s_typespec: db 'D=' 120 000001B1 43485300 <1> s_type: db 'CHS', 0 121 000001B5 0D0A656E64 <1> s_end: db 0Dh, 0Ah, 'end' 122 000001BA 0D0A00 <1> s_crlf: db 0Dh, 0Ah, 0 123 <1> 124 <1> ; This indicates the general format of the last few bytes in the boot sector 125 <1> BS_MAGIC_VER equ 0x1b << 9 280 bailmsg equ s_end 281 282 %ifdef HAVE_PTABLE 283 ; This fails if the boot sector overflows into the partition table 284 000001BD 00 zb 1BEh-($-$$) 285 286 000001BE 00 ptable zb 40h ; Partition table 287 %endif ; HAVE_PTABLE 288 289 000001FE 55AA bootsignature dw 0xAA55 290 291 ; This fails if the boot sector overflows 292 zb 200h-($-$$) 293 294 sector_2: