--- /dev/null
+#
+# FreeLoader
+# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+
+export CC = gcc
+export LD = ld
+export AR = ar
+export RM = cmd /C del
+export CP = cmd /C copy
+export NASM = nasm
+export MAKE = make
+
+.PHONY : bootsect freeldr install clean
+
+all: bootsect freeldr install
+
+bootsect:
+ $(MAKE) -C bootsect
+
+freeldr: bootsect
+ $(MAKE) -C freeldr
+
+install:
+ $(MAKE) -C install
+
+clean:
+ $(RM) *.bin
+++ /dev/null
-; BOOTSECT.ASM
-; FAT12/16 Boot Sector
-; Copyright (c) 1998 Brian Palmer
-
-org 7c00h
-
-segment .text
-
-bits 16
-
-start:
- jmp short main
- nop
-
-OEMName db 'FreeLDR!'
-BytesPerSector dw 512
-SectsPerCluster db 1
-ReservedSectors dw 1
-NumberOfFats db 2
-MaxRootEntries dw 224
-TotalSectors dw 2880
-MediaDescriptor db 0f0h
-SectorsPerFat dw 9
-SectorsPerTrack dw 18
-NumberOfHeads dw 2
-HiddenSectors dd 0
-TotalSectorsBig dd 0
-BootDrive db 0
-Reserved db 0
-ExtendSig db 29h
-SerialNumber dd 00000000h
-VolumeLabel db 'FreeLoader!'
-FileSystem db 'FAT12 '
-
-main:
- cli
- cld
- xor ax,ax
- mov ss,ax
- mov sp,7c00h ; Setup a stack
- mov ax,cs ; Setup segment registers
- mov ds,ax ; Make DS correct
- mov es,ax ; Make ES correct
-
-
- sti ; Enable ints now
- mov [BootDrive],dl ; Save the boot drive
- xor ax,ax ; Zero out AX
-
- ; Reset disk controller
- int 13h
- jnc Continue1
- jmp BadBoot ; Reset failed...
-
-Continue1:
- ; Now we must find our way to the first sector of the root directory
- xor ax,ax
- xor cx,cx
- mov al,[NumberOfFats] ; Number of fats
- mul WORD [SectorsPerFat] ; Times sectors per fat
- add ax,WORD [HiddenSectors]
- adc dx,WORD [HiddenSectors+2] ; Add the number of hidden sectors
- add ax,[ReservedSectors] ; Add the number of reserved sectors
- adc dx,cx ; Add carry bit
- push ax ; Store it on the stack
- push dx ; Save 32-bit logical start sector
- push ax
- push dx ; Save it for later use also
- ; DX:AX now has the number of the starting sector of the root directory
-
- ; Now calculate the size of the root directory
- mov ax,0020h ; Size of dir entry
- mul WORD [MaxRootEntries] ; Times the number of entries
- mov bx,[BytesPerSector]
- add ax,bx
- dec ax
- div bx ; Divided by the size of a sector
- ; AX now has the number of root directory sectors
-
- xchg ax,cx ; Now CX has number of sectors
- pop dx
- pop ax ; Restore logical sector start
- push cx ; Save for later use
- mov bx,7c0h ; We will load the root directory
- add bx,20h ; Right after the boot sector in memory
- mov es,bx
- xor bx,bx ; We will load it to [0000:7e00h]
- call ReadSectors ; Read the sectors
- jnc Continue2 ; BadBoot on error
- jmp BadBoot
-Continue2:
-
-
- ; Now we have to find our way through the root directory to
- ; The OSLOADER.SYS file
- mov bx,[MaxRootEntries]; Search entire root directory
- mov ax,7e0h ; We loaded at 07e0:0000
- mov es,ax
- xor di,di
- mov si,filename
- mov cx,11
- rep cmpsb ; Compare filenames
- jz FoundFile ; If same we found it
- dec bx
- jnz FindFile
- jmp ErrBoot
-
-FindFile:
- mov ax,es ; We didn't find it in the previous dir entry
- add ax,2 ; So lets move to the next one
- mov es,ax ; And search again
- xor di,di
- mov si,filename
- mov cx,11
- rep cmpsb ; Compare filenames
- jz FoundFile ; If same we found it
- dec bx ; Keep searching till we run out of dir entries
- jnz FindFile ; Last entry?
- jmp ErrBoot
-
-FoundFile:
- xor di,di ; ES:DI has dir entry
- xor dx,dx
- mov ax,WORD [es:di+1ah] ; Get start cluster
- dec ax
- dec ax
- xor ch,ch
- mov cl,BYTE [SectsPerCluster] ; Times sectors per cluster
- mul cx
- pop cx ; Get number of sectors for root dir
- add ax,cx
- adc dx,0
- pop cx ; Get logical start sector of
- pop bx ; Root directory
- add ax,bx ; Now we have DX:AX with the logical start
- adc dx,cx ; Sector of OSLOADER.SYS
- push ax
- push dx
- mov ax,WORD [es:di+1ch]
- mov dx,WORD [es:di+1eh]
- mov bx,[BytesPerSector]
- dec bx
- add ax,bx
- adc dx,0
- div WORD [BytesPerSector]
- xchg ax,cx ; Now CX has number of sectors of OSLOADER.SYS
- pop dx
- pop ax
- mov bx,800h
- mov es,bx
- xor bx,bx ; Load ROSLDR at 0000:8000h
- call ReadSectors ; Load it
- jc BadBoot
- mov dl,[BootDrive]
- xor ax,ax
- push ax
- mov ax,8000h
- push ax ; We will do a far return to 0000:8000h
- retf ; Transfer control to ROSLDR
-
-
-
-; Reads logical sectors into [ES:BX]
-; DX:AX has logical sector number to read
-; CX has number of sectors to read
-; CarryFlag set on error
-ReadSectors:
- push ax
- push dx
- push cx
- xchg ax,cx
- xchg ax,dx
- xor dx,dx
- div WORD [SectorsPerTrack]
- xchg ax,cx
- div WORD [SectorsPerTrack] ; Divide logical by SectorsPerTrack
- inc dx ; Sectors numbering starts at 1 not 0
- xchg cx,dx
- div WORD [NumberOfHeads] ; Number of heads
- mov dh,dl ; Head to DH, drive to DL
- mov dl,[BootDrive] ; Drive number
- mov ch,al ; Cylinder in CX
- ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits
- ror ah,1 ; in CL shifted to bits 6 & 7
- or cl,ah ; Or with sector number
- mov ax,513
- int 13h ; DISK - READ SECTORS INTO MEMORY
- ; AL = number of sectors to read, CH = track, CL = sector
- ; DH = head, DL = drive, ES:BX -> buffer to fill
- ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read
- pop cx
- pop dx
- pop ax
- jc ReadFail
- inc ax ;Increment Sector to Read
- jnz NoCarry
- inc dx
-
-
-NoCarry:
- push bx
- mov bx,es
- add bx,20h
- mov es,bx
- pop bx
- ; Increment read buffer for next sector
- loop ReadSectors ; Read next sector
-
-
-ReadFail:
- ret
-
-
-
-; Displays a bad boot message
-; And reboots
-BadBoot:
- mov si,msgDiskError ; Bad boot disk message
- call PutChars ; Display it
- mov si,msgAnyKey ; Press any key message
- call PutChars ; Display it
-
- jmp Reboot
-
-; Displays an error message
-; And reboots
-ErrBoot:
- mov si,msgFreeLdr ; FreeLdr not found message
- call PutChars ; Display it
- mov si,msgAnyKey ; Press any key message
- call PutChars ; Display it
-
-Reboot:
- xor ax,ax
- int 16h ; Wait for a keypress
- int 19h ; Reboot
-
-PutChars:
- lodsb
- or al,al
- jz short Done
- mov ah,0eh
- mov bx,07h
- int 10h
- jmp short PutChars
-Done:
- retn
-
-msgDiskError db 'Disk error',0dh,0ah,0
-msgFreeLdr db 'FREELDR.SYS not found',0dh,0ah,0
-msgAnyKey db 'Press any key to continue.',0dh,0ah,0
-filename db 'FREELDR SYS'
-
- times 510-($-$$) db 0 ; Pad to 510 bytes
- dw 0aa55h ; BootSector signature
-
+++ /dev/null
-nasm -o bootsect.bin -f bin bootsect.asm
-nasm -o btsect32.bin -f bin btsect32.asm
\ No newline at end of file
--- /dev/null
+#
+# FreeLoader
+# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+
+export CC = gcc
+export LD = ld
+export AR = ar
+export RM = cmd /C del
+export CP = cmd /C copy
+export NASM = nasm
+
+.PHONY : clean
+
+all: fat.bin fat32.bin bin2c.exe split.exe stubit.exe
+
+fat.bin: fat.asm bin2c.exe split.exe
+ $(NASM) -o fat_tmp.bin -f bin fat.asm
+ split fat_tmp.bin fat.bin fatstub.bin 512
+ $(RM) fat_tmp.bin
+ bin2c fat.bin fat.h fat_data
+
+fat32.bin: fat32.asm bin2c.exe
+ $(NASM) -o fat32.bin -f bin fat32.asm
+ bin2c fat32.bin fat32.h fat32_data
+
+bin2c.exe: bin2c.c
+ $(CC) -o bin2c.exe bin2c.c
+
+split.exe: split.c
+ $(CC) -o split.exe split.c
+
+stubit.exe: stubit.c
+ $(CC) -o stubit.exe stubit.c
+
+clean:
+ $(RM) *.bin
+ $(RM) *.exe
+ $(RM) *.h
#include <stdio.h>
-char in_filename[260];
-char out_filename[260];
FILE *in;
FILE *out;
-int main(void)
+int main(int argc, char *argv[])
{
unsigned char ch;
int cnt = 0;
- printf("Enter data filename: ");
- scanf("%s", in_filename);
- printf("Enter output filename: ");
- scanf("%s", out_filename);
+ if (argc < 4)
+ {
+ printf("usage: bin2c infile.bin outfile.h array_name\n");
+ return -1;
+ }
- if ((in = fopen(in_filename, "rb")) == NULL)
+ if ((in = fopen(argv[1], "rb")) == NULL)
{
printf("Couldn't open data file.\n");
- return 0;
+ return -1;
}
- if ((out = fopen(out_filename, "wb")) == NULL)
+ if ((out = fopen(argv[2], "wb")) == NULL)
{
printf("Couldn't open output file.\n");
- return 0;
+ return -1;
}
- fprintf(out, "unsigned char data[] = {\n");
+ fprintf(out, "unsigned char %s[] = {\n", argv[3]);
ch = fgetc(in);
while (!feof(in))
+++ /dev/null
-unsigned char data[] = {
-
-0xeb, 0x3c, 0x90, 0x46, 0x72, 0x65, 0x65, 0x4c, 0x44, 0x52, 0x21, 0x00, 0x02, 0x01, 0x01, 0x00,
-0x02, 0x00, 0x02, 0x40, 0x0b, 0xf0, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x46, 0x72, 0x65, 0x65, 0x4c,
-0x6f, 0x61, 0x64, 0x65, 0x72, 0x21, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0xfa, 0xfc,
-0x31, 0xc0, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8c, 0xc8, 0x8e, 0xd8, 0x8e, 0xc0, 0xfb, 0x88, 0x16,
-0x24, 0x7c, 0x31, 0xc0, 0xcd, 0x13, 0x73, 0x03, 0xe9, 0x0b, 0x01, 0x31, 0xc0, 0x31, 0xc9, 0xa0,
-0x10, 0x7c, 0xf7, 0x26, 0x16, 0x7c, 0x03, 0x06, 0x1c, 0x7c, 0x13, 0x16, 0x1e, 0x7c, 0x03, 0x06,
-0x0e, 0x7c, 0x11, 0xca, 0x50, 0x52, 0x50, 0x52, 0xb8, 0x20, 0x00, 0xf7, 0x26, 0x11, 0x7c, 0x8b,
-0x1e, 0x0b, 0x7c, 0x01, 0xd8, 0x48, 0xf7, 0xf3, 0x91, 0x5a, 0x58, 0x51, 0xbb, 0xc0, 0x07, 0x81,
-0xc3, 0x20, 0x00, 0x8e, 0xc3, 0x31, 0xdb, 0xe8, 0x8c, 0x00, 0x73, 0x03, 0xe9, 0xc7, 0x00, 0x8b,
-0x1e, 0x11, 0x7c, 0xb8, 0xe0, 0x07, 0x8e, 0xc0, 0x31, 0xff, 0xbe, 0xd8, 0x7d, 0xb9, 0x0b, 0x00,
-0xf3, 0xa6, 0x74, 0x1f, 0x4b, 0x75, 0x03, 0xe9, 0xbb, 0x00, 0x8c, 0xc0, 0x05, 0x02, 0x00, 0x8e,
-0xc0, 0x31, 0xff, 0xbe, 0xd8, 0x7d, 0xb9, 0x0b, 0x00, 0xf3, 0xa6, 0x74, 0x06, 0x4b, 0x75, 0xea,
-0xe9, 0xa2, 0x00, 0x31, 0xff, 0x31, 0xd2, 0x26, 0x8b, 0x45, 0x1a, 0x48, 0x48, 0x30, 0xed, 0x8a,
-0x0e, 0x0d, 0x7c, 0xf7, 0xe1, 0x59, 0x01, 0xc8, 0x81, 0xd2, 0x00, 0x00, 0x59, 0x5b, 0x01, 0xd8,
-0x11, 0xca, 0x50, 0x52, 0x26, 0x8b, 0x45, 0x1c, 0x26, 0x8b, 0x55, 0x1e, 0x8b, 0x1e, 0x0b, 0x7c,
-0x4b, 0x01, 0xd8, 0x81, 0xd2, 0x00, 0x00, 0xf7, 0x36, 0x0b, 0x7c, 0x91, 0x5a, 0x58, 0xbb, 0x00,
-0x08, 0x8e, 0xc3, 0x31, 0xdb, 0xe8, 0x0e, 0x00, 0x72, 0x4c, 0x8a, 0x16, 0x24, 0x7c, 0x31, 0xc0,
-0x50, 0xb8, 0x00, 0x80, 0x50, 0xcb, 0x50, 0x52, 0x51, 0x91, 0x92, 0x31, 0xd2, 0xf7, 0x36, 0x18,
-0x7c, 0x91, 0xf7, 0x36, 0x18, 0x7c, 0x42, 0x87, 0xca, 0xf7, 0x36, 0x1a, 0x7c, 0x88, 0xd6, 0x8a,
-0x16, 0x24, 0x7c, 0x88, 0xc5, 0xd0, 0xcc, 0xd0, 0xcc, 0x08, 0xe1, 0xb8, 0x01, 0x02, 0xcd, 0x13,
-0x59, 0x5a, 0x58, 0x72, 0x10, 0x40, 0x75, 0x01, 0x42, 0x53, 0x8c, 0xc3, 0x81, 0xc3, 0x20, 0x00,
-0x8e, 0xc3, 0x5b, 0xe2, 0xc1, 0xc3, 0xbe, 0x96, 0x7d, 0xe8, 0x1b, 0x00, 0xbe, 0xbb, 0x7d, 0xe8,
-0x15, 0x00, 0xe9, 0x0c, 0x00, 0xbe, 0xa3, 0x7d, 0xe8, 0x0c, 0x00, 0xbe, 0xbb, 0x7d, 0xe8, 0x06,
-0x00, 0x31, 0xc0, 0xcd, 0x16, 0xcd, 0x19, 0xac, 0x08, 0xc0, 0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07,
-0x00, 0xcd, 0x10, 0xeb, 0xf2, 0xc3, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72,
-0x0d, 0x0a, 0x00, 0x46, 0x52, 0x45, 0x45, 0x4c, 0x44, 0x52, 0x2e, 0x53, 0x59, 0x53, 0x20, 0x6e,
-0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x0d, 0x0a, 0x00, 0x50, 0x72, 0x65, 0x73, 0x73,
-0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x74,
-0x69, 0x6e, 0x75, 0x65, 0x2e, 0x0d, 0x0a, 0x00, 0x46, 0x52, 0x45, 0x45, 0x4c, 0x44, 0x52, 0x20,
-0x53, 0x59, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
-};
\ No newline at end of file
+++ /dev/null
-unsigned char data[] = {
-
-0xeb, 0x58, 0x90, 0x46, 0x72, 0x65, 0x65, 0x4c, 0x44, 0x52, 0x21, 0x00, 0x02, 0x01, 0x01, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x46, 0x72, 0x65, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x65,
-0x72, 0x21, 0x46, 0x41, 0x54, 0x33, 0x32, 0x20, 0x20, 0x20, 0xfa, 0xfc, 0x31, 0xc0, 0x8e, 0xd0,
-0xbc, 0x00, 0x7c, 0x8c, 0xc8, 0x8e, 0xd8, 0x8e, 0xc0, 0xfb, 0x88, 0x16, 0x40, 0x7c, 0x31, 0xc0,
-0xcd, 0x13, 0x73, 0x03, 0xe9, 0x05, 0x01, 0x31, 0xd2, 0xb8, 0x0e, 0x00, 0x03, 0x06, 0x1c, 0x7c,
-0x13, 0x16, 0x1e, 0x7c, 0xb9, 0x01, 0x00, 0xbb, 0xe0, 0x07, 0x8e, 0xc3, 0x31, 0xdb, 0xe8, 0xab,
-0x00, 0x73, 0x03, 0xe9, 0xe6, 0x00, 0x66, 0xa1, 0x2c, 0x7c, 0x66, 0x3d, 0xf8, 0xff, 0xff, 0x0f,
-0x72, 0x03, 0xe9, 0xe6, 0x00, 0xbb, 0x00, 0x08, 0x8e, 0xc3, 0xe8, 0xb2, 0x01, 0x31, 0xdb, 0x8a,
-0x1e, 0x0d, 0x7c, 0xc1, 0xe3, 0x04, 0xb8, 0x00, 0x08, 0x8e, 0xc0, 0x31, 0xff, 0xbe, 0xee, 0x7d,
-0xb9, 0x0b, 0x00, 0xf3, 0xa6, 0x74, 0x2a, 0x4b, 0x75, 0x03, 0xe9, 0xbe, 0x00, 0x8c, 0xc0, 0x05,
-0x02, 0x00, 0x8e, 0xc0, 0x31, 0xff, 0xbe, 0xee, 0x7d, 0xb9, 0x0b, 0x00, 0xf3, 0xa6, 0x74, 0x11,
-0x4b, 0x75, 0xea, 0x66, 0xa1, 0x2c, 0x7c, 0xe8, 0x16, 0x01, 0x66, 0xa3, 0x2c, 0x7c, 0xe9, 0xa5,
-0xff, 0x31, 0xff, 0x31, 0xd2, 0x26, 0x8b, 0x45, 0x14, 0x66, 0xc1, 0xe0, 0x10, 0x26, 0x8b, 0x45,
-0x1a, 0xbb, 0x00, 0x08, 0x8e, 0xc3, 0x66, 0x3d, 0xf8, 0xff, 0xff, 0x0f, 0x73, 0x22, 0x66, 0x50,
-0x31, 0xdb, 0x06, 0xe8, 0x49, 0x01, 0x07, 0x31, 0xdb, 0x8a, 0x1e, 0x0d, 0x7c, 0xc1, 0xe3, 0x05,
-0x8c, 0xc0, 0x01, 0xd8, 0x8e, 0xc0, 0x66, 0x58, 0x06, 0xe8, 0xd4, 0x00, 0x07, 0xe9, 0xd6, 0xff,
-0x8a, 0x16, 0x40, 0x7c, 0x31, 0xc0, 0x50, 0xb8, 0x00, 0x80, 0x50, 0xcb, 0x50, 0x52, 0x51, 0x91,
-0x92, 0x31, 0xd2, 0xf7, 0x36, 0x18, 0x7c, 0x91, 0xf7, 0x36, 0x18, 0x7c, 0x42, 0x87, 0xca, 0xf7,
-0x36, 0x1a, 0x7c, 0x88, 0xd6, 0x8a, 0x16, 0x40, 0x7c, 0x88, 0xc5, 0xd0, 0xcc, 0xd0, 0xcc, 0x08,
-0xe1, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x59, 0x5a, 0x58, 0x72, 0x10, 0x40, 0x75, 0x01, 0x42, 0x53,
-0x8c, 0xc3, 0x81, 0xc3, 0x20, 0x00, 0x8e, 0xc3, 0x5b, 0xe2, 0xc1, 0xc3, 0xbe, 0xac, 0x7d, 0xe8,
-0x1b, 0x00, 0xbe, 0xd1, 0x7d, 0xe8, 0x15, 0x00, 0xe9, 0x0c, 0x00, 0xbe, 0xb9, 0x7d, 0xe8, 0x0c,
-0x00, 0xbe, 0xd1, 0x7d, 0xe8, 0x06, 0x00, 0x31, 0xc0, 0xcd, 0x16, 0xcd, 0x19, 0xac, 0x08, 0xc0,
-0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0xeb, 0xf2, 0xc3, 0x44, 0x69, 0x73, 0x6b,
-0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0d, 0x0a, 0x00, 0x46, 0x52, 0x45, 0x45, 0x4c, 0x44, 0x52,
-0x2e, 0x53, 0x59, 0x53, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x0d, 0x0a,
-0x00, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74,
-0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x0d, 0x0a, 0x00, 0x46, 0x52,
-0x45, 0x45, 0x4c, 0x44, 0x52, 0x20, 0x53, 0x59, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa,
-0x66, 0xc1, 0xe0, 0x02, 0x66, 0x89, 0xc1, 0x66, 0x31, 0xd2, 0x66, 0x0f, 0xb7, 0x1e, 0x0b, 0x7c,
-0x66, 0x53, 0x66, 0xf7, 0xf3, 0x66, 0x0f, 0xb7, 0x1e, 0x0e, 0x7c, 0x66, 0x01, 0xd8, 0x66, 0x0f,
-0xb7, 0x1e, 0x1c, 0x7c, 0x66, 0x01, 0xd8, 0x66, 0x5b, 0x66, 0x4b, 0x66, 0x21, 0xd9, 0x66, 0x51,
-0x66, 0xc1, 0xc8, 0x10, 0x89, 0xc2, 0x66, 0xc1, 0xc8, 0x10, 0xbb, 0x00, 0x70, 0x8e, 0xc3, 0x31,
-0xdb, 0xb9, 0x01, 0x00, 0xe8, 0xf5, 0xfe, 0x73, 0x03, 0xe9, 0x30, 0xff, 0xbb, 0x00, 0x70, 0x8e,
-0xc3, 0x66, 0x59, 0x26, 0x66, 0x67, 0x8b, 0x01, 0x66, 0x25, 0xff, 0xff, 0xff, 0x0f, 0xc3, 0x66,
-0x48, 0x66, 0x48, 0x66, 0x31, 0xd2, 0x66, 0x0f, 0xb6, 0x1e, 0x0d, 0x7c, 0x66, 0xf7, 0xe3, 0x66,
-0x50, 0x66, 0x31, 0xd2, 0x66, 0x0f, 0xb6, 0x06, 0x10, 0x7c, 0x66, 0xf7, 0x26, 0x24, 0x7c, 0x66,
-0x0f, 0xb7, 0x1e, 0x0e, 0x7c, 0x66, 0x01, 0xd8, 0x66, 0x03, 0x06, 0x1c, 0x7c, 0x66, 0x5b, 0x66,
-0x01, 0xd8, 0x66, 0xc1, 0xc8, 0x10, 0x89, 0xc2, 0x66, 0xc1, 0xc8, 0x10, 0x31, 0xdb, 0x0f, 0xb6,
-0x0e, 0x0d, 0x7c, 0xe8, 0x96, 0xfe, 0x73, 0x03, 0xe9, 0xd1, 0xfe, 0xc3, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
-};
\ No newline at end of file
--- /dev/null
+; FAT.ASM
+; FAT12/16 Boot Sector
+; Copyright (c) 1998, 2001 Brian Palmer
+
+
+
+; This is a FAT12/16 file system boot sector
+; that searches the entire root directory
+; for the file freeldr.sys and loads it into
+; memory.
+;
+; The stack is set to 0000:7C00 so that the first
+; DWORD pushed will be placed at 0000:7BFC
+;
+; When it locates freeldr.sys on the disk it will
+; load the first sector of the file to 0000:7E00
+; With the help of this sector we should be able
+; to load the entire file off the disk, no matter
+; how fragmented it is.
+;
+; We load the entire FAT table into memory at
+; 7000:0000. This improves the speed of floppy disk
+; boots dramatically.
+
+
+
+org 7c00h
+
+segment .text
+
+bits 16
+
+start:
+ jmp short main
+ nop
+
+OEMName db 'FrLdr1.0'
+BytesPerSector dw 512
+SectsPerCluster db 1
+ReservedSectors dw 1
+NumberOfFats db 2
+MaxRootEntries dw 224
+TotalSectors dw 2880
+MediaDescriptor db 0f0h
+SectorsPerFat dw 9
+SectorsPerTrack dw 18
+NumberOfHeads dw 2
+HiddenSectors dd 0
+TotalSectorsBig dd 0
+BootDrive db 0
+Reserved db 0
+ExtendSig db 29h
+SerialNumber dd 00000000h
+VolumeLabel db 'NO NAME '
+FileSystem db 'FAT12 '
+
+main:
+ cli
+ cld
+ xor ax,ax
+ mov ss,ax
+ mov bp,7c00h
+ mov sp,bp ; Setup a stack
+ mov ax,cs ; Setup segment registers
+ mov ds,ax ; Make DS correct
+ mov es,ax ; Make ES correct
+
+
+ sti ; Enable ints now
+ mov [BYTE bp+BootDrive],dl ; Save the boot drive
+ xor ax,ax ; Zero out AX
+
+ ; Reset disk controller
+ int 13h
+ jnc Continue1
+ jmp BadBoot ; Reset failed...
+
+Continue1:
+ ; Now we must find our way to the first sector of the root directory
+ xor ax,ax
+ xor dx,dx
+ mov al,[BYTE bp+NumberOfFats] ; Number of fats
+ mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat
+ add ax,WORD [BYTE bp+HiddenSectors]
+ adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors
+ add ax,WORD [BYTE bp+ReservedSectors] ; Add the number of reserved sectors
+ adc dx,byte 0 ; Add carry bit
+ push ax ; Store it on the stack
+ push dx ; Save 32-bit logical start sector
+ push ax
+ push dx ; Save it for later use also
+ ; DX:AX now has the number of the starting sector of the root directory
+
+ ; Now calculate the size of the root directory
+ mov ax,0020h ; Size of dir entry
+ mul WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
+ mov bx,[BYTE bp+BytesPerSector]
+ add ax,bx
+ dec ax
+ div bx ; Divided by the size of a sector
+ ; AX now has the number of root directory sectors
+
+ xchg ax,cx ; Now CX has number of sectors
+ pop dx
+ pop ax ; Restore logical sector start
+ push cx ; Save number of root dir sectors for later use
+ mov bx,7c0h ; We will load the root directory
+ add bx,byte 20h ; Right after the boot sector in memory
+ mov es,bx
+ xor bx,bx ; We will load it to [0000:7e00h]
+ call ReadSectors ; Read the sectors
+
+
+ ; Now we have to find our way through the root directory to
+ ; The OSLOADER.SYS file
+ mov bx,[BYTE bp+MaxRootEntries]; Search entire root directory
+ mov ax,7e0h ; We loaded at 07e0:0000
+ mov es,ax
+ xor di,di
+ mov si,filename
+ mov cx,11
+ rep cmpsb ; Compare filenames
+ jz FoundFile ; If same we found it
+ dec bx
+ jnz FindFile
+ jmp ErrBoot
+
+FindFile:
+ mov ax,es ; We didn't find it in the previous dir entry
+ add ax,byte 2 ; So lets move to the next one
+ mov es,ax ; And search again
+ xor di,di
+ mov si,filename
+ mov cx,11
+ rep cmpsb ; Compare filenames
+ jz FoundFile ; If same we found it
+ dec bx ; Keep searching till we run out of dir entries
+ jnz FindFile ; Last entry?
+ jmp ErrBoot
+
+FoundFile:
+ ; We found freeldr.sys on the disk
+ ; so we need to load the first 512
+ ; bytes of it to 0000:7E00
+ xor di,di ; ES:DI has dir entry
+ xor dx,dx
+ mov ax,WORD [es:di+1ah]; Get start cluster
+ dec ax ; Adjust start cluster by 2
+ dec ax ; Because the data area starts on cluster 2
+ xor ch,ch
+ mov cl,BYTE [BYTE bp+SectsPerCluster] ; Times sectors per cluster
+ mul cx
+ pop cx ; Get number of sectors for root dir
+ add ax,cx ; Add it to the start sector of freeldr.sys
+ adc dx,byte 0
+ pop cx ; Get logical start sector of
+ pop bx ; Root directory
+ add ax,bx ; Now we have DX:AX with the logical start
+ adc dx,cx ; Sector of OSLOADER.SYS
+ mov cx,1 ; We will load 1 sector
+ push WORD [es:di+1ah] ; Save start cluster
+ mov bx,7e0h
+ mov es,bx
+ xor bx,bx
+ call ReadSectors ; Load it
+ pop ax ; Restore start cluster
+ jmp LoadFile
+
+
+
+; Reads logical sectors into [ES:BX]
+; DX:AX has logical sector number to read
+; CX has number of sectors to read
+; CarryFlag set on error
+ReadSectors:
+ push ax
+ push dx
+ push cx
+ xchg ax,cx
+ xchg ax,dx
+ xor dx,dx
+ div WORD [BYTE bp+SectorsPerTrack]
+ xchg ax,cx
+ div WORD [BYTE bp+SectorsPerTrack] ; Divide logical by SectorsPerTrack
+ inc dx ; Sectors numbering starts at 1 not 0
+ xchg cx,dx
+ div WORD [BYTE bp+NumberOfHeads] ; Number of heads
+ mov dh,dl ; Head to DH, drive to DL
+ mov dl,[BYTE bp+BootDrive] ; Drive number
+ mov ch,al ; Cylinder in CX
+ ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits
+ ror ah,1 ; in CL shifted to bits 6 & 7
+ or cl,ah ; Or with sector number
+ mov ax,0201h
+ int 13h ; DISK - READ SECTORS INTO MEMORY
+ ; AL = number of sectors to read, CH = track, CL = sector
+ ; DH = head, DL = drive, ES:BX -> buffer to fill
+ ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read
+
+ jc BadBoot
+
+ pop cx
+ pop dx
+ pop ax
+ inc ax ;Increment Sector to Read
+ jnz NoCarry
+ inc dx
+
+
+NoCarry:
+ push bx
+ mov bx,es
+ add bx,byte 20h
+ mov es,bx
+ pop bx
+ ; Increment read buffer for next sector
+ loop ReadSectors ; Read next sector
+
+ ret
+
+
+
+; Displays a bad boot message
+; And reboots
+BadBoot:
+ mov si,msgDiskError ; Bad boot disk message
+ call PutChars ; Display it
+ mov si,msgAnyKey ; Press any key message
+ call PutChars ; Display it
+
+ jmp Reboot
+
+; Displays an error message
+; And reboots
+ErrBoot:
+ mov si,msgFreeLdr ; FreeLdr not found message
+ call PutChars ; Display it
+ mov si,msgAnyKey ; Press any key message
+ call PutChars ; Display it
+
+Reboot:
+ xor ax,ax
+ int 16h ; Wait for a keypress
+ int 19h ; Reboot
+
+PutChars:
+ lodsb
+ or al,al
+ jz short Done
+ mov ah,0eh
+ mov bx,07h
+ int 10h
+ jmp short PutChars
+Done:
+ retn
+
+msgDiskError db 'Disk error',0dh,0ah,0
+msgFreeLdr db 'FREELDR.SYS not found',0dh,0ah,0
+msgAnyKey db 'Press any key to continue.',0dh,0ah,0
+filename db 'FREELDR SYS'
+
+ times 510-($-$$) db 0 ; Pad to 510 bytes
+ dw 0aa55h ; BootSector signature
+
+
+
+; End of bootsector
+;
+; Now starts the extra boot code that we will store
+; in the first 512 bytes of freeldr.sys
+
+
+
+LoadFile:
+ ; Display "Loading FreeLoader..." message
+ push ax
+ mov si,msgLoading ; Loading message
+ call PutChars ; Display it
+ pop ax
+
+ ; AX has start cluster of freeldr.sys
+ push ax
+ call ReadFatIntoMemory
+ pop ax
+
+ mov bx,7e0h
+ mov es,bx
+
+LoadFile2:
+ push ax
+ call IsFat12
+ pop ax
+ jnc LoadFile3
+ cmp ax,0ff8h ; Check to see if this is the last cluster in the chain
+ jmp LoadFile4
+LoadFile3:
+ cmp ax,0fff8h
+LoadFile4:
+ jae LoadFile_Done ; If so continue, if not then read then next one
+ push ax
+ xor bx,bx ; Load ROSLDR starting at 0000:8000h
+ push es
+ call ReadCluster
+ pop es
+
+ xor bx,bx
+ mov bl,BYTE [BYTE bp+SectsPerCluster]
+ shl bx,5 ; BX = BX * 512 / 16
+ mov ax,es ; Increment the load address by
+ add ax,bx ; The size of a cluster
+ mov es,ax
+
+ call IsFat12
+ pop ax
+ push es
+ jnc LoadFile5
+ call GetFatEntry12 ; Get the next entry
+ jmp LoadFile6
+LoadFile5:
+ call GetFatEntry16
+LoadFile6:
+ pop es
+
+ jmp LoadFile2 ; Load the next cluster (if any)
+
+LoadFile_Done:
+ mov dl,BYTE [BYTE bp+BootDrive]
+ xor ax,ax
+ push ax
+ mov ax,8000h
+ push ax ; We will do a far return to 0000:8000h
+ retf ; Transfer control to ROSLDR
+
+
+; Reads the entire FAT into memory at 7000:0000
+ReadFatIntoMemory:
+ mov ax,WORD [BYTE bp+HiddenSectors]
+ mov dx,WORD [BYTE bp+HiddenSectors+2]
+ add ax,WORD [BYTE bp+ReservedSectors]
+ adc dx,byte 0
+ mov cx,WORD [BYTE bp+SectorsPerFat]
+ mov bx,7000h
+ mov es,bx
+ xor bx,bx
+ call ReadSectors
+ ret
+
+
+; Returns the FAT entry for a given cluster number for 16-bit FAT
+; On entry AX has cluster number
+; On return AX has FAT entry for that cluster
+GetFatEntry16:
+
+ xor dx,dx
+ mov cx,2 ; AX = AX * 2 (since FAT16 entries are 2 bytes)
+ mul cx
+ shl dx,0fh
+
+ mov bx,7000h
+ add bx,dx
+ mov es,bx
+ mov bx,ax ; Restore FAT entry offset
+ mov ax,WORD [es:bx] ; Get FAT entry
+
+ ret
+
+
+; Returns the FAT entry for a given cluster number for 12-bit FAT
+; On entry AX has cluster number
+; On return AX has FAT entry for that cluster
+GetFatEntry12:
+
+ push ax
+ mov cx,ax
+ shr ax,1
+ add ax,cx ; AX = AX * 1.5 (AX = AX + (AX / 2)) (since FAT12 entries are 12 bits)
+
+ mov bx,7000h
+ mov es,bx
+ mov bx,ax ; Put FAT entry offset into BX
+ mov ax,WORD [es:bx] ; Get FAT entry
+ pop cx ; Get cluster number from stack
+ and cx,1
+ jz UseLow12Bits
+ and ax,0fff0h
+ shr ax,4
+ jmp GetFatEntry12_Done
+
+UseLow12Bits:
+ and ax,0fffh
+
+GetFatEntry12_Done:
+
+ ret
+
+
+; Reads cluster number in AX into [ES:0000]
+ReadCluster:
+ ; StartSector = ((Cluster - 2) * SectorsPerCluster) + + ReservedSectors + HiddenSectors;
+
+ dec ax
+ dec ax
+ xor dx,dx
+ movzx bx,BYTE [BYTE bp+SectsPerCluster]
+ mul bx
+ push ax
+ push dx
+ ; Now calculate the size of the root directory
+ mov ax,0020h ; Size of dir entry
+ mul WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
+ mov bx,WORD [BYTE bp+BytesPerSector]
+ add ax,bx
+ dec ax
+ div bx ; Divided by the size of a sector
+ mov cx,ax
+ ; CX now has the number of root directory sectors
+ xor dx,dx
+ movzx ax,BYTE [BYTE bp+NumberOfFats]
+ mul WORD [BYTE bp+SectorsPerFat]
+ add ax,WORD [BYTE bp+ReservedSectors]
+ adc dx,byte 0
+ add ax,WORD [BYTE bp+HiddenSectors]
+ adc dx,WORD [BYTE bp+HiddenSectors+2]
+ add ax,cx
+ adc dx,byte 0
+ pop cx
+ pop bx
+ add ax,bx
+ adc dx,cx
+ xor bx,bx ; We will load it to [ES:0000], ES loaded before function call
+ movzx cx,BYTE [BYTE bp+SectsPerCluster]
+ call ReadSectors
+ ret
+
+; Returns CF = 1 if this is a FAT12 file system
+; Otherwise CF = 0 for FAT16
+IsFat12:
+
+ ; Now calculate the size of the root directory
+ mov ax,0020h ; Size of dir entry
+ mul WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
+ mov bx,WORD [BYTE bp+BytesPerSector]
+ add ax,bx ; Plus (BytesPerSector - 1)
+ dec ax
+ div bx ; Divided by the size of a sector
+ ; AX now has the number of root directory sectors
+
+ mov bx,ax
+ ; Now we must find our way to the first sector of the root directory
+ xor ax,ax
+ xor dx,dx
+ mov al,BYTE [BYTE bp+NumberOfFats] ; Number of fats
+ mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat
+ add ax,WORD [BYTE bp+HiddenSectors]
+ adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors
+ add ax,[BYTE bp+ReservedSectors] ; Add the number of reserved sectors
+ adc dx,byte 0 ; Add carry bit
+ add ax,bx
+ adc dx,byte 0 ; Add carry bit
+ ; DX:AX now has the number of the starting sector of the data area
+
+ xor cx,cx
+ mov bx,WORD [BYTE bp+TotalSectors]
+ cmp bx,byte 0
+ jnz IsFat12_2
+ mov bx,WORD [BYTE bp+TotalSectorsBig]
+ mov cx,WORD [BYTE bp+TotalSectorsBig+2]
+
+ ; CX:BX now contains the number of sectors on the volume
+IsFat12_2:
+ sub bx,ax ; Subtract data area start sector
+ sub cx,dx ; from total sectors of volume
+ mov ax,bx
+ mov dx,cx
+
+ ; DX:AX now contains the number of data sectors on the volume
+ movzx bx,BYTE [BYTE bp+SectsPerCluster]
+ div bx
+ ; AX now has the number of clusters on the volume
+ stc
+ cmp ax,4085
+ jb IsFat12_Done
+ clc
+
+IsFat12_Done:
+ ret
+
+
+
+ times 998-($-$$) db 0 ; Pad to 998 bytes
+
+msgLoading db 'Loading FreeLoader...',0dh,0ah,0
+
+ dw 0aa55h ; BootSector signature
-; BTSECT32.ASM
+; FAT32.ASM
; FAT32 Boot Sector
-; Copyright (c) 1998, 2000 Brian Palmer
+; Copyright (c) 1998, 2000, 2001 Brian Palmer
org 7c00h
jmp short main
nop
-OEMName db 'FreeLDR!'
+OEMName db 'FrLdr1.0'
BytesPerSector dw 512
SectsPerCluster db 1
-ReservedSectors dw 1
+ReservedSectors dw 32
NumberOfFats db 2
-MaxRootEntries dw 0 ;512 - Always zero for FAT32 volumes
-TotalSectors dw 0 ;2880 - Always zero for FAT32 volumes
+MaxRootEntries dw 0 ; Always zero for FAT32 volumes
+TotalSectors dw 0 ; Always zero for FAT32 volumes
MediaDescriptor db 0f8h
-SectorsPerFat dw 0 ;9 - Always zero for FAT32 volumes
+SectorsPerFat dw 0 ; Always zero for FAT32 volumes
SectorsPerTrack dw 18
NumberOfHeads dw 2
HiddenSectors dd 0
Reserved db 0
ExtendSig db 29h
SerialNumber dd 00000000h
-VolumeLabel db 'FreeLoader!'
+VolumeLabel db 'NO NAME '
FileSystem db 'FAT32 '
main:
mov [BootDrive],dl ; Save the boot drive
xor ax,ax ; Zero out AX
+ cmp word [TotalSectors],byte 0x00 ; Check the old 16-bit value of TotalSectors
+ jnz ErrBoot ; If it is non-zero then exit with an error
+
+ cmp word [FSVersion],byte 0x00 ; Check the file system version word
+ ja ErrBoot ; If it is not zero then exit with an error
+
+
; Reset disk controller
int 13h
- jnc Continue
+ jnc LoadExtraBootCode
jmp BadBoot ; Reset failed...
-Continue:
+LoadExtraBootCode:
; First we have to load our extra boot code at
; sector 14 into memory at [0000:7e00h]
xor dx,dx
mov es,bx ; Read sector to [0000:7e00h]
xor bx,bx
call ReadSectors
- jnc Continue1
- jmp BadBoot
-
-
-Continue1:
- ; Now we must get the first cluster of the root directory
- mov eax,DWORD [RootDirStartCluster]
- cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain
- jb Continue2 ; If not continue, if so BadBoot
- jmp ErrBoot
-Continue2:
- mov bx,800h
- mov es,bx ; Read cluster to [0000:8000h]
- call ReadCluster ; Read the cluster
-
-
- ; Now we have to find our way through the root directory to
- ; The OSLOADER.SYS file
- xor bx,bx
- mov bl,[SectsPerCluster]
- shl bx,4 ; BX = BX * 512 / 32
- mov ax,800h ; We loaded at 0800:0000
- mov es,ax
- xor di,di
- mov si,filename
- mov cx,11
- rep cmpsb ; Compare filenames
- jz FoundFile ; If same we found it
- dec bx
- jnz FindFile
- jmp ErrBoot
-
-FindFile:
- mov ax,es ; We didn't find it in the previous dir entry
- add ax,2 ; So lets move to the next one
- mov es,ax ; And search again
- xor di,di
- mov si,filename
- mov cx,11
- rep cmpsb ; Compare filenames
- jz FoundFile ; If same we found it
- dec bx ; Keep searching till we run out of dir entries
- jnz FindFile ; Last entry?
-
- ; Get the next root dir cluster and try again until we run out of clusters
- mov eax,DWORD [RootDirStartCluster]
- call GetFatEntry
- mov [RootDirStartCluster],eax
- jmp Continue1
-
-FoundFile:
- xor di,di ; ES:DI has dir entry
- xor dx,dx
- mov ax,WORD [es:di+14h] ; Get start cluster high word
- shl eax,16
- mov ax,WORD [es:di+1ah] ; Get start cluster low word
-
- mov bx,800h
- mov es,bx
-
-FoundFile2:
- cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain
- jae FoundFile3 ; If so continue, if not then read then next one
- push eax
- xor bx,bx ; Load ROSLDR starting at 0000:8000h
- push es
- call ReadCluster
- pop es
-
- xor bx,bx
- mov bl,[SectsPerCluster]
- shl bx,5 ; BX = BX * 512 / 16
- mov ax,es ; Increment the load address by
- add ax,bx ; The size of a cluster
- mov es,ax
+ jmp StartSearch
- pop eax
- push es
- call GetFatEntry ; Get the next entry
- pop es
-
- jmp FoundFile2 ; Load the next cluster (if any)
-
-FoundFile3:
- mov dl,[BootDrive]
- xor ax,ax
- push ax
- mov ax,8000h
- push ax ; We will do a far return to 0000:8000h
- retf ; Transfer control to ROSLDR
ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits
ror ah,1 ; in CL shifted to bits 6 & 7
or cl,ah ; Or with sector number
- mov ax,513
+ mov ax,0201h
int 13h ; DISK - READ SECTORS INTO MEMORY
; AL = number of sectors to read, CH = track, CL = sector
; DH = head, DL = drive, ES:BX -> buffer to fill
; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read
+
+ jc BadBoot
+
pop cx
pop dx
pop ax
- jc ReadFail
inc ax ;Increment Sector to Read
jnz NoCarry
inc dx
NoCarry:
push bx
mov bx,es
- add bx,20h
+ add bx,byte 20h
mov es,bx
pop bx
; Increment read buffer for next sector
loop ReadSectors ; Read next sector
-
-ReadFail:
- ret
+ ret
; Note: Win2k uses sector 12 for this purpose
+
+StartSearch:
+ ; Now we must get the first cluster of the root directory
+ mov eax,DWORD [RootDirStartCluster]
+ cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain
+ jb ContinueSearch ; If not continue, if so BadBoot
+ jmp ErrBoot
+ContinueSearch:
+ mov bx,800h
+ mov es,bx ; Read cluster to [0000:8000h]
+ call ReadCluster ; Read the cluster
+
+
+ ; Now we have to find our way through the root directory to
+ ; The OSLOADER.SYS file
+ xor bx,bx
+ mov bl,[SectsPerCluster]
+ shl bx,4 ; BX = BX * 512 / 32
+ mov ax,800h ; We loaded at 0800:0000
+ mov es,ax
+ xor di,di
+ mov si,filename
+ mov cx,11
+ rep cmpsb ; Compare filenames
+ jz FoundFile ; If same we found it
+ dec bx
+ jnz FindFile
+ jmp ErrBoot
+
+FindFile:
+ mov ax,es ; We didn't find it in the previous dir entry
+ add ax,2 ; So lets move to the next one
+ mov es,ax ; And search again
+ xor di,di
+ mov si,filename
+ mov cx,11
+ rep cmpsb ; Compare filenames
+ jz FoundFile ; If same we found it
+ dec bx ; Keep searching till we run out of dir entries
+ jnz FindFile ; Last entry?
+
+ ; Get the next root dir cluster and try again until we run out of clusters
+ mov eax,DWORD [RootDirStartCluster]
+ call GetFatEntry
+ mov [RootDirStartCluster],eax
+ jmp StartSearch
+
+FoundFile:
+ ; Display "Loading FreeLoader..." message
+ mov si,msgLoading ; Loading message
+ call PutChars ; Display it
+
+ xor di,di ; ES:DI has dir entry
+ xor dx,dx
+ mov ax,WORD [es:di+14h] ; Get start cluster high word
+ shl eax,16
+ mov ax,WORD [es:di+1ah] ; Get start cluster low word
+
+ mov bx,800h
+ mov es,bx
+
+FoundFile2:
+ cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain
+ jae FoundFile3 ; If so continue, if not then read then next one
+ push eax
+ xor bx,bx ; Load ROSLDR starting at 0000:8000h
+ push es
+ call ReadCluster
+ pop es
+
+ xor bx,bx
+ mov bl,[SectsPerCluster]
+ shl bx,5 ; BX = BX * 512 / 16
+ mov ax,es ; Increment the load address by
+ add ax,bx ; The size of a cluster
+ mov es,ax
+
+ pop eax
+ push es
+ call GetFatEntry ; Get the next entry
+ pop es
+
+ jmp FoundFile2 ; Load the next cluster (if any)
+
+FoundFile3:
+ mov dl,[BootDrive]
+ xor ax,ax
+ push ax
+ mov ax,8000h
+ push ax ; We will do a far return to 0000:8000h
+ retf ; Transfer control to ROSLDR
+
+
; Returns the FAT entry for a given cluster number
; On entry EAX has cluster number
; On return EAX has FAT entry for that cluster
div ebx ; FAT Sector Number = EAX / BytesPerSector
movzx ebx,WORD [ReservedSectors]
add eax,ebx ; FAT Sector Number += ReservedSectors
- movzx ebx,WORD [HiddenSectors]
+ mov ebx,DWORD [HiddenSectors]
add eax,ebx ; FAT Sector Number += HiddenSectors
pop ebx
dec ebx
and ecx,ebx ; FAT Offset Within Sector = ECX % BytesPerSector
; EAX holds logical FAT sector number
; ECX holds FAT entry offset
+
+ ; Now we have to check the extended flags
+ ; to see which FAT is the active one
+ ; and use it, or if they are mirrored then
+ ; no worries
+ movzx ebx,WORD [ExtendedFlags] ; Get extended flags and put into ebx
+ and bx,0x0f ; Mask off upper 8 bits
+ jz GetFatEntry2 ; If fat is mirrored then skip fat calcs
+ cmp bl,[NumberOfFats] ; Compare bl to number of fats
+ jc GetFatEntry1
+ jmp ErrBoot ; If bl is bigger than numfats exit with error
+GetFatEntry1:
+ mov edx,eax ; Put logical FAT sector number in edx
+ mov eax,[SectorsPerFatBig] ; Get the number of sectors occupied by one fat in eax
+ mul ebx ; Multiplied by the active FAT index we have in ebx
+ add eax,edx ; Add the current FAT sector offset
+
+GetFatEntry2:
push ecx
ror eax,16
mov dx,ax
xor bx,bx ; We will load it to [7000:0000h]
mov cx,1
call ReadSectors
- jnc GetFatEntry1
+ jnc GetFatEntry3
jmp BadBoot
-GetFatEntry1:
+GetFatEntry3:
mov bx,7000h
mov es,bx
pop ecx
xor bx,bx ; We will load it to [ES:0000], ES loaded before function call
movzx cx,BYTE [SectsPerCluster]
call ReadSectors
- jnc ReadCluster1
- jmp BadBoot
-
-ReadCluster1:
ret
- times 1022-($-$$) db 0 ; Pad to 1022 bytes
+ times 998-($-$$) db 0 ; Pad to 998 bytes
+
+msgLoading db 'Loading FreeLoader...',0dh,0ah,0
+
dw 0aa55h ; BootSector signature
+++ /dev/null
-debug bootsect.bin < install.src
+++ /dev/null
-w 100 0 0 1
-q
--- /dev/null
+#include <stdio.h>
+
+FILE *in;
+FILE *out;
+FILE *new;
+
+int main(int argc, char *argv[])
+{
+ unsigned char ch;
+ int cnt;
+ int split_offset;
+
+ if (argc < 5)
+ {
+ printf("usage: split infile.bin outfile.bin newfile.bin split_offset\n");
+ return -1;
+ }
+
+ if ((in = fopen(argv[1], "rb")) == NULL)
+ {
+ printf("Couldn't open data file.\n");
+ return -1;
+ }
+ if ((out = fopen(argv[2], "wb")) == NULL)
+ {
+ printf("Couldn't open output file.\n");
+ return -1;
+ }
+ if ((new = fopen(argv[3], "wb")) == NULL)
+ {
+ printf("Couldn't open new file.\n");
+ return -1;
+ }
+
+ split_offset = atoi(argv[4]);
+
+ for (cnt=0; cnt<split_offset; cnt++)
+ {
+ ch = fgetc(in);
+ fputc(ch, out);
+ }
+
+ ch = fgetc(in);
+ while (!feof(in))
+ {
+ fputc(ch, new);
+ ch = fgetc(in);
+ }
+
+ fclose(in);
+ fclose(out);
+ fclose(new);
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#include <stdio.h>
+
+FILE *in;
+FILE *in2;
+FILE *out;
+
+int main(int argc, char *argv[])
+{
+ unsigned char ch;
+
+ if (argc < 4)
+ {
+ printf("usage: stubit infile1.bin infile2.sys outfile.bin\n");
+ return -1;
+ }
+
+ if ((in = fopen(argv[1], "rb")) == NULL)
+ {
+ printf("Couldn't open data file.\n");
+ return -1;
+ }
+ if ((in2 = fopen(argv[2], "rb")) == NULL)
+ {
+ printf("Couldn't open data file.\n");
+ return -1;
+ }
+ if ((out = fopen(argv[3], "wb")) == NULL)
+ {
+ printf("Couldn't open output file.\n");
+ return -1;
+ }
+
+ ch = fgetc(in);
+ while (!feof(in))
+ {
+ fputc(ch, out);
+ ch = fgetc(in);
+ }
+
+ ch = fgetc(in2);
+ while (!feof(in2))
+ {
+ fputc(ch, out);
+ ch = fgetc(in2);
+ }
+
+ fclose(in);
+ fclose(in2);
+ fclose(out);
+
+ return 0;
+}
\ No newline at end of file
jmp short main
nop
-OEMName db 'FreeLDR!'
+OEMName db 'MSWIN4.0'
BytesPerSector dw 512
SectsPerCluster db 1
ReservedSectors dw 1
Reserved db 0
ExtendSig db 29h
SerialNumber dd 00000000h
-VolumeLabel db 'FreeLoader!'
-FileSystem db 'FAT12 '
+VolumeLabel db 'NO NAME '
+FileSystem db 'FAT32 '
main:
00007C5A 33C9 xor cx,cx
00008112 660FB74E0E movzx ecx,word [bp+ReservedSectors] ; Add the reserved sectors
00008117 6603C1 add eax,ecx ; To the hidden sectors + the value we computed earlier
0000811A 660FB75E28 movzx ebx,word [bp+ExtendedFlags] ; Get extended flags and put into ebx
-0000811F 83E30F and bx,byte +0xf ; Mask off everything but the active fat bits
-00008122 7416 jz load_fat_sector_into_memory ; If active fat is first fat skip fat size calcs
+0000811F 83E30F and bx,byte +0xf ; Mask off upper 8 bits
+00008122 7416 jz load_fat_sector_into_memory ; If fat is mirrored then skip fat calcs
00008124 3A5E10 cmp bl,[bp+NumberOfFats] ; Compare bl to number of fats
00008127 0F83ABFB jnc near print_ntldr_error_message ; If bl is bigger than numfats exit with error
0000812B 52 push dx ; Save dx
#
# FreeLoader
-# Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
+# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
export CP = cmd /C copy
#FLAGS = -Wall -nostdinc -fno-builtin
-FLAGS = -Wall -fno-builtin
+FLAGS = -Wall -fno-builtin -DDEBUG
# asmcode.o has to be first in the link line because it contains the startup code
OBJS = asmcode.a asmcode.o mb.o boot.o freeldr.o stdlib.o fs.a fs.o fs_fat.o \
reactos.o tui.o menu.o miscboot.o options.o linux.o multiboot.o arcname.o \
- mem.o memory.o
+ mem.o memory.o debug.o parseini.o
ASM_OBJS = asmcode.o mb.o boot.o mem.o
C_OBJS = freeldr.o stdlib.o fs.a reactos.o tui.o menu.o miscboot.o options.o linux.o \
- multiboot.o arcname.o memory.o
+ multiboot.o arcname.o memory.o debug.o parseini.o
+
+.PHONY : clean
all: freeldr.sys
mem.o: mem.S asmcode.h Makefile
$(CC) $(FLAGS) -o mem.o -c mem.S
-memory.o: memory.c asmcode.h memory.h Makefile
+memory.o: memory.c memory.h Makefile
$(CC) $(FLAGS) -o memory.o -c memory.c
+debug.o: debug.c debug.h Makefile
+ $(CC) $(FLAGS) -o debug.o -c debug.c
+
+parseini.o: parseini.c parseini.h Makefile
+ $(CC) $(FLAGS) -o parseini.o -c parseini.c
+
clean:
$(RM) *.o
$(RM) *.a
#include "stdlib.h"
-BOOL DissectArcPath(char *ArcPath, char *BootPath, unsigned int *BootDrive, unsigned int *BootPartition)
+BOOL DissectArcPath(char *ArcPath, char *BootPath, PULONG BootDrive, PULONG BootPartition)
{
char *p;
#ifndef __ARCNAME_H
#define __ARCNAME_H
-BOOL DissectArcPath(char *ArcPath, char *BootPath, unsigned int *BootDrive, unsigned int *BootPartition);
-//BOOL ConvertBiosDriveToArcName()
-//BOOL ConvertArcNameToBiosDrive()
+BOOL DissectArcPath(char *ArcPath, char *BootPath, PULONG BootDrive, PULONG BootPartition);
+//BOOL ConvertBiosDriveToArcName(PUCHAR ArcName, ULONG BiosDriveNumber);
+//ULONG ConvertArcNameToBiosDrive(PUCHAR ArcName);
#endif // defined __ARCNAME_H
\ No newline at end of file
--- /dev/null
+/*
+ * FreeLoader
+ * Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "freeldr.h"
+#include "debug.h"
+#include "stdlib.h"
+
+ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY;
+
+void DebugPrint(ULONG Mask, char *format, ...)
+{
+ int *dataptr = (int *) &format;
+ char c, *ptr, str[16];
+ char buffer[512];
+ char *p = buffer;
+
+ // Mask out unwanted debug messages
+ if (!(Mask & DebugPrintMask))
+ {
+ return;
+ }
+
+ dataptr++;
+
+ while ((c = *(format++)))
+ {
+ if (c != '%')
+ {
+ *p = c;
+ p++;
+ }
+ else
+ switch (c = *(format++))
+ {
+ case 'd': case 'u': case 'x':
+ *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
+
+ ptr = str;
+
+ while (*ptr)
+ {
+ *p = *(ptr++);
+ p++;
+ }
+ break;
+
+ case 'c':
+ *p = (*(dataptr++))&0xff;
+ p++;
+ break;
+
+ case 's':
+ ptr = (char *)(*(dataptr++));
+
+ while ((c = *(ptr++)))
+ {
+ *p = c;
+ p++;
+ }
+ break;
+ }
+ }
+ *p=0;
+
+
+ print(buffer);
+}
--- /dev/null
+/*
+ * FreeLoader
+ * Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifndef __DEBUG_H
+#define __DEBUG_H
+
+#define DPRINT_WARNING 0x00000001 // OR this with DebugPrintMask to enable debugger messages and other misc stuff
+#define DPRINT_MEMORY 0x00000002 // OR this with DebugPrintMask to enable memory management messages
+
+void DebugPrint(ULONG Mask, char *format, ...);
+
+#define BugCheck0(format) \
+ { \
+ DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+ DebugPrint(DPRINT_WARNING, format); \
+ for (;;); \
+ }
+
+#define BugCheck1(format, arg1) \
+ { \
+ DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+ DebugPrint(DPRINT_WARNING, format, arg1); \
+ for (;;); \
+ }
+
+#define BugCheck2(format, arg1, arg2) \
+ { \
+ DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+ DebugPrint(DPRINT_WARNING, format, arg1, arg2); \
+ for (;;); \
+ }
+
+#define BugCheck3(format, arg1, arg2, arg3) \
+ { \
+ DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+ DebugPrint(DPRINT_WARNING, format, arg1, arg2, arg3); \
+ for (;;); \
+ }
+
+#endif // defined __DEBUG_H
\ No newline at end of file
#include "menu.h"
#include "miscboot.h"
#include "linux.h"
+#include "memory.h"
+#include "parseini.h"
// Variable BootDrive moved to asmcode.S
-//unsigned int BootDrive = 0; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
-unsigned int BootPartition = 0; // Boot Partition, 1-4
-BOOL bTUILoaded = FALSE; // Tells us if the user interface is loaded
+//ULONG BootDrive = 0; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
+ULONG BootPartition = 0; // Boot Partition, 1-4
+BOOL UserInterfaceUp = FALSE; // Tells us if the user interface is displayed
-char *pFreeldrIni = (char *)(FREELDRINIADDR); // Load address for freeldr.ini
-char *pScreenBuffer = (char *)(SCREENBUFFER); // Save address for screen contents
-int nCursorXPos = 0; // Cursor's X Position
-int nCursorYPos = 0; // Cursor's Y Position
+PUCHAR ScreenBuffer = (PUCHAR)(SCREENBUFFER); // Save buffer for screen contents
+int CursorXPos = 0; // Cursor's X Position
+int CursorYPos = 0; // Cursor's Y Position
OSTYPE OSList[16];
int nNumOS = 0;
enable_a20();
- SaveScreen(pScreenBuffer);
- nCursorXPos = wherex();
- nCursorYPos = wherey();
+ SaveScreen(ScreenBuffer);
+ CursorXPos = wherex();
+ CursorYPos = wherey();
printf("Loading FreeLoader...\n");
+ InitMemoryManager((PVOID)0x100000, 0x20000);
+
if (!ParseIniFile())
{
printf("Press any key to reboot.\n");
hidecursor();
// Draw the backdrop and title box
DrawBackdrop();
- bTUILoaded = TRUE;
+ UserInterfaceUp = TRUE;
if (nNumOS == 0)
{
DrawStatusText(" Press ENTER to reboot");
- MessageBox("Error: there were no operating systems listed to boot.\nPress ENTER to reboot.");
+ MessageBox("Error: there were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
clrscr();
showcursor();
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
return;
}
}
MessageBox("Press any key to reboot.");
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
showcursor();
- gotoxy(nCursorXPos, nCursorYPos);
-}
-
-BOOL ParseIniFile(void)
-{
- int i;
- char name[1024];
- char value[1024];
- FILE Freeldr_Ini; // File handle for freeldr.ini
-
- // Open the boot drive for file access
- if(!OpenDiskDrive(BootDrive, 0))
- {
- printf("Error opening boot drive for file access.\n");
- return FALSE;
- }
-
- // Try to open freeldr.ini or fail
- if(!OpenFile("freeldr.ini", &Freeldr_Ini))
- {
- printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n");
- return FALSE;
- }
-
- // Check and see if freeldr.ini is too big
- // if so display a warning
- if(GetFileSize(&Freeldr_Ini) > 0x4000)
- {
- printf("Warning: FREELDR.INI is bigger than 16k.\n");
- printf("Only 16k of it will be loaded off the disk.\n");
- printf("Press any key to continue.\n");
- getch();
- }
-
- // Read freeldr.ini off the disk
- ReadFile(&Freeldr_Ini, 0x4000, pFreeldrIni);
-
- // Make sure the [FREELOADER] section exists
- if(!GetNumSectionItems("FREELOADER"))
- {
- printf("Section [FREELOADER] not found in FREELDR.INI.\nYou need to re-install FreeLoader.\n");
- return FALSE;
- }
-
- // Validate the settings in the [FREELOADER] section
- for(i=1; i<=GetNumSectionItems("FREELOADER"); i++)
- {
- ReadSectionSettingByNumber("FREELOADER", i, name, value);
- if(!IsValidSetting(name, value))
- {
- printf("Invalid setting in freeldr.ini.\nName: \"%s\", Value: \"%s\"\n", name, value);
- printf("Press any key to continue.\n");
- getch();
- }
- else
- SetSetting(name, value);
- }
-
- return TRUE;
-}
-
-int GetNumSectionItems(char *section)
-{
- int i;
- char str[1024];
- char real_section[1024];
- int num_items = 0;
- int freeldr_ini_offset;
- BOOL bFoundSection = FALSE;
-
- // Get the real section name
- strcpy(real_section, "[");
- strcat(real_section, section);
- strcat(real_section, "]");
-
- // Get to the beginning of the file
- freeldr_ini_offset = 0;
-
- // Find the section
- while(freeldr_ini_offset < 0x4000)
- {
- // Read a line
- for(i=0; i<1024; i++,freeldr_ini_offset++)
- {
- if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
- str[i] = pFreeldrIni[freeldr_ini_offset];
- else
- {
- freeldr_ini_offset++;
- break;
- }
- }
- str[i] = '\0';
- //fgets(str, 1024, &Freeldr_Ini);
-
- // Get rid of newline & linefeed characters (if any)
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
-
- // Skip comments
- if(str[0] == '#')
- continue;
-
- // Skip blank lines
- if(!strlen(str))
- continue;
-
- // If it isn't a section header then continue on
- if(str[0] != '[')
- continue;
-
- // Check and see if we found it
- if(stricmp(str, real_section) == 0)
- {
- bFoundSection = TRUE;
- break;
- }
- }
-
- // If we didn't find the section then we're outta here
- if(!bFoundSection)
- return 0;
-
- // Now count how many settings are in this section
- while(freeldr_ini_offset < 0x4000)
- {
- // Read a line
- for(i=0; i<1024; i++,freeldr_ini_offset++)
- {
- if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
- str[i] = pFreeldrIni[freeldr_ini_offset];
- else
- {
- freeldr_ini_offset++;
- break;
- }
- }
- str[i] = '\0';
- //fgets(str, 1024, &Freeldr_Ini);
-
- // Get rid of newline & linefeed characters (if any)
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
-
- // Skip comments
- if(str[0] == '#')
- continue;
-
- // Skip blank lines
- if(!strlen(str))
- continue;
-
- // If we hit a new section then we're done
- if(str[0] == '[')
- break;
-
- num_items++;
- }
-
- return num_items;
-}
-
-BOOL ReadSectionSettingByNumber(char *section, int num, char *name, char *value)
-{
- char str[1024];
- char real_section[1024];
- int num_items = 0;
- int i;
- int freeldr_ini_offset;
- BOOL bFoundSection = FALSE;
-
- // Get the real section name
- strcpy(real_section, "[");
- strcat(real_section, section);
- strcat(real_section, "]");
-
- // Get to the beginning of the file
- freeldr_ini_offset = 0;
-
- // Find the section
- while(freeldr_ini_offset < 0x4000)
- {
- // Read a line
- for(i=0; i<1024; i++,freeldr_ini_offset++)
- {
- if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
- str[i] = pFreeldrIni[freeldr_ini_offset];
- else
- {
- freeldr_ini_offset++;
- break;
- }
- }
- str[i] = '\0';
- //fgets(str, 1024, &Freeldr_Ini);
-
- // Get rid of newline & linefeed characters (if any)
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
-
- // Skip comments
- if(str[0] == '#')
- continue;
-
- // Skip blank lines
- if(!strlen(str))
- continue;
-
- // If it isn't a section header then continue on
- if(str[0] != '[')
- continue;
-
- // Check and see if we found it
- if(stricmp(str, real_section) == 0)
- {
- bFoundSection = TRUE;
- break;
- }
- }
-
- // If we didn't find the section then we're outta here
- if(!bFoundSection)
- return FALSE;
-
- // Now find the setting we are looking for
- while(freeldr_ini_offset < 0x4000)
- {
- // Read a line
- for(i=0; i<1024; i++,freeldr_ini_offset++)
- {
- if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
- str[i] = pFreeldrIni[freeldr_ini_offset];
- else
- {
- freeldr_ini_offset++;
- break;
- }
- }
- str[i] = '\0';
- //fgets(str, 1024, &Freeldr_Ini);
-
- // Get rid of newline & linefeed characters (if any)
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
-
- // Skip comments
- if(str[0] == '#')
- continue;
-
- // Skip blank lines
- if(!strlen(str))
- continue;
-
- // If we hit a new section then we're done
- if(str[0] == '[')
- break;
-
- // Increment setting number
- num_items++;
-
- // Check and see if we found the setting
- if(num_items == num)
- {
- for(i=0; i<strlen(str); i++)
- {
- // Check and see if this character is the separator
- if(str[i] == '=')
- {
- name[i] = '\0';
-
- strcpy(value, str+i+1);
-
- return TRUE;
- }
- else
- name[i] = str[i];
- }
- }
- }
-
- return FALSE;
-}
-
-BOOL ReadSectionSettingByName(char *section, char *valuename, char *name, char *value)
-{
- char str[1024];
- char real_section[1024];
- char temp[1024];
- int i;
- int freeldr_ini_offset;
- BOOL bFoundSection = FALSE;
-
- // Get the real section name
- strcpy(real_section, "[");
- strcat(real_section, section);
- strcat(real_section, "]");
-
- // Get to the beginning of the file
- freeldr_ini_offset = 0;
-
- // Find the section
- while(freeldr_ini_offset < 0x4000)
- {
- // Read a line
- for(i=0; i<1024; i++,freeldr_ini_offset++)
- {
- if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
- str[i] = pFreeldrIni[freeldr_ini_offset];
- else
- {
- freeldr_ini_offset++;
- break;
- }
- }
- str[i] = '\0';
- //fgets(str, 1024, &Freeldr_Ini);
-
- // Get rid of newline & linefeed characters (if any)
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
-
- // Skip comments
- if(str[0] == '#')
- continue;
-
- // Skip blank lines
- if(!strlen(str))
- continue;
-
- // If it isn't a section header then continue on
- if(str[0] != '[')
- continue;
-
- // Check and see if we found it
- if(stricmp(str, real_section) == 0)
- {
- bFoundSection = TRUE;
- break;
- }
- }
-
- // If we didn't find the section then we're outta here
- if(!bFoundSection)
- return FALSE;
-
- // Now find the setting we are looking for
- while(freeldr_ini_offset < 0x4000)
- {
- // Read a line
- for(i=0; i<1024; i++,freeldr_ini_offset++)
- {
- if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
- str[i] = pFreeldrIni[freeldr_ini_offset];
- else
- {
- freeldr_ini_offset++;
- break;
- }
- }
- str[i] = '\0';
- //fgets(str, 1024, &Freeldr_Ini);
-
- // Get rid of newline & linefeed characters (if any)
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
- if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
- str[strlen(str)-1] = '\0';
-
- // Skip comments
- if(str[0] == '#')
- continue;
-
- // Skip blank lines
- if(!strlen(str))
- continue;
-
- // If we hit a new section then we're done
- if(str[0] == '[')
- break;
-
- // Extract the setting name
- for(i=0; i<strlen(str); i++)
- {
- if(str[i] != '=')
- temp[i] = str[i];
- else
- {
- temp[i] = '\0';
- break;
- }
- }
-
- // Check and see if we found the setting
- if(stricmp(temp, valuename) == 0)
- {
- for(i=0; i<strlen(str); i++)
- {
- // Check and see if this character is the separator
- if(str[i] == '=')
- {
- name[i] = '\0';
-
- strcpy(value, str+i+1);
-
- return TRUE;
- }
- else
- name[i] = str[i];
- }
- }
- }
-
- return FALSE;
-}
-
-BOOL IsValidSetting(char *setting, char *value)
-{
- if(stricmp(setting, "MessageBox") == 0)
- return TRUE;
- else if(stricmp(setting, "MessageLine") == 0)
- return TRUE;
- else if(stricmp(setting, "TitleText") == 0)
- return TRUE;
- else if(stricmp(setting, "StatusBarColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "StatusBarTextColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "BackdropTextColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "BackdropColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "BackdropFillStyle") == 0)
- {
- if(IsValidFillStyle(value))
- return TRUE;
- }
- else if(stricmp(setting, "TitleBoxTextColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "TitleBoxColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "MessageBoxTextColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "MessageBoxColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "MenuTextColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "MenuColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "TextColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "SelectedTextColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "SelectedColor") == 0)
- {
- if(IsValidColor(value))
- return TRUE;
- }
- else if(stricmp(setting, "OS") == 0)
- return TRUE;
- else if(stricmp(setting, "TimeOut") == 0)
- return TRUE;
- /*else if(stricmp(setting, "") == 0)
- return TRUE;
- else if(stricmp(setting, "") == 0)
- return TRUE;
- else if(stricmp(setting, "") == 0)
- return TRUE;
- else if(stricmp(setting, "") == 0)
- return TRUE;
- else if(stricmp(setting, "") == 0)
- return TRUE;
- else if(stricmp(setting, "") == 0)
- return TRUE;
- else if(stricmp(setting, "") == 0)
- return TRUE;*/
-
- return FALSE;
-}
-
-void SetSetting(char *setting, char *value)
-{
- char name[260];
- char v[260];
-
- if(stricmp(setting, "TitleText") == 0)
- strcpy(szTitleBoxTitleText, value);
- else if(stricmp(setting, "StatusBarColor") == 0)
- cStatusBarBgColor = TextToColor(value);
- else if(stricmp(setting, "StatusBarTextColor") == 0)
- cStatusBarFgColor = TextToColor(value);
- else if(stricmp(setting, "BackdropTextColor") == 0)
- cBackdropFgColor = TextToColor(value);
- else if(stricmp(setting, "BackdropColor") == 0)
- cBackdropBgColor = TextToColor(value);
- else if(stricmp(setting, "BackdropFillStyle") == 0)
- cBackdropFillStyle = TextToFillStyle(value);
- else if(stricmp(setting, "TitleBoxTextColor") == 0)
- cTitleBoxFgColor = TextToColor(value);
- else if(stricmp(setting, "TitleBoxColor") == 0)
- cTitleBoxBgColor = TextToColor(value);
- else if(stricmp(setting, "MessageBoxTextColor") == 0)
- cMessageBoxFgColor = TextToColor(value);
- else if(stricmp(setting, "MessageBoxColor") == 0)
- cMessageBoxBgColor = TextToColor(value);
- else if(stricmp(setting, "MenuTextColor") == 0)
- cMenuFgColor = TextToColor(value);
- else if(stricmp(setting, "MenuColor") == 0)
- cMenuBgColor = TextToColor(value);
- else if(stricmp(setting, "TextColor") == 0)
- cTextColor = TextToColor(value);
- else if(stricmp(setting, "SelectedTextColor") == 0)
- cSelectedTextColor = TextToColor(value);
- else if(stricmp(setting, "SelectedColor") == 0)
- cSelectedTextBgColor = TextToColor(value);
- else if(stricmp(setting, "OS") == 0)
- {
- if(nNumOS >= 16)
- {
- printf("Error: you can only boot to at most 16 different operating systems.\n");
- printf("Press any key to continue\n");
- getch();
- return;
- }
-
- if(!GetNumSectionItems(value))
- {
- printf("Error: OS \"%s\" listed.\n", value);
- printf("It does not have it's own [section], or it is empty.\n");
- printf("Press any key to continue\n");
- getch();
- return;
- }
-
- strcpy(OSList[nNumOS].name, value);
-
- if (!ReadSectionSettingByName(value, "BootType", name, v))
- {
- printf("Unknown BootType for OS \"%s\"\n", value);
- printf("Press any key to continue\n");
- getch();
- return;
- }
-
- if (stricmp(v, "ReactOS") == 0)
- OSList[nNumOS].nOSType = OSTYPE_REACTOS;
- else if (stricmp(v, "Linux") == 0)
- OSList[nNumOS].nOSType = OSTYPE_LINUX;
- else if (stricmp(v, "BootSector") == 0)
- OSList[nNumOS].nOSType = OSTYPE_BOOTSECTOR;
- else if (stricmp(v, "Partition") == 0)
- OSList[nNumOS].nOSType = OSTYPE_PARTITION;
- else if (stricmp(v, "Drive") == 0)
- OSList[nNumOS].nOSType = OSTYPE_DRIVE;
- else
- {
- printf("Unknown BootType for OS \"%s\"\n", value);
- printf("Press any key to continue\n");
- getch();
- return;
- }
-
- nNumOS++;
- }
- else if(stricmp(setting, "TimeOut") == 0)
- nTimeOut = atoi(value);
+ gotoxy(CursorXPos, CursorYPos);
}
#define WORD unsigned short
#define DWORD unsigned long
#define CHAR char
+#define PCHAR char *
+#define UCHAR unsigned char
+#define PUCHAR unsigned char *
#define WCHAR unsigned short
+#define PWCHAR unsigned short *
#define LONG long
#define ULONG unsigned long
#define PULONG unsigned long *
#define PDWORD DWORD *
#define PWORD WORD *
+#define VOID void
+#define PVOID VOID*
+
+#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
#define OSTYPE_REACTOS 1
#define OSTYPE_LINUX 2
{
char name[260];
int nOSType; // ReactOS or Linux or a bootsector, etc.
-} OSTYPE;
+} OSTYPE, *POSTYPE;
-extern unsigned int BootDrive; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
-extern unsigned int BootPartition; // Boot Partition, 1-4
-extern BOOL bTUILoaded; // Tells us if the user interface is loaded
+extern ULONG BootDrive; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
+extern ULONG BootPartition; // Boot Partition, 1-4
+extern BOOL UserInterfaceUp; // Tells us if the user interface is displayed
-extern char *pFreeldrIni; // Load address for freeldr.ini
-extern char *pScreenBuffer; // Save address for screen contents
-extern int nCursorXPos; // Cursor's X Position
-extern int nCursorYPos; // Cursor's Y Position
+extern PUCHAR ScreenBuffer; // Save buffer for screen contents
+extern int CursorXPos; // Cursor's X Position
+extern int CursorYPos; // Cursor's Y Position
extern OSTYPE OSList[16]; // The OS list
extern int nNumOS; // Number of OSes listed
extern int nTimeOut; // Time to wait for the user before booting
void BootMain(void);
-BOOL ParseIniFile(void);
-int GetNumSectionItems(char *section); // returns the number of items in a particular section (i.e. [FREELOADER])
-BOOL ReadSectionSettingByNumber(char *section, int num, char *name, char *value); // Reads the num'th value from section
-BOOL ReadSectionSettingByName(char *section, char *valuename, char *name, char *value); // Reads the value named name from section
-BOOL IsValidSetting(char *setting, char *value);
-void SetSetting(char *setting, char *value);
#endif // defined __FREELDR_H
\ No newline at end of file
#define FS_DO_ERROR(s) \
{ \
- if (bTUILoaded) \
+ if (UserInterfaceUp) \
MessageBox(s); \
else \
{ \
memcpy((void*)0x90000, bootsector, 512);
memcpy((void*)0x90200, setup, 2048);
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
showcursor();
- gotoxy(nCursorXPos, nCursorYPos);
+ gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToLinuxBootCode();
#include "freeldr.h"
#include "memory.h"
+#include "stdlib.h"
+#include "debug.h"
+#define MEM_BLOCK_SIZE 256
-void InitMemoryManager(void *HeapBaseAddress, unsigned long HeapLength)
+typedef struct
{
+ BOOL MemBlockAllocated; // Is this block allocated or free
+ ULONG BlocksAllocated; // Block length, in multiples of 256 bytes
+} MEMBLOCK, *PMEMBLOCK;
+
+PVOID HeapBaseAddress = NULL;
+ULONG HeapLengthInBytes = 0;
+ULONG HeapMemBlockCount = 0;
+PMEMBLOCK HeapMemBlockArray = NULL;
+
+#ifdef DEBUG
+ULONG AllocationCount = 0;
+
+VOID VerifyHeap(VOID);
+VOID IncrementAllocationCount(VOID);
+VOID DecrementAllocationCount(VOID);
+VOID MemAllocTest(VOID);
+#endif DEBUG
+
+VOID InitMemoryManager(PVOID BaseAddress, ULONG Length)
+{
+ ULONG MemBlocks;
+
+ // Calculate how many memory blocks we have
+ MemBlocks = (Length / MEM_BLOCK_SIZE);
+
+ // Adjust the heap length so we can reserve
+ // enough storage space for the MEMBLOCK array
+ Length -= (MemBlocks * sizeof(MEMBLOCK));
+
+ // Initialize our tracking variables
+ HeapBaseAddress = BaseAddress;
+ HeapLengthInBytes = Length;
+ HeapMemBlockCount = (HeapLengthInBytes / MEM_BLOCK_SIZE);
+ HeapMemBlockArray = (PMEMBLOCK)(HeapBaseAddress + HeapLengthInBytes);
+
+ // Clear the memory
+ ZeroMemory(HeapBaseAddress, HeapLengthInBytes);
+ ZeroMemory(HeapMemBlockArray, (HeapMemBlockCount * sizeof(MEMBLOCK)));
+
+#ifdef DEBUG
+ DebugPrint(DPRINT_MEMORY, "Memory Manager initialized. BaseAddress = 0x%x Length = 0x%x. %d blocks in heap.\n", BaseAddress, Length, HeapMemBlockCount);
+ //MemAllocTest();
+#endif
}
-void *malloc(int size)
+PVOID AllocateMemory(ULONG NumberOfBytes)
{
- return 0;
+ ULONG BlocksNeeded;
+ ULONG Idx;
+ ULONG NumFree;
+ PVOID MemPointer;
+
+#ifdef DEBUG
+ VerifyHeap();
+#endif DEBUG
+
+ // Find out how many blocks it will take to
+ // satisfy this allocation
+ BlocksNeeded = ROUND_UP(NumberOfBytes, MEM_BLOCK_SIZE) / MEM_BLOCK_SIZE;
+
+ // Now loop through our array of blocks and
+ // see if we have enough space
+ for (Idx=0,NumFree=0; Idx<HeapMemBlockCount; Idx++)
+ {
+ // Check this block and see if it is already allocated
+ // If so reset our counter and continue the loop
+ if (HeapMemBlockArray[Idx].MemBlockAllocated)
+ {
+ NumFree = 0;
+ continue;
+ }
+ else
+ {
+ // It is free memory so lets increment our count
+ NumFree++;
+ }
+
+ // If we have found enough blocks to satisfy the request
+ // then we're done searching
+ if (NumFree >= BlocksNeeded)
+ {
+ break;
+ }
+ }
+ Idx++;
+
+ // If we don't have enough available mem
+ // then return NULL
+ if (NumFree < BlocksNeeded)
+ {
+ return NULL;
+ }
+
+ // Subtract the block count from Idx and we have
+ // the start block of the memory
+ Idx -= NumFree;
+
+ // Now we know which block to give them
+ MemPointer = HeapBaseAddress + (Idx * MEM_BLOCK_SIZE);
+
+ // Now loop through and mark all the blocks as allocated
+ for (NumFree=0; NumFree<BlocksNeeded; NumFree++)
+ {
+ HeapMemBlockArray[Idx + NumFree].MemBlockAllocated = TRUE;
+ HeapMemBlockArray[Idx + NumFree].BlocksAllocated = NumFree ? 0 : BlocksNeeded; // Mark only the first block with the count
+ }
+
+#ifdef DEBUG
+ IncrementAllocationCount();
+ DebugPrint(DPRINT_MEMORY, "Allocated %d bytes (%d blocks) of memory starting at block %d. AllocationCount: %d\n", NumberOfBytes, BlocksNeeded, Idx, AllocationCount);
+#endif DEBUG
+
+ // Now return the pointer
+ return MemPointer;
}
-void free(void *memblock)
+VOID FreeMemory(PVOID MemBlock)
{
+ ULONG BlockNumber;
+ ULONG BlockCount;
+ ULONG Idx;
+
+#ifdef DEBUG
+ VerifyHeap();
+
+ // Make sure we didn't get a bogus pointer
+ if ((MemBlock < HeapBaseAddress) || (MemBlock > (HeapBaseAddress + HeapLengthInBytes)))
+ {
+ BugCheck1("Bogus memory pointer (0x%x) passed to FreeMemory()\n", MemBlock);
+ }
+#endif DEBUG
+
+ // Find out the block number if the first
+ // block of memory they allocated
+ BlockNumber = (MemBlock - HeapBaseAddress) / MEM_BLOCK_SIZE;
+ BlockCount = HeapMemBlockArray[BlockNumber].BlocksAllocated;
+
+#ifdef DEBUG
+ // Make sure we didn't get a bogus pointer
+ if ((BlockCount < 1) || (BlockCount > HeapMemBlockCount))
+ {
+ BugCheck1("Invalid block count in heap page header. HeapMemBlockArray[BlockNumber].BlocksAllocated = %d\n", HeapMemBlockArray[BlockNumber].BlocksAllocated);
+ }
+#endif
+
+ // Loop through our array and mark all the
+ // blocks as free
+ for (Idx=BlockNumber; Idx<(BlockNumber + BlockCount); Idx++)
+ {
+ HeapMemBlockArray[Idx].MemBlockAllocated = FALSE;
+ HeapMemBlockArray[Idx].BlocksAllocated = 0;
+ }
+
+#ifdef DEBUG
+ DecrementAllocationCount();
+ DebugPrint(DPRINT_MEMORY, "Freed %d blocks of memory starting at block %d. AllocationCount: %d\n", BlockCount, BlockNumber, AllocationCount);
+#endif DEBUG
+}
+
+#ifdef DEBUG
+VOID VerifyHeap(VOID)
+{
+ ULONG Idx;
+ ULONG Idx2;
+ ULONG Count;
+
+ // Loop through the array and verify that
+ // everything is kosher
+ for (Idx=0; Idx<HeapMemBlockCount; Idx++)
+ {
+ // Check if this block is allocation
+ if (HeapMemBlockArray[Idx].MemBlockAllocated)
+ {
+ // This is the first block in the run so it
+ // had better have a length that is within range
+ if ((HeapMemBlockArray[Idx].BlocksAllocated < 1) || (HeapMemBlockArray[Idx].BlocksAllocated > (HeapMemBlockCount - Idx)))
+ {
+ BugCheck1("Allocation length out of range in heap table. HeapMemBlockArray[Idx].BlocksAllocated = %d\n", HeapMemBlockArray[Idx].BlocksAllocated);
+ }
+
+ // Now go through and verify that the rest of
+ // this run has the blocks marked allocated
+ // with a length of zero but don't check the
+ // first one because we already did
+ Count = HeapMemBlockArray[Idx].BlocksAllocated;
+ for (Idx2=1; Idx2<Count; Idx2++)
+ {
+ // Make sure it's allocated
+ if (HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE)
+ {
+ BugCheck0("Heap table indicates hole in memory allocation. HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE\n");
+ }
+
+ // Make sure the length is zero
+ if (HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0)
+ {
+ BugCheck0("Allocation chain has non-zero value in non-first block in heap table. HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0\n");
+ }
+ }
+
+ // Move on to the next run
+ Idx += Count;
+ }
+ else
+ {
+ // Nope, not allocated so make sure the length is zero
+ if (HeapMemBlockArray[Idx].BlocksAllocated != 0)
+ {
+ BugCheck0("Free block is start of memory allocation. HeapMemBlockArray[Idx].BlocksAllocated != 0\n");
+ }
+ }
+ }
+}
+
+VOID IncrementAllocationCount(VOID)
+{
+ AllocationCount++;
+}
+
+VOID DecrementAllocationCount(VOID)
+{
+ AllocationCount--;
+}
+
+VOID MemAllocTest(VOID)
+{
+ PVOID MemPtr1;
+ PVOID MemPtr2;
+ PVOID MemPtr3;
+ PVOID MemPtr4;
+ PVOID MemPtr5;
+
+ MemPtr1 = AllocateMemory(4096);
+ printf("MemPtr1: 0x%x\n", (int)MemPtr1);
+ getch();
+ MemPtr2 = AllocateMemory(4096);
+ printf("MemPtr2: 0x%x\n", (int)MemPtr2);
+ getch();
+ MemPtr3 = AllocateMemory(4096);
+ printf("MemPtr3: 0x%x\n", (int)MemPtr3);
+ getch();
+
+ FreeMemory(MemPtr2);
+ getch();
+
+ MemPtr4 = AllocateMemory(2048);
+ printf("MemPtr4: 0x%x\n", (int)MemPtr4);
+ getch();
+ MemPtr5 = AllocateMemory(4096);
+ printf("MemPtr5: 0x%x\n", (int)MemPtr5);
+ getch();
}
+#endif DEBUG
#include "multiboot.h"
-void InitMemoryManager(void *HeapBaseAddress, unsigned long HeapLength);
+VOID InitMemoryManager(PVOID BaseAddress, ULONG Length);
-void* malloc(int size);
-void free(void *memblock);
+PVOID AllocateMemory(ULONG NumberOfBytes);
+VOID FreeMemory(PVOID MemBlock);
// These functions are implemented in mem.S
int GetExtendedMemorySize(void); // Returns extended memory size in KB
#include "stdlib.h"
#include "fs.h"
#include "tui.h"
+#include "parseini.h"
void LoadAndBootBootSector(int nOSToBoot)
{
MessageLine(value);
}
- if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", name, value))
+ if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
{
MessageBox("Boot drive not specified for selected OS!");
return;
BootDrive = atoi(value);
BootPartition = 0;
- if (ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", name, value))
+ if (ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", value))
BootPartition = atoi(value);
- if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootSector", name, value))
+ if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootSector", value))
{
MessageBox("Boot sector file not specified for selected OS!");
return;
return;
}
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
showcursor();
- gotoxy(nCursorXPos, nCursorYPos);
+ gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
MessageLine(value);
}
- if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", name, value))
+ if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
{
MessageBox("Boot drive not specified for selected OS!");
return;
BootDrive = atoi(value);
- if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", name, value))
+ if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", value))
{
MessageBox("Boot partition not specified for selected OS!");
return;
return;
}
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
showcursor();
- gotoxy(nCursorXPos, nCursorYPos);
+ gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
MessageLine(value);
}
- if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", name, value))
+ if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
{
MessageBox("Boot drive not specified for selected OS!");
return;
return;
}
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
showcursor();
- gotoxy(nCursorXPos, nCursorYPos);
+ gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
#include "fs.h"
#include "multiboot.h"
#include "tui.h"
+#include "parseini.h"
unsigned long next_module_load_base = 0;
int GetBootPartition(char *OperatingSystemName)
{
int BootPartitionNumber = -1;
- char name[1024];
char value[1024];
- if (ReadSectionSettingByName(OperatingSystemName, "BootPartition", name, value))
+ if (ReadSectionSettingByName(OperatingSystemName, "BootPartition", value))
{
BootPartitionNumber = atoi(value);
}
#define MB_INFO_FLAG_APM_TABLE 0x00000400
#define MB_INFO_FLAG_GRAPHICS_TABLE 0x00000800
-#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-
#ifndef ASM
/* Do not include here in boot.S. */
return;
}
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
showcursor();
- gotoxy(nCursorXPos, nCursorYPos);
+ gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
return;
}
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
showcursor();
- gotoxy(nCursorXPos, nCursorYPos);
+ gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
--- /dev/null
+/*
+ * FreeLoader
+ * Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "freeldr.h"
+#include "parseini.h"
+#include "tui.h"
+#include "fs.h"
+#include "stdlib.h"
+#include "memory.h"
+
+PUCHAR FreeLoaderIniFileData = NULL;
+ULONG FreeLoaderIniFileSize = 0;
+
+BOOL ParseIniFile(void)
+{
+ int i;
+ char name[1024];
+ char value[1024];
+ FILE Freeldr_Ini; // File handle for freeldr.ini
+
+ // Open the boot drive for file access
+ if (!OpenDiskDrive(BootDrive, 0))
+ {
+ printf("Error opening boot drive for file access.\n");
+ return FALSE;
+ }
+
+ // Try to open freeldr.ini or fail
+ if (!OpenFile("freeldr.ini", &Freeldr_Ini))
+ {
+ printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n");
+ return FALSE;
+ }
+
+ // Get the file size & allocate enough memory for it
+ FreeLoaderIniFileSize = GetFileSize(&Freeldr_Ini);
+ FreeLoaderIniFileData = AllocateMemory(FreeLoaderIniFileSize);
+
+ // If we are out of memory then return FALSE
+ if (FreeLoaderIniFileData == NULL)
+ {
+ printf("Out of memory while loading FREELDR.INI.\n");
+ return FALSE;
+ }
+
+ // Read freeldr.ini off the disk
+ ReadFile(&Freeldr_Ini, FreeLoaderIniFileSize, FreeLoaderIniFileData);
+
+ // Make sure the [FREELOADER] section exists
+ if (!GetNumSectionItems("FREELOADER"))
+ {
+ printf("Section [FREELOADER] not found in FREELDR.INI.\nYou need to re-install FreeLoader.\n");
+ return FALSE;
+ }
+
+ // Validate the settings in the [FREELOADER] section
+ for (i=1; i<=GetNumSectionItems("FREELOADER"); i++)
+ {
+ ReadSectionSettingByNumber("FREELOADER", i, name, value);
+ if (!IsValidSetting(name, value))
+ {
+ printf("Invalid setting in freeldr.ini.\nName: \"%s\", Value: \"%s\"\n", name, value);
+ printf("Press any key to continue.\n");
+ getch();
+ }
+ else
+ SetSetting(name, value);
+ }
+
+ return TRUE;
+}
+
+ULONG GetNextLineOfFileData(PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset)
+{
+ ULONG Idx;
+
+ // Loop through grabbing chars until we hit the end of the
+ // file or we encounter a new line char
+ for (Idx=0; (CurrentOffset < FreeLoaderIniFileSize); CurrentOffset++)
+ {
+ // If we haven't exceeded our buffer size yet
+ // then store another char
+ if (Idx < (BufferSize - 1))
+ {
+ Buffer[Idx++] = FreeLoaderIniFileData[CurrentOffset];
+ }
+
+ // Check for new line char
+ if (FreeLoaderIniFileData[CurrentOffset] == '\n')
+ {
+ CurrentOffset++;
+ break;
+ }
+ }
+
+ // Terminate the string
+ Buffer[Idx] = '\0';
+
+ // Get rid of newline & linefeed characters (if any)
+ if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r'))
+ Buffer[strlen(Buffer)-1] = '\0';
+ if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r'))
+ Buffer[strlen(Buffer)-1] = '\0';
+
+ // Send back new offset
+ return CurrentOffset;
+}
+
+ULONG GetOffsetOfFirstLineOfSection(PUCHAR SectionName)
+{
+ char str[1024];
+ char real_section[1024];
+ ULONG freeldr_ini_offset;
+ BOOL SectionFound = FALSE;
+
+ // Get the real section name
+ strcpy(real_section, "[");
+ strcat(real_section, SectionName);
+ strcat(real_section, "]");
+
+ // Get to the beginning of the file
+ freeldr_ini_offset = 0;
+
+ // Find the section
+ while (freeldr_ini_offset < FreeLoaderIniFileSize)
+ {
+ // Read a line
+ freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+ // Skip comments
+ if (str[0] == '#')
+ continue;
+
+ // Skip blank lines
+ if (!strlen(str))
+ continue;
+
+ // If it isn't a section header then continue on
+ if (str[0] != '[')
+ continue;
+
+ // Check and see if we found it
+ if (stricmp(str, real_section) == 0)
+ {
+ SectionFound = TRUE;
+ break;
+ }
+ }
+
+ // If we didn't find the section then we're outta here
+ if (!SectionFound)
+ return 0;
+
+ return freeldr_ini_offset;
+}
+
+ULONG GetNumSectionItems(PUCHAR SectionName)
+{
+ UCHAR str[1024];
+ ULONG num_items = 0;
+ ULONG freeldr_ini_offset;
+
+ // Get to the beginning of the section
+ freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
+
+ // If the section wasn't found then exit
+ if (freeldr_ini_offset == 0)
+ {
+ return 0;
+ }
+
+ // Now count how many settings are in this section
+ while (freeldr_ini_offset < FreeLoaderIniFileSize)
+ {
+ // Read a line
+ freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+ // Skip comments
+ if (str[0] == '#')
+ continue;
+
+ // Skip blank lines
+ if (!strlen(str))
+ continue;
+
+ // If we hit a new section then we're done
+ if (str[0] == '[')
+ break;
+
+ num_items++;
+ }
+
+ return num_items;
+}
+
+BOOL ReadSectionSettingByNumber(PUCHAR SectionName, ULONG SettingNumber, PUCHAR SettingName, PUCHAR SettingValue)
+{
+ UCHAR str[1024];
+ ULONG num_items = 0;
+ ULONG i;
+ ULONG freeldr_ini_offset;
+
+ // Get to the beginning of the section
+ freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
+
+ // If the section wasn't found then exit
+ if (freeldr_ini_offset == 0)
+ {
+ return 0;
+ }
+
+ // Now find the setting we are looking for
+ while (freeldr_ini_offset < FreeLoaderIniFileSize)
+ {
+ // Read a line
+ freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+ // Skip comments
+ if (str[0] == '#')
+ continue;
+
+ // Skip blank lines
+ if (!strlen(str))
+ continue;
+
+ // If we hit a new section then we're done
+ if (str[0] == '[')
+ break;
+
+ // Increment setting number
+ num_items++;
+
+ // Check and see if we found the setting
+ if (num_items == SettingNumber)
+ {
+ for (i=0; i<strlen(str); i++)
+ {
+ // Check and see if this character is the separator
+ if (str[i] == '=')
+ {
+ SettingName[i] = '\0';
+
+ strcpy(SettingValue, str+i+1);
+
+ return TRUE;
+ }
+ else
+ SettingName[i] = str[i];
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL ReadSectionSettingByName(PUCHAR SectionName, PUCHAR SettingName, PUCHAR SettingValue)
+{
+ UCHAR str[1024];
+ UCHAR temp[1024];
+ ULONG i;
+ ULONG freeldr_ini_offset;
+
+ // Get to the beginning of the section
+ freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
+
+ // If the section wasn't found then exit
+ if (freeldr_ini_offset == 0)
+ {
+ return 0;
+ }
+
+ // Now find the setting we are looking for
+ while (freeldr_ini_offset < FreeLoaderIniFileSize)
+ {
+ // Read a line
+ freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+ // Skip comments
+ if (str[0] == '#')
+ continue;
+
+ // Skip blank lines
+ if (!strlen(str))
+ continue;
+
+ // If we hit a new section then we're done
+ if (str[0] == '[')
+ break;
+
+ // Extract the setting name
+ for (i=0; i<strlen(str); i++)
+ {
+ if (str[i] != '=')
+ temp[i] = str[i];
+ else
+ {
+ temp[i] = '\0';
+ break;
+ }
+ }
+
+ // Check and see if we found the setting
+ if (stricmp(temp, SettingName) == 0)
+ {
+ for (i=0; i<strlen(str); i++)
+ {
+ // Check and see if this character is the separator
+ if (str[i] == '=')
+ {
+ strcpy(SettingValue, str+i+1);
+
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL IsValidSetting(char *setting, char *value)
+{
+ if(stricmp(setting, "MessageBox") == 0)
+ return TRUE;
+ else if(stricmp(setting, "MessageLine") == 0)
+ return TRUE;
+ else if(stricmp(setting, "TitleText") == 0)
+ return TRUE;
+ else if(stricmp(setting, "StatusBarColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "StatusBarTextColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "BackdropTextColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "BackdropColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "BackdropFillStyle") == 0)
+ {
+ if(IsValidFillStyle(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "TitleBoxTextColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "TitleBoxColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "MessageBoxTextColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "MessageBoxColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "MenuTextColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "MenuColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "TextColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "SelectedTextColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "SelectedColor") == 0)
+ {
+ if(IsValidColor(value))
+ return TRUE;
+ }
+ else if(stricmp(setting, "OS") == 0)
+ return TRUE;
+ else if(stricmp(setting, "TimeOut") == 0)
+ return TRUE;
+ /*else if(stricmp(setting, "") == 0)
+ return TRUE;
+ else if(stricmp(setting, "") == 0)
+ return TRUE;
+ else if(stricmp(setting, "") == 0)
+ return TRUE;
+ else if(stricmp(setting, "") == 0)
+ return TRUE;
+ else if(stricmp(setting, "") == 0)
+ return TRUE;
+ else if(stricmp(setting, "") == 0)
+ return TRUE;
+ else if(stricmp(setting, "") == 0)
+ return TRUE;*/
+
+ return FALSE;
+}
+
+void SetSetting(char *setting, char *value)
+{
+ char v[260];
+
+ if(stricmp(setting, "TitleText") == 0)
+ strcpy(szTitleBoxTitleText, value);
+ else if(stricmp(setting, "StatusBarColor") == 0)
+ cStatusBarBgColor = TextToColor(value);
+ else if(stricmp(setting, "StatusBarTextColor") == 0)
+ cStatusBarFgColor = TextToColor(value);
+ else if(stricmp(setting, "BackdropTextColor") == 0)
+ cBackdropFgColor = TextToColor(value);
+ else if(stricmp(setting, "BackdropColor") == 0)
+ cBackdropBgColor = TextToColor(value);
+ else if(stricmp(setting, "BackdropFillStyle") == 0)
+ cBackdropFillStyle = TextToFillStyle(value);
+ else if(stricmp(setting, "TitleBoxTextColor") == 0)
+ cTitleBoxFgColor = TextToColor(value);
+ else if(stricmp(setting, "TitleBoxColor") == 0)
+ cTitleBoxBgColor = TextToColor(value);
+ else if(stricmp(setting, "MessageBoxTextColor") == 0)
+ cMessageBoxFgColor = TextToColor(value);
+ else if(stricmp(setting, "MessageBoxColor") == 0)
+ cMessageBoxBgColor = TextToColor(value);
+ else if(stricmp(setting, "MenuTextColor") == 0)
+ cMenuFgColor = TextToColor(value);
+ else if(stricmp(setting, "MenuColor") == 0)
+ cMenuBgColor = TextToColor(value);
+ else if(stricmp(setting, "TextColor") == 0)
+ cTextColor = TextToColor(value);
+ else if(stricmp(setting, "SelectedTextColor") == 0)
+ cSelectedTextColor = TextToColor(value);
+ else if(stricmp(setting, "SelectedColor") == 0)
+ cSelectedTextBgColor = TextToColor(value);
+ else if(stricmp(setting, "OS") == 0)
+ {
+ if(nNumOS >= 16)
+ {
+ printf("Error: you can only boot to at most 16 different operating systems.\n");
+ printf("Press any key to continue\n");
+ getch();
+ return;
+ }
+
+ if(!GetNumSectionItems(value))
+ {
+ printf("Error: OS \"%s\" listed.\n", value);
+ printf("It does not have it's own [section], or it is empty.\n");
+ printf("Press any key to continue\n");
+ getch();
+ return;
+ }
+
+ strcpy(OSList[nNumOS].name, value);
+
+ if (!ReadSectionSettingByName(value, "BootType", v))
+ {
+ printf("Unknown BootType for OS \"%s\"\n", value);
+ printf("Press any key to continue\n");
+ getch();
+ return;
+ }
+
+ if (stricmp(v, "ReactOS") == 0)
+ OSList[nNumOS].nOSType = OSTYPE_REACTOS;
+ else if (stricmp(v, "Linux") == 0)
+ OSList[nNumOS].nOSType = OSTYPE_LINUX;
+ else if (stricmp(v, "BootSector") == 0)
+ OSList[nNumOS].nOSType = OSTYPE_BOOTSECTOR;
+ else if (stricmp(v, "Partition") == 0)
+ OSList[nNumOS].nOSType = OSTYPE_PARTITION;
+ else if (stricmp(v, "Drive") == 0)
+ OSList[nNumOS].nOSType = OSTYPE_DRIVE;
+ else
+ {
+ printf("Unknown BootType for OS \"%s\"\n", value);
+ printf("Press any key to continue\n");
+ getch();
+ return;
+ }
+
+ nNumOS++;
+ }
+ else if(stricmp(setting, "TimeOut") == 0)
+ nTimeOut = atoi(value);
+}
--- /dev/null
+/*
+ * FreeLoader
+ * Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PARSEINI_H
+#define __PARSEINI_H
+
+BOOL ParseIniFile(void);
+ULONG GetNextLineOfFileData(PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset); // Gets the next line of text (up to BufferSize) after CurrentOffset and returns the offset of the next line
+ULONG GetOffsetOfFirstLineOfSection(PUCHAR SectionName); // Returns the offset of the first line in the section or zero if the section wasn't found
+ULONG GetNumSectionItems(PUCHAR SectionName); // returns the number of items in a particular section (i.e. [FREELOADER])
+BOOL ReadSectionSettingByNumber(PUCHAR SectionName, ULONG SettingNumber, PUCHAR SettingName, PUCHAR SettingValue); // Reads the num'th value from section
+BOOL ReadSectionSettingByName(PUCHAR SectionName, PUCHAR SettingName, PUCHAR SettingValue); // Reads the value named name from section
+BOOL IsValidSetting(char *setting, char *value);
+void SetSetting(char *setting, char *value);
+
+
+#endif // defined __PARSEINI_H
\ No newline at end of file
#include "multiboot.h"
#include "arcname.h"
#include "memory.h"
+#include "parseini.h"
-BOOL LoadReactOSKernel(char *OperatingSystemName);
-BOOL LoadReactOSDrivers(char *OperatingSystemName);
+BOOL LoadReactOSKernel(PUCHAR OperatingSystemName);
+BOOL LoadReactOSDrivers(PUCHAR OperatingSystemName);
-void LoadAndBootReactOS(char *OperatingSystemName)
+void LoadAndBootReactOS(PUCHAR OperatingSystemName)
{
FILE file;
char name[1024];
/*
* Make sure the system path is set in the .ini file
*/
- if(!ReadSectionSettingByName(OperatingSystemName, "SystemPath", name, value))
+ if (!ReadSectionSettingByName(OperatingSystemName, "SystemPath", value))
{
MessageBox("System path not specified for selected operating system.");
return;
/*
* Verify system path
*/
- if(!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
+ if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
{
sprintf(MsgBuffer,"Invalid system path: '%s'", value);
MessageBox(MsgBuffer);
/*
* Read the optional kernel parameters (if any)
*/
- if (ReadSectionSettingByName(OperatingSystemName, "Options", name, value))
+ if (ReadSectionSettingByName(OperatingSystemName, "Options", value))
{
strcat(multiboot_kernel_cmdline, " ");
strcat(multiboot_kernel_cmdline, value);
/*
* Find the kernel image name
*/
- if(!ReadSectionSettingByName(OperatingSystemName, "Kernel", name, value))
+ if(!ReadSectionSettingByName(OperatingSystemName, "Kernel", value))
{
MessageBox("Kernel image file not specified for selected operating system.");
return;
* Find the kernel image name
* and try to load the kernel off the disk
*/
- if(ReadSectionSettingByName(OperatingSystemName, "Kernel", name, value))
+ if(ReadSectionSettingByName(OperatingSystemName, "Kernel", value))
{
/*
* Set the name and try to open the PE image
strcat(name, ".");
//MessageBox(name);
- RestoreScreen(pScreenBuffer);
+ RestoreScreen(ScreenBuffer);
/*
* Now boot the kernel
#define __ROSBOOT_H
-void LoadAndBootReactOS(char *OperatingSystemName);
+void LoadAndBootReactOS(PUCHAR OperatingSystemName);
#endif // defined __ROSBOOT_H
\ No newline at end of file
char *fgets(char *string, int n, FILE *stream);
int atoi(char *string);
+#define ZeroMemory(Destination, Length) memset(Destination, 0, Length)
+
void print(char *str);
void printf(char *fmt, ...);
void sprintf(char *buffer, char *format, ...);
+char *convert_to_ascii(char *buf, int c, ...);
+
int biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buffer); // Implemented in asmcode.S
void stop_floppy(void); // Implemented in asmcode.S
int get_heads(int drive); // Implemented in asmcode.S