PageRenderTime 42ms CodeModel.GetById 14ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 1ms

/bootloader/stage1.asm

http://github.com/Pokelover980/Poke-and-Necro-Hobby-OS
Assembly | 243 lines | 199 code | 28 blank | 16 comment | 0 complexity | 8932d093f4233a442b387fbc1a649b54 MD5 | raw file
  1; -------------------------------------------------------------
  2; Pokelover and Necro's Hobby OS Bootloader - Stage 1
  3; 
  4; Based on the MikeOS bootloader, which is based on the free
  5; bootloader by E Dehling. It looks for the STAGE2.BIN file on
  6; a FAT12 filesystem (specifically a floppy). Takes up exactly
  7; one sector and MUST end in 0xAA55, which is the bootloader
  8; signature.
  9; -------------------------------------------------------------
 10
 11[BITS 16]                    ; Let NASM know we want 16 bit mode, even though
 12                             ; it should be able to detect it on it's own
 13jmp short BootStart          ; Jump over disk info.
 14nop
 15
 16OEMLabel db "PNOSBOOT"       ; Disk label
 17BytesPerSector dw 512        ; Bytes per sector
 18SectorsPerCluster db 1       ; Sectors per cluster
 19ReservedForBoot dw 1         ; Reserved sectors for boot record
 20NumberOfFats		db 2	 ; Number of copies of the FAT
 21RootDirEntries		dw 224	 ; Number of entries in root dir
 22					         ; (224 * 32 = 7168 = 14 sectors to read)
 23LogicalSectors		dw 2880	 ; Number of logical sectors
 24MediumByte		db 0F0h		 ; Medium descriptor byte
 25SectorsPerFat		dw 9	 ; Sectors per FAT
 26SectorsPerTrack		dw 18	 ; Sectors per track (36/cylinder)
 27Sides			dw 2		 ; Number of sides/heads
 28HiddenSectors		dd 0	 ; Number of hidden sectors
 29LargeSectors		dd 0	 ; Number of LBA sectors
 30DriveNo			dw 0		 ; Drive No: 0
 31Signature		db 41		 ; Drive signature: 41 for floppy
 32VolumeID		dd 00000000h ; Volume ID: any number
 33VolumeLabel		db "PNOS       "; Volume Label: any 11 chars
 34FileSystem		db "FAT12   "	; File system type: don't change!
 35
 36BootStart:
 37	mov ax, 0x07C0           ; This is our entry point, we're going to set up
 38	                         ; a 4K stack space above this
 39	add ax, 544              ; And first we need a 544 paragraph buffer so we don't
 40	                         ; interfere with this or the disk buffer!
 41	cli                      ; Disable interrupts while changing stack
 42	mov ss, ax
 43	mov sp, 4096
 44	sti                      ; Restore interrupts
 45	mov ax, 0x07C0           ; Set data segment to where we've loaded to make things easier
 46	mov ds, ax
 47	mov byte [BootDev], dl   ; Save boot device number
 48	mov eax, 0               ; Older BIOSes may need this
 49	
 50FloppyOk:                    ; Ready to read first block of data
 51	mov ax, 19               ; Root dir starts at logical sector 19
 52	call l2hts
 53	mov si, Buffer           ; Set ES:BX to our buffer
 54	mov bx, ds
 55	mov es, bx
 56	mov bx, si
 57	mov ah, 2                ; int 0x13 params: Read floppy sectors
 58	mov al, 14               ; 14 floppy sectors to read
 59	pusha                    ; Push registers to stack to prepare for loop
 60	
 61ReadRootDir:
 62	popa                     ; Just in case int 0x13 modified anything
 63	pusha
 64	stc                      ; Not all BIOSes set properly on error
 65	int 0x13                 ; Read sectors
 66	jnc SearchDir            ; If read was OK, skip ahead
 67	call ResetFloppy         ; If not, reset floppy and try again
 68	jnc ReadRootDir          ; Did the floppy reset fine?
 69	jmp Reboot               ; If it didn't, double error, restart
 70	
 71SearchDir:
 72	popa
 73	mov ax, ds               ; Root dir is now in [Buffer]
 74	mov es, ax               ; Give this info to DI
 75	mov di, Buffer
 76	mov cx, word [RootDirEntries] ; Search all entries
 77	mov ax, 0                ; Start at 0
 78	
 79NextRootEntry:
 80	xchg cx, dx              ; We use cx in the inner loop
 81	mov si, BootFileName     ; Start searching for stage2 filename
 82	mov cx, 11
 83	rep cmpsb
 84	je FoundFileToLoad       ; Pointer DI will be at offset 11
 85	add ax, 32               ; Bump by one entry (32 bytes per entry)
 86	mov di, Buffer           ; Point to next entry
 87	add di, ax
 88	xchg dx, cx              ; Get cx back
 89	loop NextRootEntry
 90	mov si, NoFile
 91	call PrintString
 92	jmp Reboot
 93	
 94FoundFileToLoad:             ; Let's load the FAT into RAM
 95	mov ax, word[es:di+0x0F] ; Offset 11+15=26 contains our first cluster
 96	mov word[Cluster], ax
 97	mov ax, 1                ; Sector 1 = first sector of FAT
 98	call l2hts
 99	mov di, Buffer
