diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1a3ffdc06c0686f5de976fc3c0d14b9a57289fde --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +AS := as +LD := ld -m elf_x86_64 + +LDFLAG := -Ttext 0x0 -s --oformat binary + +image : linux.img + +linux.img : tools/build bootsect setup + ./tools/build bootsect setup > $@ + +tools/build : tools/build.c + gcc -o $@ $< + +bootsect : bootsect.o + $(LD) $(LDFLAG) -o $@ $< + +bootsect.o : bootsect.S + $(AS) -o $@ $< + +setup : setup.o + $(LD) $(LDFLAG) -e _start_setup -o $@ $< + +setup.o : setup.S + $(AS) -o $@ $< +clean: + rm -f *.o + rm -f bootsect + rm -f setup + rm -f tools/build + rm -f linux.img + diff --git a/bootsect.S b/bootsect.S new file mode 100644 index 0000000000000000000000000000000000000000..440aadb62920237917732dee3a57cafa2627301e --- /dev/null +++ b/bootsect.S @@ -0,0 +1,77 @@ +SETUPLEN = 4 + +BOOTSEG = 0x7c0 + +INITSEG = 0x9000 + +SETUPSEG = 0x9020 + +SYSSEG = 0x1000 + +ENDSEG = SYSSEG + SYSSIZE + +ROOT_DEV = 0x000 + +.code16 +.text + +.global _start +_start: + + jmpl $BOOTSEG, $start2 + +start2: + movw $BOOTSEG, %ax + movw %ax, %ds + movw $INITSEG, %ax + movw %ax, %es + movw $256, %cx + subw %si, %si + subw %di, %di + + rep + movsw + + jmpl $INITSEG, $go + +go: + movw %cs, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw $0xFF00, %sp + +load_setup: + movw $0x0000, %dx + movw $0x0002, %cx + movw $0x0200, %bx + movb $SETUPLEN, %al + movb $0x02, %ah + int $0x13 + jnc ok_load_setup + movw $0x0000, %dx + movw $0x0000, %ax + int $0x13 + jmp load_setup + +ok_load_setup: + + movw $msg, %ax + movw %ax, %bp + movw $0x01301, %ax + movw $0x0c, %bx + movw $21, %cx + movb $0, %dl + int $0x010 + + jmpl $SETUPSEG, $0 + +msg: +.ascii "Setup has been loaded" + +.org 508 +root_dev: + .word ROOT_DEV +boot_flag: + .word 0xaa55 + diff --git a/setup.S b/setup.S new file mode 100644 index 0000000000000000000000000000000000000000..714f42bcad7d31bdf8568cc961b685316c7df5de --- /dev/null +++ b/setup.S @@ -0,0 +1,20 @@ +.code16 +.text +.globl _start_setup + +_start_setup: + movw %cs, %ax + movw %ax, %ds + movw %ax, %es + + movw $setup_msg, %ax + movw %ax, %bp + movw $0x01301, %ax + movw $0x0c, %bx + movw $16, %cx + movb $3, %dh + movb $0, %dl + int $0x010 +setup_msg: + .ascii "setup is running" + diff --git a/tools/build.c b/tools/build.c new file mode 100644 index 0000000000000000000000000000000000000000..7803c7de469015b1cb5d85112064e25f74aa0ab6 --- /dev/null +++ b/tools/build.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define MINIX_HEADER 32 +#define GCC_HEADER 1024 + +#define SYS_SIZE 0x2000 + +#define DEFAULT_MAJOR_ROOT 3 +#define DEFAULT_MINOR_ROOT 6 + +#define SETUP_SECTS 4 + +#define STRINGIFY(x) #x + +#define ARG_LEN 3 + +void die(char * str) +{ + fprintf(stderr, "%s\n", str); + exit(1); +} + +void usage(void) +{ + die("Usage: build bootsect setup system [rootdev] [> image]"); +} + +int main(int argc, char **argv) +{ + int i, c, id; + char buf[1024]; + char major_root, minor_root; + struct stat sb; + + if ((argc != ARG_LEN) && (argc != ARG_LEN + 1)) + usage(); + + if (argc == ARG_LEN + 1) + { + if (strcmp(argv[ARG_LEN], "FLOPPY")) + { + if (stat(argv[ARG_LEN], &sb)) + { + perror(argv[ARG_LEN]); + die("Couldn't stat root device"); + } + major_root = sb.st_rdev & 0xff00; + minor_root = sb.st_rdev & 0x00ff; + } + else + { + major_root = 0; + minor_root = 0; + } + } + else + { + major_root = DEFAULT_MAJOR_ROOT; + minor_root = DEFAULT_MINOR_ROOT; + } + fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); + if ((major_root != 2) && (major_root != 3) && (major_root != 0)) + { + fprintf(stderr, "Illegal root device (major = %d)\n", major_root); + die("Bad root device --- major #"); + } + + for (i = 0; i < sizeof(buf); i++) + buf[i] = 0; + + if ((id = open(argv[1], O_RDONLY, 0)) < 0) + die("Unable to open 'boot'"); + + i = read(id, buf, sizeof(buf)); + fprintf(stderr, "Boot sector %d bytes.\n", i); + if (i != 512) + die("Boot block must be exactly 512 bytes"); + + buf[508] = (char) minor_root; + buf[509] = (char) major_root; + i = write(1, buf, 512); + if (i != 512) + die("Write call failed"); + close(id); + + if ((id = open(argv[2], O_RDONLY, 0)) < 0) + die("Unable to open 'setup'"); + + for (i = 0; (c = read(id, buf, sizeof(buf))) > 0; i += c) + if (write(1, buf, c) != c) + die("Write call failed"); + + close(id); + + if (i > SETUP_SECTS * 512) + die("Setup exceeds" STRINGIFY(SETUP_SECTS) " sectors - rewrite build/boot/setup"); + fprintf(stderr, "Setup is %d bytes.\n", i); + for (c = 0; c < sizeof(buf); c++) + buf[c] ='\0'; + while (i < SETUP_SECTS * 512) + { + c = SETUP_SECTS * 512 - i; + if (c > sizeof(buf)) + c = sizeof(buf); + + if (write(1, buf, c) != c) + die("Write call failed"); + i+=c; + } + + /* + if ((id = open(argv[3], O_RDONLY, 0)) < 0) + die("Unable to open 'system'"); + for (i = 0; (c = read(id, buf, sizeof(buf))) > 0; i += c) + if (write(1, buf, c) != c) + die("Write call failed"); + close(id); + fprintf(stderr, "System is %d bytes.\n", i); + if (i > SYS_SIZE * 16) + die("System is too big"); + */ + + return 0; +} +