|
|
- ORG 0x7C00
- BITS 16
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; SLRboot
- ; Bootloader for SingOS
- ; version 0.2.0.3-exp
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- cli
- jmp long 0x0000:start
-
- start:
- mov ax, 0x1000
- mov ss, ax
- mov sp, 0xb000
- mov ax, 0
- mov ds, ax
- mov es, ax
- mov [disk_identifier], dl
- sti
- mov si, 0x7c00
- mov di, 0x600
- mov cx, 0x100
- rep movsw
- mov bx, relocated
- sub bx, 0x7600 ; Calculate the offset.
- push bx
- ret ; Return far
- ;jmp long 0:bx
-
- relocated:
-
- mov si, message ; Put address of the null-terminated string to output into 'si'
- call print ; Call our string-printing routine
-
- ; Check for more than one active partition that we can start from.
- xor bx, bx
- xor cx, cx
- mov ax, [partition_1.active_partition]
- cmp ax, 0x80
- jne check_p_2
- mov bx, 0x01 ; Partion 1 active
- inc cx
-
- check_p_2:
- mov ax, [partition_2.active_partition]
- cmp ax, 0x80
- jne check_p_3
- inc cx
- mov bx, 0x02 ; Partion 2 active
-
- check_p_3:
- mov ax, [partition_3.active_partition]
- cmp ax, 0x80
- jne check_p_4
- inc cx
- mov bx, 0x03 ; Partion 3 active
-
- check_p_4:
- mov ax, [partition_4.active_partition]
- cmp ax, 0x80
- jne eval_active_partion_number
- inc cx
- mov bx, 0x04 ; Partion 4 active
-
- eval_active_partion_number:
- cmp cx, 1
- je boot_partition
- ; here goes wait call, for the user to enter debug mode.
- ; Wating for 2 seconds:
- mov ah, 0x86 ; code for waiting interupt call
- mov cx, 0x001e ; high count of microseconds
- mov dx, 0x8480 ; low count
- int 0x15
- .busy_wait_for_key:
- xor ax, ax
- mov ah, 0x01 ; BIOS call to wait for key
- int 0x16
-
-
- boot_partition:
- ; IMPORTANT bx, has to hold the value 1-4 for the partiotion that wanted to be booted.
-
- mov bx, 2
-
- mov ax, partition_1
- .loop:
- cmp bx, 1
- je break
- add ax, 0x10
- ;call dumpax
- dec bx
- jmp .loop
- break:
-
- add ax, 8 ; This is the offset to fetch the LBA start adress of the partition record
- mov bx, ax
- xor ax, ax
- mov ax, [bx] ; first part of LBA
- mov WORD [DAPACK.lba_addr_dw_low], ax
- call dumpax
- add bx, 2 ; next part
- mov ax, [bx]
- mov WORD [DAPACK.lba_addr_dw_low + 1], ax
- call dumpax
- cli
- hlt
- mov WORD [DAPACK.blkcnt], 0x01
- mov WORD [DAPACK.db_addr_segment], 0x0000
- mov WORD [DAPACK.db_addr_offset], 0x7c00
- mov si, DAPACK ; address of "disk address packet"
- xor ax, ax
- mov ah, 0x42 ; READ
- mov dl, [disk_identifier]
- int 0x13
-
- jmp long 0x0:0x7c00
-
- cli
- hlt
-
-
- %IF 0
- cli
- jmp long 0x0000:start
-
- start:
- xor ax, ax
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov [disk_identifier], dl
-
- ; initialize stack
- ; Set up 4K stack after this bootloader
- ; [Remember: Effective Address = Segment*16 + Offset]
- mov ax, 0x7C0 ; Set 'ax' equal to the location of this bootloader divided by 16
- add ax, 0x20 ; Skip over the size of the bootloader divided by 16
- mov ss, ax ; Set 'ss' to this location (the beginning of our stack region)
- mov sp, 8192 ; Set 'ss:sp' to the top of our 8K stack
- sti
- mov si, message ; Put address of the null-terminated string to output into 'si'
- call print ; Call our string-printing routine
-
- mov si, enter_debug_mode
- call print
- call printCRLF
- ;%IF 0
- ; here goes wait call, for the user to enter debug mode.
- ; Wating for 2 seconds:
- mov ah, 0x86 ; code for waiting interupt call
- mov cx, 0x001e ; high count of microseconds
- mov dx, 0x8480 ; low count
- int 0x15
-
- .busy_wait_for_key:
- xor ax, ax
- mov ah, 0x01 ; BIOS call to wait for key
- int 0x16
- jnz debug_mode
-
- ; entering system check:
- mov si, enter_system_check
-
- mov si, sys_check_ok ; Put address of the null-terminated string to output into 'si'
- call print ; Call our string-printing routine
-
- mov si, boot_system ; Put address of the null-terminated string to output into 'si'
- call print ; Call our string-printing routine
-
- ;This goes first as to now overwrite %ah and %al.
- ;mov ax, 0x0050
- ;mov es, ax ;Section to write into
- ;mov ah, 0x2 ;Read sectors from drive
- ;mov al, 0x08 ;Number of sectors to read (31 * 512 = 15872 bytes)
- ;mov ch, 0x0 ;Low 8 bits of cylinder
- ;mov cl, 0x11 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
- ;mov dh, 0x0 ;Head number
- ;mov dl, [disk_identifier] ;Drive number
- ;mov bx, 0x0000 ;Offset into section
- ;int 0x13 ;Low level disk services
-
- ;jnc notcarry
- ;mov si, error_str
- ;call print
- ;jmp endcarrycheck
-
- notcarry:
- ;mov si, success_str
- ;call print
- ;call printCRLF
-
- mov ax, 0x0
- mov ds, ax
- mov ax, 89 ; lba adress
-
- jmp 0x50:0x0000 ; Jump to the kernel
-
- endcarrycheck:
- cli ; Clear the Interrupt Flag (disable external interrupts)
- hlt ; Halt the CPU (until the next external interrupt)
-
- debug_mode:
- mov si, .welcome_debug
- call print
- cli ; Clear the Interrupt Flag (disable external interrupts)
- hlt
-
- .welcome_debug db 'This is debug mode', 0
-
- printCRLF:
- mov ah, 0xE
- mov al, 13
- int 0x10
- mov al, 10
- int 0x10
- ret
- %ENDIF
-
- ;Routine for printing a 'ax' as hex
- dumpax:
- pusha ; save registers
- mov bx, ax
- mov ah, 0xE ; Teletype output
-
- mov cx, 4 ; 4 nipples in a 16 bit word
- .loop:
- rol bx, 4 ; rotate to next nipple
- mov al, bl ; we copy to al because we need to mask only the low 4 bits
- and al, 1111b ; Do the masking
- add al, '0' ; convert to ASCII
- cmp al, '9' ; If we are greater than 9 ascii, we add 7 to make digit 10 be represented as 'A'
- jbe .skip ; -|-
- add al, 7 ; -|-
- .skip: ; -|-
- int 0x10 ; BIOS call 'output'
- loop .loop
-
- popa ; restore registers
- ret
-
- ; Routine for outputting string in 'si' register to screen
- print:
- mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function
- ; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)]
- .printchar:
- lodsb ; Load byte at address SI into AL, and increment SI
- cmp al, 0
- je .done ; If the character is zero (NUL), stop writing the string
- int 0x10 ; Otherwise, print the character via 'int 0x10'
- jmp .printchar ; Repeat for the next character
- .done:
- ret
-
- data:
- message db 'SLRboot for SingOS! v0.2.0.3-exp',13,10,0
- ;enter_debug_mode db 'Press d to enter bootloader debug mode',13,10,0
- ;enter_system_check db 'Performing system check:',13,10,0
- ;sys_check_ok db 'System check ok', 13, 10, 0
- ;boot_system db 'Read SingOS from disk', 13, 10, 0
- ;error_str db 'Error', 0
- ;success_str db 'Success', 0
- boot_this_partition: dw 0
- disk_identifier db 0
-
-
- DAPACK:
- .dap_Size: db 0x10 ; This is always 16 bytes (0x10)
- .rev_byte: db 0x0 ; reserved byte, should always be zero
- .blkcnt: dw 0x0 ; int 13 resets this to # of blocks actually read/written
- .db_addr_offset: dw 0x0 ; memory buffer destination address (0:7c00)
- .db_addr_segment: dw 0x0 ; in memory page zero
- .lba_addr_dw_low: dd 0x0 ; put the lba to read in this spot
- .lba_addr_dw_high: dd 0x0 ; more storage bytes only for big lba's ( > 4 bytes )
-
-
- ; Pad to 510 bytes (boot sector size minus 2) with 0s, and finish with the two-byte standard boot signature
- times 446-($-$$) db 0 ; First partion entry
- partition_1:
- .active_partition db 0x80
- .start_CHS db 0x00, 0x00, 0x11;0x20, 0x21, 0x00
- .disk_type db 0x83
- .end_CHS db 0x8C, 0x3D, 0x0F
- .start_LBA db 0x10, 0x00, 0x00, 0x00
- .size db 0x00, 0xC8, 0x03, 0x00
-
- partition_2:
- .active_partition db 0x80
- .start_CHS db 0x8C, 0x3E, 0x0F
- .disk_type db 0x83
- .end_CHS db 0xFF, 0xFF, 0xFF
- .start_LBA db 0x00, 0xD0, 0x03, 0x00
- .size db 0x00, 0x28, 0x1C, 0x03
-
- partition_3:
- .active_partition db 0x00
- .start_CHS db 0x00, 0x00, 0x00
- .disk_type db 0x00
- .end_CHS db 0x00, 0x00, 0x00
- .start_LBA db 0x00, 0x00, 0x00, 0x00
- .size db 0x00, 0x00, 0x00, 0x00
-
- partition_4:
- .active_partition db 0x00
- .start_CHS db 0x00, 0x00, 0x00
- .disk_type db 0x00
- .end_CHS db 0x00, 0x00, 0x00
- .start_LBA db 0x00, 0x00, 0x00, 0x00
- .size db 0x00, 0x00, 0x00, 0x00
-
- times 510-($-$$) db 0
- dw 0xAA55 ; => 0x55 0xAA (little endian byte order)
- ; bootloder debug_mode goes here
-
- times 8192-($-$$) db 0
-
-
-
- ; mov si, 0x7be
- ; cmp byte [si], al
- ; jne 0x33
- ; add si, 0x10
- ; cmp si, 0x7fe
- ; jne 0x24
- ; jmp 0x49
- ; mov ah, 2
- ; mov al, 1
- ; mov bx, 0x7c00
- ; mov dl, 0x80
- ; mov dh, byte [si + 1]
- ; mov cx, word [si + 2]
- ; int 0x13
- ; jmp long 0:0x7c00
-
- ; jmp 0x49
|