100	mov bx, di               ; ES:BX points to our buffer
101	mov ah, 2                ; int 0x13 params: read FAT sectors
102	mov al, 9                ; All 9 sectors of first FAT
103	pusha                    ; Push registers to stack to prepare for loop
104	
105ReadFat:
106	popa                     ; In case int 0x13 modified anything
107	pusha
108	stc
109	int 0x13                 ; Read sectors using BIOS
110	jnc ReadFatOkay          ; If read was okay, skip ahead
111	call ResetFloppy         ; Otherwise, reset floppy and try again
112	jnc ReadFat              ; Floppy reset OK?
113	mov si, DiskError
114	call PrintString         ; If not, print an error and reboot
115	jmp Reboot
116
117ReadFatOkay:
118	popa
119	mov ax, 0x2000           ; Segment where we're loading kernel
120	mov es, ax
121	mov bx, 0
122	mov ah, 2                ; int 0x13 read params
123	mov al, 1
124	push ax                  ; Save in case it gets lost
125	
126; We're gonna load the FAT from the disk now
127
128LoadFileSector:
129	mov ax, word [Cluster]   ; Convert sector to logical
130	add ax, 31
131	call l2hts
132	mov ax, 0x2000           ; Set buffer past what we've read
133	mov es, ax
134	mov bx, word [Pointer]
135	pop ax                   ; Save in case it gets lost
136	push ax
137	stc
138	int 0x13
139	jnc CalculateNextCluster ; If there's no error
140	call ResetFloppy         ; If there is, reset floppy
141	jmp LoadFileSector
142	
143CalculateNextCluster:
144	mov ax, [Cluster]
145	mov dx, 0
146	mov bx, 3
147	mul bx
148	mov bx, 2
149	div bx                   ; DX = [Cluster] mod 2
150	mov si, Buffer
151	add si, ax               ; AX = word in FAT for 12 bit entry
152	mov ax, word [ds:si]
153	or dx, dx                ; If DX = 0 [Cluster] is even; if 1, [Cluster] is odd
154	jz even                  ; If [Cluster] is even, drop last 4 bits of word with
155	                         ; next clusters; if odd, drop first 4 bits
156							 
157odd:
158	shr ax, 4
159	jmp short NextClusterCont
160	
161even:
162	and ax, 0x0FFF           ; Mask out final four bits
163	
164NextClusterCont:
165	mov word [Cluster], ax   ; Store cluster
166	cmp ax, 0x0FF8           ; 0xFF8 = end of file in FAT12
167	jae end
168	add word [Pointer], 512  ; Increase buffer point 1 sector
169	jmp LoadFileSector
170	
171end:                         ; Hooray, we've reached the end and got the file to load!
172	pop ax                   ; Clean up stack, as we pushed AX earlier
173	mov dl, byte[BootDev]    ; Provide Stage2/Kernel with boot device info
174	mov si, NoFile
175	call PrintString
176	jmp 0x2000:0x0           ; Jump to entry point of stage2!
177	
178; Subroutines below
179
180Reboot:
181	mov ax, 0
182	int 0x16                 ; Wait for keystroke
183	mov ax, 0
184	int 0x19                 ; Reboot
185	
186PrintString:
187	pusha
188	mov ax, 0x0E
189	
190.repeat:
191	lodsb
192	cmp al, 0
193	je .done                 ; If char is 0, we've reached the end of the string
194	int 0x10                 ; Otherwise, we print it
195	jmp short .repeat
196	
197.done:
198	popa
199	ret
200	
201ResetFloppy:                 ; Carry set on error
202	push ax
203	push dx
204	mov ax, 0
205	mov dl, byte [BootDev]
206	stc
207	int 0x13
208	pop dx
209	pop ax
210	ret
211	
212l2hts:                       ; Calculate head, track and sector for int 0x13
213	push bx
214	push ax
215	mov bx, ax
216	mov dx, 0
217	div word [SectorsPerTrack]
218	add dl, 0x01
219	mov cl, dl
220	mov ax, bx
221	mov dx, 0
222	div word [SectorsPerTrack]
223	mov dx, 0
224	div word [Sides]
225	mov dh, dl
226	mov ch, al
227	pop ax
228	pop bx
229	mov dl, byte [BootDev]
230	ret
231	
232	
233BootFileName db "STAGE2  BIN" ; Stage2 filename
234DiskError db "Disk error! Press any key to reboot...", 0 ; Something went wrong!
235NoFile db "No STAGE2.BIN", 0  ; Someone forgot to add something...
236BootDev db 0
237Cluster dw 0
238Pointer dw 0
239
240times 510-($-$$) db 0
241dw 0AA55h
242
243Buffer: