flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
sid123 17 Aug 2013, 06:16
Actually I want to modify this bootloader such that the user is asked to put a kernel file name, and then the boot loader will load the kernel (format *.bin) from the respective file......
BTW (there's a print_string function there and the kernel file string is kern_filename) All the main variables are in the last. I am sorry if this is silly, but with my current assembly knowledge I don't even know a single piece of what to do for modifying this bootloader Here's the Boot Code (Below the License)(HUGGGEEEE) Code: MikeOS -- License ================================================================== Copyright (C) 2006 - 2013 MikeOS Developers -- http://mikeos.berlios.de All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name MikeOS nor the names of any MikeOS contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY MIKEOS DEVELOPERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MIKEOS DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================== Code: ; =====================================================;===================================================== ; The Mike Operating System bootloader ; Copyright (C) 2006 - 2013 MikeOS Developers -- see doc/LICENSE.TXT ; ; Based on a free boot loader by E Dehling. It scans the FAT12 ; floppy for KERNEL.BIN (the MikeOS kernel), loads it and executes it. ; This must grow no larger than 512 bytes (one sector), with the final ; two bytes being the boot signature (AA55h). Note that in FAT12, ; a cluster is the same as a sector: 512 bytes. ; ================================================================== BITS 16 jmp short bootloader_start ; Jump past disk description section nop ; Pad out before disk description ; ------------------------------------------------------------------ ; Disk description table, to make it a valid floppy ; Note: some of these values are hard-coded in the source! ; Values are those used by IBM for 1.44 MB, 3.5" diskette OEMLabel db "MIKEBOOT" ; Disk label BytesPerSector dw 512 ; Bytes per sector SectorsPerCluster db 1 ; Sectors per cluster ReservedForBoot dw 1 ; Reserved sectors for boot record NumberOfFats db 2 ; Number of copies of the FAT RootDirEntries dw 224 ; Number of entries in root dir ; (224 * 32 = 7168 = 14 sectors to read) LogicalSectors dw 2880 ; Number of logical sectors MediumByte db 0F0h ; Medium descriptor byte SectorsPerFat dw 9 ; Sectors per FAT SectorsPerTrack dw 18 ; Sectors per track (36/cylinder) Sides dw 2 ; Number of sides/heads HiddenSectors dd 0 ; Number of hidden sectors LargeSectors dd 0 ; Number of LBA sectors DriveNo dw 0 ; Drive No: 0 Signature db 41 ; Drive signature: 41 for floppy VolumeID dd 00000000h ; Volume ID: any number VolumeLabel db "MIKEOS "; Volume Label: any 11 chars FileSystem db "FAT12 " ; File system type: don't change! ; ------------------------------------------------------------------ ; Main bootloader code bootloader_start: mov ax, 07C0h ; Set up 4K of stack space above buffer add ax, 544 ; 8k buffer = 512 paragraphs + 32 paragraphs (loader) cli ; Disable interrupts while changing stack mov ss, ax mov sp, 4096 sti ; Restore interrupts mov ax, 07C0h ; Set data segment to where we're loaded mov ds, ax ; NOTE: A few early BIOSes are reported to improperly set DL cmp dl, 0 je no_change mov [bootdev], dl ; Save boot device number mov ah, 8 ; Get drive parameters int 13h jc fatal_disk_error and cx, 3Fh ; Maximum sector number mov [SectorsPerTrack], cx ; Sector numbers start at 1 movzx dx, dh ; Maximum head number add dx, 1 ; Head numbers start at 0 - add 1 for total mov [Sides], dx no_change: mov eax, 0 ; Needed for some older BIOSes ; First, we need to load the root directory from the disk. Technical details: ; Start of root = ReservedForBoot + NumberOfFats * SectorsPerFat = logical 19 ; Number of root = RootDirEntries * 32 bytes/entry / 512 bytes/sector = 14 ; Start of user data = (start of root) + (number of root) = logical 334 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; floppy_ok: ; Ready to read first block of data mov ax, 19 ; Root dir starts at logical sector 19 call l2hts mov si, buffer ; Set ES:BX to point to our buffer (see end of code) mov bx, ds mov es, bx mov bx, si mov ah, 2 ; Params for int 13h: read floppy sectors mov al, 14 ; And read 14 of them pusha ; Prepare to enter loop read_root_dir: popa ; In case registers are altered by int 13h pusha stc ; A few BIOSes do not set properly on error int 13h ; Read sectors using BIOS jnc search_dir ; If read went OK, skip ahead call reset_floppy ; Otherwise, reset floppy controller and try again jnc read_root_dir ; Floppy reset OK? jmp reboot ; If not, fatal double error search_dir: popa mov ax, ds ; Root dir is now in [buffer] mov es, ax ; Set DI to this info mov di, buffer mov cx, word [RootDirEntries] ; Search all (224) entries mov ax, 0 ; Searching at offset 0 next_root_entry: xchg cx, dx ; We use CX in the inner loop... mov si, kern_filename ; Start searching for kernel filename mov cx, 11 rep cmpsb je found_file_to_load ; Pointer DI will be at offset 11 add ax, 32 ; Bump searched entries by 1 (32 bytes per entry) mov di, buffer ; Point to next entry add di, ax xchg dx, cx ; Get the original CX back loop next_root_entry mov si, file_not_found ; If kernel is not found, bail out call print_string jmp reboot found_file_to_load: ; Fetch cluster and load FAT into RAM mov ax, word [es:di+0Fh] ; Offset 11 + 15 = 26, contains 1st cluster mov word [cluster], ax mov ax, 1 ; Sector 1 = first sector of first FAT call l2hts mov di, buffer ; ES:BX points to our buffer mov bx, di mov ah, 2 ; int 13h params: read (FAT) sectors mov al, 9 ; All 9 sectors of 1st FAT pusha ; Prepare to enter loop read_fat: popa ; In case registers are altered by int 13h pusha stc int 13h ; Read sectors using the BIOS jnc read_fat_ok ; If read went OK, skip ahead call reset_floppy ; Otherwise, reset floppy controller and try again jnc read_fat ; Floppy reset OK? ; ****************************************************************** fatal_disk_error: ; ****************************************************************** mov si, disk_error ; If not, print error message and reboot call print_string jmp reboot ; Fatal double error read_fat_ok: popa mov ax, 2000h ; Segment where we'll load the kernel mov es, ax mov bx, 0 mov ah, 2 ; int 13h floppy read params mov al, 1 push ax ; Save in case we (or int calls) lose it ; Now we must load the FAT from the disk. Here's how we find out where it starts: ; FAT cluster 0 = media descriptor = 0F0h ; FAT cluster 1 = filler cluster = 0FFh ; Cluster start = ((cluster number) - 2) * SectorsPerCluster + (start of user) ; = (cluster number) + 31 load_file_sector: mov ax, word [cluster] ; Convert sector to logical add ax, 31 call l2hts ; Make appropriate params for int 13h mov ax, 2000h ; Set buffer past what we've already read mov es, ax mov bx, word [pointer] pop ax ; Save in case we (or int calls) lose it push ax stc int 13h jnc calculate_next_cluster ; If there's no error... call reset_floppy ; Otherwise, reset floppy and retry jmp load_file_sector ; In the FAT, cluster values are stored in 12 bits, so we have to ; do a bit of maths to work out whether we're dealing with a byte ; and 4 bits of the next byte -- or the last 4 bits of one byte ; and then the subsequent byte! calculate_next_cluster: mov ax, [cluster] mov dx, 0 mov bx, 3 mul bx mov bx, 2 div bx ; DX = [cluster] mod 2 mov si, buffer add si, ax ; AX = word in FAT for the 12 bit entry mov ax, word [ds:si] or dx, dx ; If DX = 0 [cluster] is even; if DX = 1 then it's odd jz even ; If [cluster] is even, drop last 4 bits of word ; with next cluster; if odd, drop first 4 bits odd: shr ax, 4 ; Shift out first 4 bits (they belong to another entry) jmp short next_cluster_cont even: and ax, 0FFFh ; Mask out final 4 bits next_cluster_cont: mov word [cluster], ax ; Store cluster cmp ax, 0FF8h ; FF8h = end of file marker in FAT12 jae end add word [pointer], 512 ; Increase buffer pointer 1 sector length jmp load_file_sector end: ; We've got the file to load! pop ax ; Clean up the stack (AX was pushed earlier) mov dl, byte [bootdev] ; Provide kernel with boot device info jmp 2000h:0000h ; Jump to entry point of loaded kernel! ; ------------------------------------------------------------------ ; BOOTLOADER SUBROUTINES reboot: mov ax, 0 int 16h ; Wait for keystroke mov ax, 0 int 19h ; Reboot the system print_string: ; Output string in SI to screen pusha mov ah, 0Eh ; int 10h teletype function .repeat: lodsb ; Get char from string cmp al, 0 je .done ; If char is zero, end of string int 10h ; Otherwise, print it jmp short .repeat .done: popa ret reset_floppy: ; IN: [bootdev] = boot device; OUT: carry set on error push ax push dx mov ax, 0 mov dl, byte [bootdev] stc int 13h pop dx pop ax ret l2hts: ; Calculate head, track and sector settings for int 13h ; IN: logical sector in AX, OUT: correct registers for int 13h push bx push ax mov bx, ax ; Save logical sector mov dx, 0 ; First the sector div word [SectorsPerTrack] add dl, 01h ; Physical sectors start at 1 mov cl, dl ; Sectors belong in CL for int 13h mov ax, bx mov dx, 0 ; Now calculate the head div word [SectorsPerTrack] mov dx, 0 div word [Sides] mov dh, dl ; Head/side mov ch, al ; Track pop ax pop bx mov dl, byte [bootdev] ; Set correct device ret ; ------------------------------------------------------------------ ; STRINGS AND VARIABLES kern_filename db "KERNEL BIN" ; MikeOS kernel filename disk_error db "Floppy error! Press any key...", 0 file_not_found db "KERNEL.BIN not found!", 0 bootdev db 0 ; Boot device number cluster dw 0 ; Cluster of the file we want to load pointer dw 0 ; Pointer into Buffer, for loading kernel ; ------------------------------------------------------------------ ; END OF BOOT SECTOR AND BUFFER START times 510-($-$$) db 0 ; Pad remainder of boot sector with zeros dw 0AA55h ; Boot signature (DO NOT CHANGE!) buffer: ; Disk buffer begins (8k after this, stack starts) ; ================================================================== _________________ "Those who can make you believe in absurdities can make you commit atrocities" -- Voltaire https://github.com/Benderx2/R3X XD Last edited by sid123 on 17 Aug 2013, 10:32; edited 5 times in total |
|||
![]() |
|
bitRAKE 17 Aug 2013, 08:32
Maybe try feryno's boot manager? It's no longer on his website, but a copy is available through the wayback machine:
http://web.archive.org/web/20050312161837/http://feryno.host.sk/projects/bmf5doc/index.html IIRC, it already has the features you desire and source code is included. |
|||
![]() |
|
egos 17 Aug 2013, 09:56
I can write simple stage 2 based on this code. 100$
![]() |
|||
![]() |
|
egos 17 Aug 2013, 10:33
There is not enough space. Use stage 2 that holds a copy of the stage 1. Rewrite file name and then run a modified copy.
Last edited by egos on 17 Aug 2013, 10:35; edited 1 time in total |
|||
![]() |
|
sid123 17 Aug 2013, 10:34
I don't understand what you mean (Sorry
![]() |
|||
![]() |
|
sid123 17 Aug 2013, 10:34
egos wrote: There is not enough space. Use stage 2 that holds a copy of the stage 1. Rewrite file name and then run a copy. I don't understand what you mean (Sorry ![]() EDIT : Ooooooooooooooo ![]() Code: %INCLUDE 'bootload.asm' / .................................... Whatever code scan...... ................................... / _________________ "Those who can make you believe in absurdities can make you commit atrocities" -- Voltaire https://github.com/Benderx2/R3X XD |
|||
![]() |
|
TightCoderEx 17 Aug 2013, 16:39
There are probably as many versions of Boot Loader's out there as there are people. The link points to details of one of eleven I've done for myself, none of which incorporate and existing file system, meaning fat12/16/32 NTFS EXT EXT2 etc.
My latest version loads the second stage 50:0 -> 7B0:0 jumps to it and then loads the rest of the image 7B0:0 -> 8B00:0, thus giving me a 500 some odd K disk image in memory. Code: Load_Data: ; Build Disk Access Packet on stack xor eax, eax push eax push ax push 8 ; Absolute start sector (zero indexed). push 80 ; segment 50H push ax ; Offset 0 push 59 ; Number of sectors between 50:0 & 7c0:0 push 16 ; Size of DAP push ss pop ds mov si, sp ; DS:SI pointer to stack mov dx, [bp+11*2] ; Retrieve boot drive, probably 80H HD, SD or USB mov ah, 0x42 int DISK_IO jc @F jmp 0x50:0 ; Jump to second stage. Right now I use Pure64 as the backbone "0S" while I'm developing the user interface portion of my kernel. Then I'll go back to the "OS" part and refine drivers and initialization procedures of my own design. This way I'll be able to test on real hardware and get details of what's going on in real time, not using Bochs, QEMU or any other kind of emulation. In order to give you any constructive help I need to know; (1) What mode you're in when you get to the kernel stage of development "real/protected/long". (2) What is the operating system. In real mode BIOS is probably your operating system (3) What code are you using for system initialization if not staying in real mode. In principle, OS development is pretty simple, but the combinations and permutations after you enter @ 7C0:0 are seemingly infinite. So in order to help you constructively, I need to know more details about the system your developing hardware wise and what your objectives are, beyond loading a kernel file. |
|||
![]() |
|
sid123 17 Oct 2013, 13:08
TightCoderEx wrote: There are probably as many versions of Boot Loader's out there as there are people. The link points to details of one of eleven I've done for myself, none of which incorporate and existing file system, meaning fat12/16/32 NTFS EXT EXT2 etc. 1) Real Mode (BIOS Interrupts and speed!) 2) BIOS (As you said) 3) No Code! If you want more info please tell me. BTW My Kernel structure is like this : +KERNEL 0-24K +DISK BUFFER 24K-32K(FAT16) +EXTERNAL SPACE (to load apps on it) 32K-64K Note: I have developed the Kernel so that it sometimes uses segmentation to break out the 64K Limit, but that's only in rare cases like when an app crashes and another program (I call it MEMx86) breaks the segment out and halts the application and then restores the 64K Limit (Because of maintaining compatibility with MikeOS Apps). (Multitasking is ENABLED) I can write this stuff if i am given more than 512 Bytes,but to be honest I am a very messy coder (I admit it) and thus I require lots of memory space. But the main problem how would I load my Kernel after the second stage? +BOOTLOAD +SECOND STAGE (This will destroy the Memory Structure) +KERNEL (Now the Kernel will be loaded somewhere at 5K) +DISK BUFFER (Will now start at 29K and end at 37K) +APPS (They will now load at 37K instead of MikeOS 32K will cause incompatibility with MikeOS Awesome programs... + Less Memory Space Although that can be solved by using MEMx86) ~Help would be appreciated PS: I look for a Boot-Manager (Like GRUB), rather than changing the bootloader but I you know GRUB launches in PMode but I run the Kernel in RMode |
|||
![]() |
|
egos 18 Oct 2013, 12:30
You can use such stage 2/stage 2 extension that is loaded into extended memory (when it is really needed) but is able to load your kernel into base memory. Or you can implement MB entry point (in your kernel) which will be used to move kernel into base memory, to set RM, and to jump to native RM entry point. Also you can convert your kernel to other format and boot it by corresponding boot loaders.
|
|||
![]() |
|
sid123 01 Nov 2013, 13:04
I did it!
Here it is : ![]() _________________ "Those who can make you believe in absurdities can make you commit atrocities" -- Voltaire https://github.com/Benderx2/R3X XD |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.