ORG 0x7c00 BITS 16 %define DISK_SERVICE 0x0050:0x0000 %define KERNEL 0x2500:0x0000 ;0x0050:0x0512 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Volume Boot Record ; This will start SingOS from the disk ; The disk format has to be LessSimpleFileSystem ; Loading /kernel/kernel.bin which should contain the kernel for the system ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Ensure that the data segment and extra segment is set to 0x00 mov ax, 0x00 mov ds, ax mov es, ax ; Setup stack mov ax, 0x8fc0 mov ss, ax ; Set 'ss' to this location (the beginning of our stack region) mov sp, 0xffff ; Set 'ss:sp' to the top of our 8K stack mov bp, sp mov [global_disk_identifier], dl ; saving disk_identifier, this is the number the disk that we are booting from. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The system has to support int13 bios extended system calls, otherwise is SingOS not supporting the hardware. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ah, 0x41 ;Set AH = 0x41 mov bx, 0x55aa ;BX = 0x55AA mov dl, [global_disk_identifier] ;DL = disk_id int 0x13 ;Issue an INT 0x13. jnc ext_disk_supported ; The System does support exented read write mov si, vbr_lsfs_disk_error_msg call 0x00:tmp_print cli hlt ;Routine for printing a 'ax' as hex ;tmp_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 ;retf tmp_print: ; Prints string in si ; IN si: zero terminated string to print ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;mov ax, 0x7e55 ;mov ax, si ;call 0x00:tmp_dumpax 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 test al, al jz .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: retf ; loading essentials for SingOS to run ; starting by loading the rest of the VBR: ext_disk_supported: mov si, vbr_message call 0x00:tmp_print ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The system is suportted ; We are now loading the kernel "/kernel/kernel.bin" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INPUT ; ax = sector index for the FSCI that has to be loaded. ; bx = segment ;mov ax, [vbr_LBA_FSCI] ;mov bx, 0x00 ;call lsfs_load_fsci_info; ;INPUT ; ax = filename ; bx = pointer to buffer ; cx = buffer_size ; dx = offset in file ; es = segment to read in data ;call lsfs_read_file ; RETURN ; ax preserved ; bx preserved ; cx preserved ; dx data read ; es = remember to restore es if this has to be saved. mov ax, [vbr_LBA_address] inc ax mov dl, [global_disk_identifier] mov WORD [DAPACK.lba_addr_dw_low], ax mov WORD [DAPACK.blkcnt], 0x10 mov WORD [DAPACK.db_addr_segment], 0x7e0 mov WORD [DAPACK.db_addr_offset], 0x00 mov si, DAPACK ; address of "disk address packet" mov ah, 0x42 ; READ mov dl, [global_disk_identifier] int 0x13 mov cx, [vbr_LBA_FSCI] mov bx, ds mov ax, 0x1 push cx push bx push ax mov cx, 0x7e0 mov ds, cx mov es, cx call 0x7e0:0x00 add sp, 0x6 ; skip the paramerts mov cx, 0x0 mov ds, cx mov es, cx ; Set the Parameter_Struct mov ax, lsfs_path mov [Parameter_Struct.path], ax mov WORD [Parameter_Struct.buffer_segment], 0x50 mov WORD [Parameter_Struct.buffer_address], 0x00 mov WORD [Parameter_Struct.buffer_size], 0xFFFF mov WORD [Parameter_Struct.byte_offset_into_file], 0x00 mov cx, Parameter_Struct mov bx, ds mov ax, 0x2 push cx push bx push ax mov cx, 0x7e0 mov ds, cx mov es, cx call 0x7e0:0x00 add sp, 0x6 ; skip the paramerts mov cx, 0x0 mov ds, cx mov es, cx ; Set the Parameter_Struct mov ax, kernel_path mov [Parameter_Struct.path], ax mov WORD [Parameter_Struct.buffer_segment], 0x2500 mov WORD [Parameter_Struct.buffer_address], 0x00 mov WORD [Parameter_Struct.buffer_size], 0xFFFF mov WORD [Parameter_Struct.byte_offset_into_file], 0x00 mov cx, Parameter_Struct mov bx, ds mov ax, 0x2 push cx push bx push ax mov cx, 0x7e0 mov ds, cx mov es, cx call 0x7e0:0x00 add sp, 0x6 ; skip the paramerts mov cx, 0x0 mov ds, cx mov es, cx ; ready to jump to the kernel mov bx, [vbr_LBA_FSCI] mov dl, [global_disk_identifier] jmp KERNEL nop cli hlt 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 ) Parameter_Struct: .path dw 0x00 ; char* .new_path dw 0x00 ; char* .buffer_segment dw 0x00 ; int .buffer_address dw 0x00 ; int .buffer_size dw 0x00 ; int .data_length dw 0x00 ; int .byte_offset_into_file dw 0x00 ; int .entry_kind dw 0x00 ; Table_Entry_Kind global_disk_identifier db 0 vbr_message db 'VBR: Less Simple File System', 13, 10, 'Loading system', 13, 10, 0 vbr_lsfs_disk_error_msg db 'The system does not support disk operations', 0 lsfs_path db '/kernel/utils/lsfs.bin', 0 kernel_path db '/kernel/kernel.bin', 0 times 446-($-$$) db 0 vbr_size_in_bytes dw 0x00, 0x00, 0x00, 0x00 ; size of the VBR in secotrs (Such that we can load the rest of the VBR) vbr_LBA_address dw 0x00, 0x00, 0x00, 0x00 ; Abselout LBA adress of this VBR, such that we know where to find the FSCI (offset 1MB) vbr_LBA_FSCI dw 0x00, 0x00, 0x00, 0x00 times 510-($-$$) db 0 dw 0x1818; Signature, homemade, sshould it be 0xAA55? ; rest of VBR, which has to be loaded in the first part of the VBR ;%include "filesystems/lsfs/lsfs.nasm" incbin "../lsfs_16-bit/disk.out" ; By specification the max size can be 1MB of the compiled file.