diff --git a/boot/bootsect/Makefile b/boot/bootsect/Makefile index 72507a2..a9baec3 100644 --- a/boot/bootsect/Makefile +++ b/boot/bootsect/Makefile @@ -1,10 +1,15 @@ TARGET = boot_floppy1440.bin \ - boot_floppy2880.bin + boot_floppy2880.bin \ + boot_mbr.bin FLOPPY_SRCS = floppy.asm \ ../common/const.inc \ ../common/fat12.inc +MBR_SRCS = mbr.asm \ + ../common/const.inc \ + ../common/fat12.inc + .PHONY: all all: $(TARGET) @@ -14,6 +19,9 @@ boot_floppy1440.bin: $(FLOPPY_SRCS) boot_floppy2880.bin: $(FLOPPY_SRCS) $(AS) -DFLOPPY_SIZE=FLOPPY_2880 floppy.asm $@ +boot_mbr.bin: $(MBR_SRCS) + $(AS) mbr.asm $@ + .PHONY: clean clean: $(RM) $(TARGET) diff --git a/boot/bootsect/floppy.asm b/boot/bootsect/floppy.asm index 22678d0..780c47f 100644 --- a/boot/bootsect/floppy.asm +++ b/boot/bootsect/floppy.asm @@ -70,11 +70,6 @@ _start: ; search in root directory - mov si, kernel_file - call fat_search_root - jc .error_not_found - mov [kernel_start], ax - mov si, stage1_file call fat_search_root jc .error_not_found @@ -91,13 +86,6 @@ _start: call disk_read_sectors - ; preload kernel - mov ax, KERNEL_PRELOAD/0x10 - mov es, ax - mov ax, [kernel_start] - xor bx, bx - call fat_load_binary - ; load stage 2 mov ax, LOADER_BASE/0x10 mov es, ax @@ -124,10 +112,8 @@ _start: msg_error db "ERROR: ", 0 msg_not_found db " not found", CR, LF, 0 -kernel_file db "VMSTUPIDSYS", 0 stage1_file db "STPDLDR SYS", 0 -kernel_start dw 0x0 stage1_start dw 0x0 diff --git a/boot/bootsect/mbr.asm b/boot/bootsect/mbr.asm new file mode 100644 index 0000000..956d22e --- /dev/null +++ b/boot/bootsect/mbr.asm @@ -0,0 +1,32 @@ + format binary + use16 + + include '../common/const.inc' + include '../common/macro.inc' + + org MBR_BASE + cli + xor ax, ax + mov ds, ax + mov es, ax + mov ss, ax + mov sp, ax + cld + ; relocate from 0x7C00 to 0x0600 + mov cx, 0x0100 + mov si, BOOTSECT_BASE + mov di, MBR_BASE + rep movsw + jmp 0x0:start +start: + ; TODO: read partition table and load bootable one. + + times 436-($-$$) db 0x90 +UID db 'STUPIDDISK' + ; partition table +PT1 db 16 dup(0) +PT2 db 16 dup(0) +PT3 db 16 dup(0) +PT4 db 16 dup(0) + ; magic + db 0x55, 0xAA diff --git a/boot/common/const.inc b/boot/common/const.inc index 4bdd4a0..2faf3e2 100644 --- a/boot/common/const.inc +++ b/boot/common/const.inc @@ -2,6 +2,7 @@ CR = 0x0D LF = 0x0A ; -------- Address ---------- +MBR_BASE = 0x0600 BOOTSECT_BASE = 0x7C00 LOADER_BASE = 0x1000 MULTIBOOT_BASE = 0x100000 diff --git a/boot/efi/uefi.inc b/boot/efi/uefi.inc index 14c8602..e13881c 100644 --- a/boot/efi/uefi.inc +++ b/boot/efi/uefi.inc @@ -139,6 +139,7 @@ defn EFI_SYSTEM_TABLE EFI_BOOT_SERVICES_SIGNATURE = 0x56524553544f4f42 EFI_BOOT_SERVICES_REVISION = EFI_SPECIFICATION_VERSION + ;; Struct: EFI_BOOT_SERVICES struc EFI_BOOT_SERVICES { .Hdr EFI_TABLE_HEADER @@ -150,6 +151,7 @@ struc EFI_BOOT_SERVICES EFI_RUNTIMES_SERVICES_SIGNATURE = 0x56524553544e5552 EFI_RUNTIMES_SERVICES_REVISION = EFI_SPECIFICATION_VERSION + ;; Struct: EFI_RUNTIMES_SERVICES struc EFI_RUNTIMES_SERVICES { .Hdr EFI_TABLE_HEADER @@ -161,6 +163,7 @@ struc EFI_RUNTIMES_SERVICES EFI_LOADED_IMAGE_PROTOCOL_GUID equ 0x5B1B31A1, 0x9562, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3D EFI_LOADED_IMAGE_PROTOCOL_REVISION = 0x1000 + ;; Struct: EFI_LOADED_IMAGE_PROTOCOL struc EFI_LOADED_IMAGE_PROTOCOL { .Revision UINT32 diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index c3e94d4..056bc88 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -2,6 +2,7 @@ format binary include '../common/const.inc' + include '../common/macro.inc' include 'multiboot.inc' org LOADER_BASE @@ -75,9 +76,10 @@ _start: include 'video.inc' include 'gdt.inc' -msg_stage2 db "StupidOS Loader", CR, LF, 0 -msg_error_a20 db "ERROR: can't enable a20 line", CR, LF, 0 -msg_error_memory db "ERROR: can't detect available memory", CR, LF, 0 +msg_stage2 db "StupidOS Loader", CR, LF, 0 +kernel_fat12_file db "VMSTUPIDSYS", 0 +msg_error_a20 db "ERROR: can't enable a20 line", CR, LF, 0 +msg_error_memory db "ERROR: can't detect available memory", CR, LF, 0 use32 ; ========================================================================= diff --git a/boot/loader/memory.inc b/boot/loader/memory.inc index 096fe9f..cedd087 100644 --- a/boot/loader/memory.inc +++ b/boot/loader/memory.inc @@ -1,28 +1,78 @@ - - ; 0xE820 Get System Memory Map - ; EAX=0x0000E820 - ; EDX=0x534D4150 - ; EBX=0x0 or continuation value - ; ECX=buffer size - ; ES:SI = buffer -memory_do_E820: - - ret - -memory_get_map: - call memory_do_E820 - jnc .end - - ; try 0x88 - clc - mov ah, 0x88 - int 0x15 - jc .error - test ax, ax - je .error -.end: - clc - ret -.error: - stc - ret \ No newline at end of file + ;; File: memory.inc + ;; Detect available memory + ;; + + ;; Constants: Address type + ;; + ;; See + ;; + ;; ADDRESS_RANGE_MEMORY - Available and usable RAM. + ;; ADDRESS_RANGE_RESERVED - Reserved or in use. +ADDRESS_RANGE_MEMORY = 1 +ADDRESS_RANGE_RESERVED = 2 + + ;; Struct: AddressRange +struc AddressRange +{ + ;; Variable: BaseAddrLow + ;; Low 32 Bits of Base Address + .BaseAddrLow dd ? + ;; Variable: BaseAddrHigh + ;; High 32 Bits of Base Address + .BaseAddrHigh dd ? + ;; Variable: LengthLow + ;; Low 32 Bits of Length in Bytes + .LengthLow dd ? + ;; Variable: LengthHigh + ;; High 32 Bits of Length in Bytes + .LengthHigh dd ? + ;; Variable: Type + ;; Address type of this range.
+ .Type db ? +} +defn AddressRange + + ;; Function: memory_e820_get_mmap_entry + ;; + ;; In: + ;; EAX - Function code + ;; EBX - Continuation + ;; ES:DI - Buffer Pointer + ;; ECX - Buffer size + ;; EDX - Signature 'SMAP' + ;; + ;; Out: + ;; CF - Carry Flag + ;; EAX - Signature 'SMAP' + ;; ES:DI - Buffer Pointer + ;; ECX - Buffer Size + ;; EBX - Continuation +memory_e820_get_map: + mov eax, 0xE820 + mov ebx, 0x0 + mov ecx, 'SMAP' + + ret + + ;; Function: memory_get_for_large_conf + ;; + ;; In: + ;; AX - Function code E801h + ;; + ;; Out: + ;; CF - Non-Carry - indicates no error + ;; AX - Extended 1 + ;; BX - Extended 2 + ;; CX - Configured 1 + ;; DX - Configured 2 + + ;; Function: memory_get_extended_memory_size + ;; + ;; In: + ;; AH - Function code 88h + ;; + ;; Out: + ;; CF - Non-Carry - indicates no error + ;; AX - Number of contiguous KB above 1MB +memory_get_map: + ret diff --git a/boot/loader/video.inc b/boot/loader/video.inc index 2920948..35c2aa8 100644 --- a/boot/loader/video.inc +++ b/boot/loader/video.inc @@ -1,2 +1,62 @@ +struc VesaInfo +{ + .Signature dd ? + .Version dw ? + .OEMNamePtr dd ? + .Capabilities dd ? + .VideoModesOffset dw ? + .VideoModesSegment dw ? + .CountOf64KBlocks dw ? + .OEMSoftwareRevision dw ? + .OEMVendorNamePtr dd ? + .OEMProductNamePtr dd ? + .OEMProductRevisionPtr dd ? + .Reserved db 222 dup(?) + .OEMData db 256 dup(?) +} + +struc VesaModeInfo +{ + .ModeAttributes dw ? + .WindowAAttributes db ? + .WindowBAttributes db ? + .WindowGranularity dw ? + .WindowSize dw ? + .SegmentWindowA dw ? + .SegmentWindowB dw ? + .WindowPositioning dd ? + .BytesPerScanLine dw ? + + ; -- + .Width dw ? + .Height dw ? + .WidthChar db ? + .HeightChar db ? + .PlanesCount db ? + .BitsPerPixel db ? + .BanksCount db ? + .MemoryModel db ? + .BankSize db ? + .ImagePagesCount db ? + .Reserved db ? + + .RedMaskSize db ? + .RedFieldPosition db ? + .GreenMaskSize db ? + .GreenFieldPosition db ? + .BlueMaskSize db ? + .BlueFieldPosition db ? + .ReservedMaskSize db ? + .ReservedMaskPosition db ? + .DirectColorModeInfo db ? + + ; -- VBE v1.2+ + .Framebuffer dd ? + .OffScreenMemoryOffset dd ? + .OffScreenMemorySize dd ? + .Reserved2 db 206 dup(?) +} +defn VesaModeInfo + video_setup: ret diff --git a/include/fs/echfs.h b/include/fs/echfs.h new file mode 100644 index 0000000..b0c2337 --- /dev/null +++ b/include/fs/echfs.h @@ -0,0 +1,8 @@ +#ifndef ECHFS_H +# define ECHFS_H 1 + +typedef struct { + +} EchFSIdentityTable; + +#endif /* !ECHFS_H */ diff --git a/include/fs/fat12.h b/include/fs/fat12.h new file mode 100644 index 0000000..e69de29 diff --git a/sbin/parted/Makefile b/sbin/parted/Makefile new file mode 100644 index 0000000..136c349 --- /dev/null +++ b/sbin/parted/Makefile @@ -0,0 +1,16 @@ +TARGET = parted +SRCS = main.c +OBJS = $(SRCS:.c=.o) + +.PHONY: all +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -o $@ $^ $(LDFLAGS) + +.PHONY: clean +clean: + $(RM) $(TARGET) $(OBJS) + +.PHONY: install +install: $(TARGET) diff --git a/sbin/parted/main.c b/sbin/parted/main.c new file mode 100644 index 0000000..8f98e4d --- /dev/null +++ b/sbin/parted/main.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +#define MBR_MAGIC0 0x55 +#define MBR_MAGIC1 0xAA + +#define MBR_PART_BOOTABLE (1 << 7) + +enum { + MBR_PART_TYPE_EMPTY = 0x00, + MBR_PART_TYPE_FAT12 = 0x01, + MBR_PART_TYPE_FAT16 = 0x04, + MBR_PART_TYPE_GPT_PROTECTIVE = 0xEE, + MBR_PART_TYPE_EFI = 0xEF +}; + +typedef struct partition { + uint8_t attributes; + uint8_t chs_start[3]; + uint8_t type; + uint8_t chs_last_sector[3]; + uint32_t lba_start; + uint32_t sectors_count; +} __attribute__((packed)) Partition; + +typedef struct mbr_header { + uint8_t raw[436]; + uint8_t uid[10]; + struct partition part[4]; + uint8_t magic[2]; +} __attribute__((packed)) MBRHeader; + +static char *prg_name = NULL; +static int dump_info = 0; +static const char *diskpath = NULL; +static FILE *diskfd = NULL; +static MBRHeader header; + +static void +dump_partition_info(Partition part) +{ + printf("\tBootable: "); + if (part.attributes & MBR_PART_BOOTABLE) + { + printf("yes\n"); + } + else + { + printf("no\n"); + } + printf("\tType: %d\n", part.type); + printf("\tLBA Start: %d\n", part.lba_start); + printf("\tSectors: %d\n", part.sectors_count); +} + +static void +dump_disk(void) +{ + int idx; + + printf("UID: "); + for (idx = 0; idx < 10; idx++) + { + printf("%02X", header.uid[idx]); + } + printf("\n"); + + for (idx = 0; idx < 4; idx++) + { + printf("Partition %d:\n", idx); + dump_partition_info(header.part[idx]); + } +} + +static void +usage(int retcode) +{ + if (retcode == EXIT_FAILURE) + { + fprintf(stderr, "Try '%s -h' for more information.\n", prg_name); + } + else + { + printf("Usage: %s [-hVd] disk\n", prg_name); + printf("\t-h\tdisplay this help and exit\n"); + printf("\t-V\toutput version information.\n"); + printf("\t-d\tdump disk information\n"); + printf("\t-o out\twrite to file 'out'\n"); + printf("\nReport bugs to <%s>\n", MK_BUGREPORT); + } + + exit(retcode); +} + +static void +version(void) +{ + printf("%s commit %s\n", prg_name, MK_COMMIT); + exit(EXIT_SUCCESS); +} + +int +main(int argc, char **argv) +{ + prg_name = argv[0]; + + while ((argc > 1) && (argv[1][0] == '-')) + { + switch (argv[1][1]) + { + case 'h': + usage(EXIT_SUCCESS); + break; + case 'V': + version(); + break; + case 'd': + dump_info = 1; + break; + default: + usage(EXIT_FAILURE); + } + + argv++; + argc--; + } + + if (argc <= 1) usage(EXIT_FAILURE); + + diskpath = argv[1]; + diskfd = fopen(diskpath, "rb"); + if (diskfd == NULL) + { + fprintf(stderr, "%s: %s\n", diskpath, strerror(errno)); + return (EXIT_FAILURE); + } + + if (fread(&header, sizeof(uint8_t), sizeof(MBRHeader), diskfd) != sizeof(MBRHeader)) + { + fprintf(stderr, "%s: can't read mbr header\n", diskpath); + return (EXIT_FAILURE); + } + if (header.magic[0] != MBR_MAGIC0 || header.magic[1] != MBR_MAGIC1) + { + fprintf(stderr, "%s: no valid MBR\n", diskpath); + return (EXIT_FAILURE); + } + + if (dump_info) + { + dump_disk(); + } + + return (EXIT_SUCCESS); +} diff --git a/tools/Makefile b/tools/Makefile index c402fdb..9a3c492 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,7 +1,7 @@ CC = gcc RM = rm -f -TARGET = fat$(EXEXT) coff-ld$(EXEXT) +TARGET = fat$(EXEXT) coff-ld$(EXEXT) parted$(EXEXT) CFLAGS = -DMK_COMMIT="$(MK_COMMIT)" -DMK_BUGREPORT="$(MK_BUGREPORT)" -I../include LDFLAGS = @@ -15,6 +15,9 @@ fat$(EXEXT): fat.c coff-ld$(EXEXT): coff-ld.c $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) +parted$(EXEXT): ../sbin/parted/main.c + $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) + .PHONY: install install: $(TARGET)