feat(mkfs.stpd): make filesystem bootable (WIP)
This commit is contained in:
parent
a98288b28c
commit
edbd42fdf4
|
@ -13,6 +13,10 @@ AM_PROG_AR
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_RANLIB
|
AC_PROG_RANLIB
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
|
AC_CHECK_PROG([NASM], [nasm], [nasm])
|
||||||
|
AS_IF([test -z "$NASM"], [
|
||||||
|
AC_MSG_ERROR([nasm is required])
|
||||||
|
])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
noinst_LIBRARIES = libstpdfs.a
|
noinst_LIBRARIES = libstpdfs.a
|
||||||
liblzp_a_SOURCES = super.c bio.c inode.c file.c dir.c
|
libstpdfs_a_SOURCES = super.c bio.c inode.c file.c dir.c
|
|
@ -4,7 +4,16 @@ LDADD = ../lib/libstpdfs.a
|
||||||
bin_PROGRAMS = mkfs.stpd tools.stpd
|
bin_PROGRAMS = mkfs.stpd tools.stpd
|
||||||
|
|
||||||
mkfs_stpd_SOURCES = mkfs/main.c
|
mkfs_stpd_SOURCES = mkfs/main.c
|
||||||
|
mkfs_stpd_LDADD = ../lib/libstpdfs.a mkfs/bootsector.o
|
||||||
|
|
||||||
tools_stpd_SOURCES = tools/main.c
|
tools_stpd_SOURCES = tools/main.c
|
||||||
|
|
||||||
man_MANS = mkfs/mkfs.stpd.8 tools/tools.stpd.8
|
mkfs/boot.o: mkfs/boot.asm
|
||||||
|
$(NASM) -fbin -o $@ $<
|
||||||
|
|
||||||
|
mkfs/bootsector.o: mkfs/boot.o
|
||||||
|
ld -r -b binary -o $@ $<
|
||||||
|
|
||||||
|
man_MANS = mkfs/mkfs.stpd.8 tools/tools.stpd.8
|
||||||
|
|
||||||
|
CLEANFILES = mkfs/boot.o mkfs/bootsector.o
|
134
tools/mkfs/boot.asm
Normal file
134
tools/mkfs/boot.asm
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
[BITS 16]
|
||||||
|
[ORG 0x7c00]
|
||||||
|
|
||||||
|
LOADER_BASE equ 0x1000
|
||||||
|
DISK_BUFFER equ 0x8000
|
||||||
|
STPDFS_MAGIC equ 0x44505453
|
||||||
|
INODE_SIZE equ 34
|
||||||
|
INODE_ALLOCATED equ (1<<15)
|
||||||
|
|
||||||
|
struc inode
|
||||||
|
.mode: resb 1
|
||||||
|
.nlink: resb 1
|
||||||
|
.uid: resb 1
|
||||||
|
.gid: resb 1
|
||||||
|
.flags: resb 1
|
||||||
|
.size: resd 1
|
||||||
|
.zones: resd 10
|
||||||
|
.actime: resq 1
|
||||||
|
.modtime: resq 1
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
jmp start
|
||||||
|
nop
|
||||||
|
|
||||||
|
bpb:
|
||||||
|
db 0, 0, 0
|
||||||
|
.oem_id: db "STUPIDFS"
|
||||||
|
.sector_size: dw 512
|
||||||
|
.sects_per_cluster: db 0
|
||||||
|
.reserved_sects: dw 0
|
||||||
|
.fat_count: db 0
|
||||||
|
.root_dir_entries: dw 0
|
||||||
|
.sector_count: dw 0
|
||||||
|
.media_type: db 0
|
||||||
|
.sects_per_fat: dw 0
|
||||||
|
.sects_per_track: dw 18
|
||||||
|
.head_count: dw 2
|
||||||
|
.hidden_sects: dd 0
|
||||||
|
.sector_count_big: dd 0
|
||||||
|
.drive_num: db 0
|
||||||
|
.reserved: db 0
|
||||||
|
.signature: db 0
|
||||||
|
.volume_id: dd 0
|
||||||
|
.volume_label: db "STPD.MKFS "
|
||||||
|
.filesystem_type: times 8 db 0
|
||||||
|
|
||||||
|
start:
|
||||||
|
cli
|
||||||
|
cld
|
||||||
|
jmp 0x0:.canonicalize_cs
|
||||||
|
|
||||||
|
.canonicalize_cs:
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov es, ax
|
||||||
|
mov sp, 0x7c00
|
||||||
|
|
||||||
|
mov [bpb.drive_num], dl
|
||||||
|
|
||||||
|
; ensure lba mode is supported
|
||||||
|
mov ah, 0x41
|
||||||
|
mov bx, 0x55AA
|
||||||
|
int 0x13
|
||||||
|
jc .err_lba
|
||||||
|
|
||||||
|
; reset disk
|
||||||
|
.reset_disk:
|
||||||
|
mov dl, [bpb.drive_num]
|
||||||
|
xor ah, ah
|
||||||
|
int 0x13
|
||||||
|
jc .reset_disk
|
||||||
|
|
||||||
|
; read superblock
|
||||||
|
mov ax, DISK_BUFFER/10
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
; load two sector in memory
|
||||||
|
; superblock and first inodes
|
||||||
|
mov eax, 1
|
||||||
|
mov cx, 2
|
||||||
|
xor bx, bx
|
||||||
|
call disk_read_sectors
|
||||||
|
|
||||||
|
mov dword eax, [DISK_BUFFER]
|
||||||
|
cmp eax, STPDFS_MAGIC
|
||||||
|
jne .err_magic
|
||||||
|
|
||||||
|
; inode 0 bad
|
||||||
|
; inode 1 root dir
|
||||||
|
; inode 2 is loader, let's keep things easy
|
||||||
|
mov ax, word [DISK_BUFFER + 34 * 2 + inode.flags]
|
||||||
|
and ax, INODE_ALLOCATED
|
||||||
|
jz .err_no_loader
|
||||||
|
|
||||||
|
mov dword eax, [DISK_BUFFER + 34 * 2 + inode.size] ; size
|
||||||
|
|
||||||
|
mov eax, DISK_BUFFER + 34 * 2 + 14 ; first zone
|
||||||
|
|
||||||
|
|
||||||
|
jmp 0x0:LOADER_BASE
|
||||||
|
|
||||||
|
.err_no_loader:
|
||||||
|
.err_magic:
|
||||||
|
.err_lba:
|
||||||
|
hlt
|
||||||
|
jmp $
|
||||||
|
|
||||||
|
disk_read_sectors:
|
||||||
|
mov word [disk_packet.sectors], cx
|
||||||
|
mov word [disk_packet.segment], es
|
||||||
|
mov word [disk_packet.offset], bx
|
||||||
|
mov dword [disk_packet.lba], eax
|
||||||
|
mov ds, [disk_packet]
|
||||||
|
mov dl, [bpb.drive_num]
|
||||||
|
mov ah, 0x42
|
||||||
|
int 0x13
|
||||||
|
ret
|
||||||
|
|
||||||
|
disk_packet:
|
||||||
|
db 0x10
|
||||||
|
db 0
|
||||||
|
.sectors:
|
||||||
|
dw 0
|
||||||
|
.segment:
|
||||||
|
dw 0
|
||||||
|
.offset:
|
||||||
|
dw 0
|
||||||
|
.lba:
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
|
||||||
|
times 510-($-$$) db 0
|
||||||
|
dw 0xAA55
|
|
@ -23,12 +23,17 @@ static const char *prg_name;
|
||||||
static int inodes = -1;
|
static int inodes = -1;
|
||||||
static const char *device;
|
static const char *device;
|
||||||
static int blocks = -1;
|
static int blocks = -1;
|
||||||
|
static int bootable = 0;
|
||||||
static struct stpdfs_sb super;
|
static struct stpdfs_sb super;
|
||||||
|
|
||||||
|
extern const char _binary_mkfs_boot_o_start[];
|
||||||
|
extern const char _binary_mkfs_boot_o_end[];
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_OPTION
|
#ifdef HAVE_STRUCT_OPTION
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"version", no_argument, 0, 'V'},
|
{"version", no_argument, 0, 'V'},
|
||||||
|
{"boot", no_argument, 0, 'b'},
|
||||||
{"inodes", required_argument, 0, 'i'},
|
{"inodes", required_argument, 0, 'i'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
@ -45,6 +50,7 @@ usage(int retval)
|
||||||
{
|
{
|
||||||
printf("Usage: %s [options] /dev/name [blocks]\n\n", prg_name);
|
printf("Usage: %s [options] /dev/name [blocks]\n\n", prg_name);
|
||||||
printf("Options:\n");
|
printf("Options:\n");
|
||||||
|
printf(" -b, --boot make filesystem bootable\n");
|
||||||
printf(" -i, --inode <num> number of inodes for the filesystem\n");
|
printf(" -i, --inode <num> number of inodes for the filesystem\n");
|
||||||
printf(" -h, --help display this help\n");
|
printf(" -h, --help display this help\n");
|
||||||
printf(" -V, --version display version\n\n");
|
printf(" -V, --version display version\n\n");
|
||||||
|
@ -168,6 +174,11 @@ mkfs()
|
||||||
super.state = STPDFS_CLEANLY_UNMOUNTED;
|
super.state = STPDFS_CLEANLY_UNMOUNTED;
|
||||||
stpdfs_write(fd, 1, &super, sizeof(struct stpdfs_sb));
|
stpdfs_write(fd, 1, &super, sizeof(struct stpdfs_sb));
|
||||||
|
|
||||||
|
if (bootable)
|
||||||
|
{
|
||||||
|
stpdfs_write(fd, 0, (void *)_binary_mkfs_boot_o_start, STPDFS_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
/* we finished \o/ */
|
/* we finished \o/ */
|
||||||
printf("StupidFS: %u blocks (%u Inodes)\n", super.fsize, super.isize);
|
printf("StupidFS: %u blocks (%u Inodes)\n", super.fsize, super.isize);
|
||||||
|
|
||||||
|
@ -189,9 +200,9 @@ main(int argc, char **argv)
|
||||||
#endif /* HAVE_LIBGEN_H */
|
#endif /* HAVE_LIBGEN_H */
|
||||||
|
|
||||||
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
|
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
|
||||||
while ((c = getopt_long(argc, argv, "hVi:", long_options, &idx)) != EOF)
|
while ((c = getopt_long(argc, argv, "hVbi:", long_options, &idx)) != EOF)
|
||||||
#else
|
#else
|
||||||
while ((c = getopt(argc, argv, "hVi:")) != EOF)
|
while ((c = getopt(argc, argv, "hVbi:")) != EOF)
|
||||||
#endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */
|
#endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
|
@ -202,6 +213,9 @@ main(int argc, char **argv)
|
||||||
case 'V':
|
case 'V':
|
||||||
version();
|
version();
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
bootable = 1;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
inodes = atoi(optarg);
|
inodes = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue