feat(tools): dump partition table

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-04-14 07:35:43 +02:00
parent e7f75acb13
commit e5fa803eb0
13 changed files with 373 additions and 47 deletions

View file

@ -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)

View file

@ -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

32
boot/bootsect/mbr.asm Normal file
View file

@ -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

View file

@ -2,6 +2,7 @@ CR = 0x0D
LF = 0x0A
; -------- Address ----------
MBR_BASE = 0x0600
BOOTSECT_BASE = 0x7C00
LOADER_BASE = 0x1000
MULTIBOOT_BASE = 0x100000

View file

@ -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

View file

@ -2,6 +2,7 @@
format binary
include '../common/const.inc'
include '../common/macro.inc'
include 'multiboot.inc'
org LOADER_BASE
@ -76,6 +77,7 @@ _start:
include 'gdt.inc'
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

View file

@ -1,28 +1,78 @@
;; File: memory.inc
;; Detect available memory
;;
; 0xE820 Get System Memory Map
; EAX=0x0000E820
; EDX=0x534D4150
; EBX=0x0 or continuation value
; ECX=buffer size
; ES:SI = buffer
memory_do_E820:
;; Constants: Address type
;;
;; See <AddressRange.Type>
;;
;; 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. <Address type>
.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:
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

View file

@ -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

8
include/fs/echfs.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef ECHFS_H
# define ECHFS_H 1
typedef struct {
} EchFSIdentityTable;
#endif /* !ECHFS_H */

0
include/fs/fat12.h Normal file
View file

16
sbin/parted/Makefile Normal file
View file

@ -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)

157
sbin/parted/main.c Normal file
View file

@ -0,0 +1,157 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#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);
}

View file

@ -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)