From cc1adaa2ddc56640a369ffe324d4555e5b1fd98a Mon Sep 17 00:00:00 2001 From: "Dmitry Kartashov (shurf)" Date: Mon, 28 Apr 2008 19:30:57 +0000 Subject: [PATCH] Added floppy FAT12 boot sector (kernel bootloader) git-svn-id: svn://kolibrios.org@796 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/bootloader/boot_fat12.asm | 287 +++++++++++++++++++++++++ kernel/trunk/bootloader/floppy1440.inc | 19 ++ kernel/trunk/bootloader/floppy1680.inc | 19 ++ kernel/trunk/bootloader/floppy1743.inc | 19 ++ kernel/trunk/bootloader/floppy2880.inc | 19 ++ kernel/trunk/bootloader/readme | 43 ++++ 6 files changed, 406 insertions(+) create mode 100644 kernel/trunk/bootloader/boot_fat12.asm create mode 100644 kernel/trunk/bootloader/floppy1440.inc create mode 100644 kernel/trunk/bootloader/floppy1680.inc create mode 100644 kernel/trunk/bootloader/floppy1743.inc create mode 100644 kernel/trunk/bootloader/floppy2880.inc create mode 100644 kernel/trunk/bootloader/readme diff --git a/kernel/trunk/bootloader/boot_fat12.asm b/kernel/trunk/bootloader/boot_fat12.asm new file mode 100644 index 0000000000..1c01e8e97d --- /dev/null +++ b/kernel/trunk/bootloader/boot_fat12.asm @@ -0,0 +1,287 @@ +; FAT12 boot sector for Kolibri OS +; +; Copyright (C) Alex Nogueira Teixeira +; Copyright (C) Diamond +; Copyright (C) Dmitry Kartashov aka shurf +; +; Distributed under GPL, see file COPYING for details +; +; Version 1.0 + +lf equ 0ah +cr equ 0dh + +pos_read_tmp equ 0700h ;position for temporary read +boot_program equ 07c00h ;position for boot code +seg_read_kernel equ 01000h ;segment to kernel read + + jmp start_program + nop + +; Boot Sector and BPB Structure +include 'floppy1440.inc' +;include 'floppy2880.inc' +;include 'floppy1680.inc' +;include 'floppy1743.inc' + +start_program: + + xor ax,ax + mov ss,ax + mov sp,boot_program + push ss + pop ds + + ; print loading string + mov si,loading+boot_program +loop_loading: + lodsb + or al,al + jz read_root_directory + mov ah,0eh + mov bx,7 + int 10h + jmp loop_loading + +read_root_directory: + push ss + pop es + + ; calculate some disk parameters + ; - beginning sector of RootDir + mov ax,word [BPB_FATSz16+boot_program] + xor cx,cx + mov cl,byte [BPB_NumFATs+boot_program] + mul cx + add ax,word [BPB_RsvdSecCnt+boot_program] + mov word [FirstRootDirSecNum+boot_program],ax ; 19 + mov si,ax + + ; - count of sectors in RootDir + mov bx,word [BPB_BytsPerSec+boot_program] + mov cl,5 ; divide ax by 32 + shr bx,cl ; bx = directory entries per sector + mov ax,word [BPB_RootEntCnt+boot_program] + xor dx,dx + div bx + mov word [RootDirSecs+boot_program],ax ; 14 + + ; - data start + add si,ax ; add beginning sector of RootDir and count sectors in RootDir + mov word [data_start+boot_program],si ; 33 + ; reading root directory + ; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! + mov ah,2 ; read + push ax + + mov ax,word [FirstRootDirSecNum+boot_program] + call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) + pop ax + mov bx,pos_read_tmp ; es:bx read buffer + call read_sector + + mov si,bx ; read buffer address: es:si + mov ax,[RootDirSecs+boot_program] + mul word [BPB_BytsPerSec+boot_program] + add ax,si ; AX = end of root dir. in buffer pos_read_tmp + + ; find kernel file in root directory +loop_find_dir_entry: + push si + mov cx,11 + mov di,kernel_name+boot_program + rep cmpsb ; compare es:si and es:di, cx bytes long + pop si + je found_kernel_file + add si,32 ; next dir. entry + cmp si,ax ; end of directory + jb loop_find_dir_entry + +file_error_message: + mov si,error_message+boot_program + +loop_error_message: + lodsb + or al,al + jz freeze_pc + mov ah,0eh + mov bx,7 + int 10h + jmp loop_error_message + +freeze_pc: + jmp $ ; endless loop + + ; === KERNEL FOUND. LOADING... === + +found_kernel_file: + mov bp,[si+01ah] ; first cluster of kernel file + ; + mov [cluster1st+boot_program],bp ; starting cluster of kernel file + ; <\diamond> + + ; reading first FAT table + mov ax,word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number + call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) + mov bx,pos_read_tmp ; es:bx read position + mov ah,2 ; ah=2 (read) + mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors) + call read_sector + jc file_error_message ; read error + + mov ax,seg_read_kernel + mov es,ax + xor bx,bx ; es:bx = 1000h:0000h + + + ; reading kernel file +loop_obtains_kernel_data: + ; read one cluster of file + call obtain_cluster + jc file_error_message ; read error + + ; add one cluster length to segment:offset + push bx + mov bx,es + mov ax,word [BPB_BytsPerSec+boot_program] ;\ + movsx cx,byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!! + mul cx ; | out this from loop !!! + shr ax,4 ;/ + add bx,ax + mov es,bx + pop bx + + mov di,bp + shr di,1 + pushf + add di,bp ; di = bp * 1.5 + add di,pos_read_tmp + mov ax,[di] ; read next entry from FAT-chain + popf + jc move_4_right + and ax,0fffh + jmp verify_end_sector +move_4_right: + mov cl,4 + shr ax,cl +verify_end_sector: + cmp ax,0ff8h ; last cluster + jae execute_kernel + mov bp,ax + jmp loop_obtains_kernel_data + +execute_kernel: + ; + mov ax,'KL' + push 0 + pop ds + mov si,loader_block+boot_program + ; + push word seg_read_kernel + push word 0 + retf ; jmp far 1000:0000 + + +;------------------------------------------ + ; loading cluster from file to es:bx +obtain_cluster: + ; bp - cluster number to read + ; carry = 0 -> read OK + ; carry = 1 -> read ERROR + + ; print one dot + push bx + mov ax,0e2eh ; ah=0eh (teletype), al='.' + xor bh,bh + int 10h + + ; convert cluster number to sector number + mov ax,bp ; data cluster to read + sub ax,2 + xor bx,bx + mov bl,byte [BPB_SecPerClus+boot_program] + mul bx + add ax,word [data_start+boot_program] + pop bx + +writesec: + call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) +patchhere: + mov ah,2 ; ah=2 (read) + mov al,byte [BPB_SecPerClus+boot_program] ; al=(one cluster) + call read_sector + retn +;------------------------------------------ + +;------------------------------------------ + ; read sector from disk +read_sector: + push bp + mov bp,20 ; try 20 times +newread: + dec bp + jz file_error_message + push ax bx cx dx + int 13h + pop dx cx bx ax + jc newread + pop bp + retn +;------------------------------------------ + ; convert abs. sector number (AX) to BIOS T:H:S + ; sector number = (abs.sector%BPB_SecPerTrk)+1 + ; pre.track number = (abs.sector/BPB_SecPerTrk) + ; head number = pre.track number%BPB_NumHeads + ; track number = pre.track number/BPB_NumHeads + ; Return: cl - sector number + ; ch - track number + ; dl - drive number (0 = a:) + ; dh - head number +conv_abs_to_THS: + push bx + mov bx,word [BPB_SecPerTrk+boot_program] + xor dx,dx + div bx + inc dx + mov cl, dl ; cl = sector number + mov bx,word [BPB_NumHeads+boot_program] + xor dx,dx + div bx + ; !!!!!!! ax = track number, dx = head number + mov ch,al ; ch=track number + xchg dh,dl ; dh=head number + mov dl,0 ; dl=0 (drive 0 (a:)) + pop bx + retn +;------------------------------------------ + +loading db cr,lf,'Starting system ',00h +error_message db 13,10 +kernel_name db 'KERNEL MNT ?',cr,lf,00h +FirstRootDirSecNum dw ? +RootDirSecs dw ? +data_start dw ? + +; +write1st: + push cs + pop ds + mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3 + mov ax,[cluster1st+boot_program] + push 1000h + pop es + xor bx,bx + call writesec + mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2 + retf +cluster1st dw ? +loader_block: + db 1 + dw 0 + dw write1st+boot_program + dw 0 +; <\diamond> + +times 0x1fe-$ db 00h + + db 55h,0aah ;boot signature diff --git a/kernel/trunk/bootloader/floppy1440.inc b/kernel/trunk/bootloader/floppy1440.inc new file mode 100644 index 0000000000..678e2d35fd --- /dev/null +++ b/kernel/trunk/bootloader/floppy1440.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 1 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) + BPB_TotSec16 dw 2880 ; count of sectors on the volume (2880 for 1.44 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 18 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/trunk/bootloader/floppy1680.inc b/kernel/trunk/bootloader/floppy1680.inc new file mode 100644 index 0000000000..ef754de8d6 --- /dev/null +++ b/kernel/trunk/bootloader/floppy1680.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 1 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 112 ; count of 32-byte dir. entries (112*32 = 7 sectors) + BPB_TotSec16 dw 3360 ; count of sectors on the volume (3360 for 1.68 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 10 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 21 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/trunk/bootloader/floppy1743.inc b/kernel/trunk/bootloader/floppy1743.inc new file mode 100644 index 0000000000..bd777301fc --- /dev/null +++ b/kernel/trunk/bootloader/floppy1743.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 1 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) + BPB_TotSec16 dw 3486 ; count of sectors on the volume (3486 for 1.74 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 11 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 21 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/trunk/bootloader/floppy2880.inc b/kernel/trunk/bootloader/floppy2880.inc new file mode 100644 index 0000000000..8a52c059ca --- /dev/null +++ b/kernel/trunk/bootloader/floppy2880.inc @@ -0,0 +1,19 @@ + BS_OEMName db 'KOLIBRI ' ; db 8 + BPB_BytsPerSec dw 512 ; bytes per sector + BPB_SecPerClus db 2 ; sectors per cluster + BPB_RsvdSecCnt dw 1 ; number of reserver sectors + BPB_NumFATs db 2 ; count of FAT data structures + BPB_RootEntCnt dw 240 ; count of 32-byte dir. entries (240*32 = 15 sectors) + BPB_TotSec16 dw 5760 ; count of sectors on the volume (5760 for 2.88 mbytes disk) + BPB_Media db 0f0h ; f0 - used for removable media + BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT + BPB_SecPerTrk dw 36 ; sectors per track + BPB_NumHeads dw 2 ; number of heads + BPB_HiddSec dd 0 ; count of hidden sectors + BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) + BS_DrvNum db 0 ; int 13h drive number + BS_Reserved db 0 ; reserved + BS_BootSig db 29h ; Extended boot signature + BS_VolID dd 0 ; Volume serial number + BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) + BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/trunk/bootloader/readme b/kernel/trunk/bootloader/readme new file mode 100644 index 0000000000..bbcc50f2e3 --- /dev/null +++ b/kernel/trunk/bootloader/readme @@ -0,0 +1,43 @@ +Загрузочный сектор для ОС Колибри (FAT12, дискета) + +- Описание + Позволяет загружать KERNEL.MNT с дискет/образов + объёмом 1.44M, 1.68M, 1.72M и 2.88M + Для выбора объёма диска, для которого надо собрать + загрузочный сектор, необходимо в файле boot_fat12.asm + раскомментировать строку вида: + include 'floppy????.inc' + для необходимого объёма диска. Доступные варианты: + floppy1440.inc, + floppy1680.inc, + floppy1743.inc и floppy2880.inc + +- Сборка + fasm boot_fat12.asm + +- Для записи загрузочного сектора на диск/образ под Linux + можно воспользоваться следующей командой: + dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc + +--------------------------------------------------------------------- + +Floppy FAT12 boot sector for KolibriOS. + +- Description + Allows booting KERNEL.MNT floppies/images + with volumes of 1.44M, 1.68M, 1.72M and 2.88M + To select the volume of the disk, which should gather + boot sector, it was necessary in file boot_fat12.asm + uncomment line: + include 'floppy????. inc' + for the necessary disk volume. Available options is: + floppy1440.inc, + floppy1680.inc, + floppy1743.inc and floppy2880.inc + +- Compile + fasm boot_fat12.asm + +- To write boot sector to the floppy/image under Linux + you can use the following command: + dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc