summaryrefslogtreecommitdiff
path: root/bootblocks
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1997-07-20 12:16:17 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:39:55 +0200
commit9d97bc3cb3aecd3416fb7c4be3ca2f436665b696 (patch)
treeb1e5b67ef9e065efb6a4c9977ecfac8dedbad39b /bootblocks
parente63c244cb22bf48ca1d2695784a072269d19ea96 (diff)
downloaddev86-9d97bc3cb3aecd3416fb7c4be3ca2f436665b696.tar.gz
Import Dev86src-0.12.4.tar.gzv0.12.4
Diffstat (limited to 'bootblocks')
-rw-r--r--bootblocks/Makefile41
-rw-r--r--bootblocks/bzimage.c2
-rw-r--r--bootblocks/dosfs.c6
-rw-r--r--bootblocks/elf_info.c189
-rw-r--r--bootblocks/elf_info.h282
-rw-r--r--bootblocks/i86_funcs.h21
-rw-r--r--bootblocks/li86.s46
-rw-r--r--bootblocks/makeboot.c43
-rw-r--r--bootblocks/minix.c349
-rw-r--r--bootblocks/minix.h103
-rw-r--r--bootblocks/monitor.c11
-rw-r--r--bootblocks/noboot.s32
-rw-r--r--bootblocks/readfs.h17
-rw-r--r--bootblocks/standalone.c309
-rw-r--r--bootblocks/sysboot.s29
-rw-r--r--bootblocks/tarboot.s12
16 files changed, 1242 insertions, 250 deletions
diff --git a/bootblocks/Makefile b/bootblocks/Makefile
index 707179f..7569500 100644
--- a/bootblocks/Makefile
+++ b/bootblocks/Makefile
@@ -7,26 +7,34 @@ CC=$(BCC)
CFLAGS=-ansi -Ms -H0x10000 -s
ASFLAGS=-0
# LST=-l $*.lst
+# CLST=-A-l -A$*.lst
default: makeboot makeboot.com monitor.out
all: default tgz bin
CSRC=minix.c
-SSRC=tarboot.s skip.s com_bcc.s tich.s sysboot.s bootlist.s mbr.s msdos.s
+SSRC=sysboot.s \
+ tarboot.s skip.s com_bcc.s tich.s \
+ bootlist.s mbr.s msdos.s noboot.s
encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v
bin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin
MOBJ=monitor.o i86_funcs.o relocate.o help.o bzimage.o dosfs.o nofs.o
MSRC=monitor.c i86_funcs.c relocate.c help.c bzimage.c dosfs.c nofs.c
+MINC=i86_funcs.h readfs.h
+
+EXTRAS=minix.h elf_info.c elf_info.h standalone.c li86.s
install:
monitor.out: $(MOBJ)
$(CC) $(CFLAGS) $(MOBJ) -o monitor.out
-monitor: $(MSRC)
+$(MOBJ): $(MINC) version.h
+
+monitor: $(MSRC) $(MINC)
@rm -f $(MOBJ)
make 'CFLAGS=-ansi' monitor.out
mv monitor.out monitor
@@ -38,35 +46,42 @@ minix.s: minix.c
minixhd.s: minix.c
$(BCC) -Mc -DHARDDISK -S minix.c -o minixhd.s
-makeboot: makeboot.c sysboot.v skip.v msdos.v tarboot.v
+makeboot: makeboot.c sysboot.v noboot.v skip.v msdos.v tarboot.v
$(HOSTCC) $(HOSTCCFLAGS) -o makeboot makeboot.c
-makeboot.com: makeboot.c sysboot.v skip.v msdos.v tarboot.v
+makeboot.com: makeboot.c sysboot.v noboot.v skip.v msdos.v tarboot.v
$(BCC) -Md -o makeboot.com makeboot.c
+version.h:
+ head -1 ../Libc_version | \
+ sed 's/\(.*\)/#define VERSION "\1"/' > version.h
+
clean realclean:
rm -f monitor makeboot bootblocks.tar.gz
- rm -f minix.s *.com *.o *.bin *.out *.lst *.sym *.v
+ rm -f minix.s minixhd.s version.h
+ rm -f *.com *.o *.bin *.out *.lst *.sym *.v *.tmp
tgz: minix.bin monitor.out makeboot.com makeboot
tar cfV bootblocks.tar ENIAC monitor.out \
README Makefile \
- $(MSRC) makeboot.c \
- $(CSRC) $(SSRC) \
- makeboot.com minix.bin
+ $(MSRC) \
+ $(MINC) \
+ makeboot.c $(CSRC) \
+ $(SSRC) \
+ makeboot.com minix.bin \
+ $(EXTRAS)
makeboot tar bootblocks.tar
gzip -f9 bootblocks.tar
distribution:
- tar czf /tmp/bootblocks.tar.gz README Makefile \
- $(MSRC) makeboot.c \
- $(CSRC) $(SSRC)
+ tar czf /tmp/bootblocks.tar.gz \
+ README Makefile $(MSRC) $(MINC) makeboot.c $(CSRC) $(SSRC) $(EXTRAS)
.SUFFIXES: .bin .v
.s.bin:
- $(BCC) -c $*.s -A-u- -A-b -A/tmp/$*.bin -A-s -A$*.sym -A-l -A$*.lst
- -@mv /tmp/$*.bin $*.bin
+ $(BCC) -c $*.s -A-u- -A-b -A$*.tmp -A-s -A$*.sym $(CLST)
+ mv $*.tmp $*.bin
-@rm $*.o
.s.v:
diff --git a/bootblocks/bzimage.c b/bootblocks/bzimage.c
index 8d38753..2e7c835 100644
--- a/bootblocks/bzimage.c
+++ b/bootblocks/bzimage.c
@@ -227,6 +227,8 @@ static unsigned int last_address = 0;
for(i=0; i<512; i++)
__poke_es(i, buffer[i]);
}
+ else
+ printf("In EMU can't write to 0x%x\n", address);
return 0;
}
#endif
diff --git a/bootblocks/dosfs.c b/bootblocks/dosfs.c
index 9dba0af..b9a2c04 100644
--- a/bootblocks/dosfs.c
+++ b/bootblocks/dosfs.c
@@ -298,14 +298,12 @@ static int pend_s, pend_h, pend_c, pend_len = 0;
pend_h != phy_h ||
pend_c != phy_c )
{
-/*
-printf("phy_read(%d,%d,%d,%d,%d,%d);\n",
- drive, pend_c, pend_h, pend_s+1, pend_len, buf_start);
-*/
if( buf_start ) do
{
rv = phy_read(drive, pend_c, pend_h, pend_s+1, pend_len, buf_start);
tries--;
+ if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
+ drive, pend_c, pend_h, pend_s+1, pend_len, buf_start);
}
while(rv && tries > 0);
diff --git a/bootblocks/elf_info.c b/bootblocks/elf_info.c
new file mode 100644
index 0000000..86fa392
--- /dev/null
+++ b/bootblocks/elf_info.c
@@ -0,0 +1,189 @@
+
+#include <stdio.h>
+#include "elf_info.h"
+
+Elf32_Ehdr elf_head;
+Elf32_Phdr *elf_prog;
+
+#ifdef TEST
+FILE *ifd;
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ ifd = fopen(argv[1], "r");
+ if (ifd == 0)
+ exit(1);
+
+ read_elfprog();
+ write_ram("", -1L, 0);
+
+ fclose(ifd);
+}
+
+read_file(buf, offset, len)
+void *buf;
+long offset;
+int len;
+{
+ fseek(ifd, offset, 0);
+ return fread(buf, 1, len, ifd);
+}
+
+write_ram(buf, linear, len)
+char *buf;
+long linear;
+int len;
+{
+static long llen = 0;
+static long lastlin= -1;
+
+ if( llen > 0 && lastlin + llen != linear )
+ {
+ printf("for %8ld bytes\n", llen);
+ lastlin= -1;
+ }
+ if( lastlin == -1 )
+ {
+ lastlin = linear;
+ llen = 0;
+
+ if( linear != -1 )
+ printf("Write %08lx ", linear);
+ }
+ llen += len;
+ return len;
+}
+
+error(str)
+char *str;
+{
+ printf("Error: %s\n", str);
+ return -1;
+}
+#endif
+
+info_elf()
+{
+ int i;
+
+ printf("ELF-386 executable, entry = 0x%08lx\n", elf_head.e_entry);
+ printf("\t\toffset paddr vaddr filesz memsz align\n");
+ for (i = 0; i < elf_head.e_phnum; i++)
+ {
+ printf(" %d: ", i);
+ switch ((int) elf_prog[i].p_type)
+ {
+ case PT_NULL:
+ printf("PT_NULL");
+ break;
+ case PT_LOAD:
+ printf("PT_LOAD");
+ break;
+ case PT_DYNAMIC:
+ printf("PT_DYNAMIC");
+ break;
+ case PT_INTERP:
+ printf("PT_INTERP");
+ break;
+ case PT_NOTE:
+ printf("PT_NOTE");
+ break;
+ case PT_SHLIB:
+ printf("PT_SHLIB");
+ break;
+ case PT_PHDR:
+ printf("PT_PHDR");
+ break;
+ default:
+ printf("PT_(%d)", elf_prog[i].p_type);
+ break;
+ }
+ printf("\t%08lx %08lx %08lx %08lx %08lx %08lx",
+ elf_prog[i].p_offset,
+ elf_prog[i].p_paddr,
+ elf_prog[i].p_vaddr,
+ elf_prog[i].p_filesz,
+ elf_prog[i].p_memsz,
+ elf_prog[i].p_align
+ );
+ printf("\n");
+ }
+}
+
+read_elfprog()
+{
+ static unsigned char elf_ok[] =
+ {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS32, ELFDATA2LSB, EV_CURRENT};
+
+ int i;
+ char page_buf[4096];
+
+ if (read_file(&elf_head, 0L, sizeof(elf_head)) != sizeof(elf_head))
+ return error("Can't read ELF header");
+
+ if (memcmp(elf_head.e_ident, elf_ok, 7) != 0 ||
+ elf_head.e_type != ET_EXEC ||
+ elf_head.e_machine != EM_386 ||
+ elf_head.e_phnum <= 0 ||
+ elf_head.e_phentsize != sizeof(Elf32_Phdr)
+ )
+ return error("Not a 386 executable ELF program");
+
+ elf_prog = malloc(i = sizeof(Elf32_Phdr) * elf_head.e_phnum);
+ if (elf_prog == 0)
+ return error("Out of memory");
+
+ if (read_file(elf_prog, elf_head.e_phoff, i) != i)
+ return error("Can't read ELF program header");
+
+ info_elf();
+
+ for (i = 0; i < elf_head.e_phnum; i++)
+ {
+ long from, to, length, copied;
+ int chunk;
+
+ switch ((int) elf_prog[i].p_type)
+ {
+ case PT_NULL:
+ case PT_NOTE:
+ continue;
+ default:
+ return error("ELF: Unusable program segment (Must be static)");
+ case PT_LOAD:
+ break;
+ }
+ from=elf_prog[i].p_offset;
+ to=elf_prog[i].p_vaddr;
+ length=elf_prog[i].p_filesz;
+
+ for(copied=0; copied<length; )
+ {
+ if(length>copied+sizeof(page_buf)) chunk=sizeof(page_buf);
+ else chunk=length-copied;
+
+ if( (chunk=read_file(page_buf, from, chunk)) <= 0 )
+ return error("ELF Cannot read executable");
+ if( write_ram(page_buf, to, chunk) < 0 )
+ return error("Memory save failed");
+ copied+=chunk; from+=chunk; to+=chunk;
+ }
+ length=elf_prog[i].p_memsz;
+ if( length > copied )
+ {
+ write_ram("", -1L, 0);
+ memset(page_buf, '\0', sizeof(page_buf));
+ for(; copied<length; )
+ {
+ if(length>copied+sizeof(page_buf)) chunk=sizeof(page_buf);
+ else chunk=length-copied;
+
+ if( write_ram(page_buf, to, chunk) < 0 )
+ return error("Memory zap failed");
+ copied+=chunk; to+=chunk;
+ }
+ }
+ }
+}
diff --git a/bootblocks/elf_info.h b/bootblocks/elf_info.h
new file mode 100644
index 0000000..a011d97
--- /dev/null
+++ b/bootblocks/elf_info.h
@@ -0,0 +1,282 @@
+
+/* ELF layout information */
+
+/* NOTE: I'm copying the file format information here because the _format_
+ * is standard, but the Linux header files are not and may depend on
+ * headers not available when compiling Linux-86 code.
+ */
+
+#ifndef _LINUX_ELF_H
+#define _LINUX_ELF_H
+
+typedef unsigned long Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned long Elf32_Off;
+typedef long Elf32_Sword;
+typedef unsigned long Elf32_Word;
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_LOPROC 0x70000000L
+#define PT_HIPROC 0x7fffffffL
+
+/* These constants define the different elf file types */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 5
+#define ET_HIPROC 6
+
+/* These constants define the various ELF target machines */
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_486 6 /* Perhaps disused */
+#define EM_860 7
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_LOPROC 0x70000000L
+#define DT_HIPROC 0x7fffffffL
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+/* Symbolic values for the entries in the auxiliary table
+ put on the initial stack */
+#define AT_NULL 0 /* end of vector */
+#define AT_IGNORE 1 /* entry should be ignored */
+#define AT_EXECFD 2 /* file descriptor of program */
+#define AT_PHDR 3 /* program headers for program */
+#define AT_PHENT 4 /* size of program header entry */
+#define AT_PHNUM 5 /* number of program headers */
+#define AT_PAGESZ 6 /* system page size */
+#define AT_BASE 7 /* base address of interpreter */
+#define AT_FLAGS 8 /* flags */
+#define AT_ENTRY 9 /* entry point of program */
+#define AT_NOTELF 10 /* program is not ELF */
+#define AT_UID 11 /* real uid */
+#define AT_EUID 12 /* effective uid */
+#define AT_GID 13 /* real gid */
+#define AT_EGID 14 /* effective gid */
+
+
+typedef struct dynamic{
+ Elf32_Sword d_tag;
+ union{
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+extern Elf32_Dyn _DYNAMIC [];
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_NUM 11
+
+typedef struct elf32_rel {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf32_rela{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct elf32_sym{
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+
+#define EI_NIDENT 16
+
+typedef struct elfhdr{
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry; /* Entry point */
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+/* These constants define the permissions on sections in the program
+ header, p_flags. */
+#define PF_R 0x4
+#define PF_W 0x2
+#define PF_X 0x1
+
+typedef struct elf_phdr{
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+/* sh_type */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_NUM 12
+#define SHT_LOPROC 0x70000000L
+#define SHT_HIPROC 0x7fffffffL
+#define SHT_LOUSER 0x80000000L
+#define SHT_HIUSER 0xffffffffL
+
+/* sh_flags */
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000L
+
+/* special section indexes */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00L
+#define SHN_LOPROC 0xff00L
+#define SHN_HIPROC 0xff1fL
+#define SHN_ABS 0xfff1L
+#define SHN_COMMON 0xfff2L
+#define SHN_HIRESERVE 0xffffL
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+#define EI_MAG0 0 /* e_ident[] indexes */
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_PAD 7
+
+#define ELFMAG0 0x7f /* EI_MAG */
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFCLASSNONE 0 /* EI_CLASS */
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define ELFDATANONE 0 /* e_ident[EI_DATA] */
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EV_NONE 0 /* e_version, EI_VERSION */
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf_note {
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf32_Nhdr;
+
+#endif /* _LINUX_ELF_H */
diff --git a/bootblocks/i86_funcs.h b/bootblocks/i86_funcs.h
new file mode 100644
index 0000000..9eb1b05
--- /dev/null
+++ b/bootblocks/i86_funcs.h
@@ -0,0 +1,21 @@
+/*
+ * These are bios and hardware functions for the 8086 IBM PC
+ */
+
+extern int x86; /* CPU major number (0-3) */
+extern char *x86_name; /* and it's name */
+extern int x86_emu; /* Is this a PC emulator ? */
+extern int x86_a20_closed; /* Is the A20 gate closed ? */
+extern int x86_test; /* In test mode */
+extern int x86_fpu;
+
+extern unsigned boot_mem_top; /* Top of RAM below 1M */
+extern long main_mem_top; /* Top of RAM above 1M */
+
+int a20_closed();
+void open_a20();
+void bios_open_a20();
+void cpu_check();
+void mem_check();
+int ext_put();
+int ext_get();
diff --git a/bootblocks/li86.s b/bootblocks/li86.s
new file mode 100644
index 0000000..0c391ff
--- /dev/null
+++ b/bootblocks/li86.s
@@ -0,0 +1,46 @@
+!----------------------------------------------------------------------------
+!
+! This is a skeleton for creating an impure Linux-8086 executable without
+! using the linker. The .text and .data areas are correctly positioned.
+!
+! This file needs to be compiled using the 3 pass mode (-j)
+!
+!----------------------------------------------------------------------------
+.text
+org -32
+.word 0x0301 ! Magic
+.word 0x0410 ! Btype
+.long 0x20 ! header length
+.long _etext ! a_text
+.long _edata-_etext ! a_data
+.long 0 ! a_bss
+.long 0 ! a_entry
+.long STACK_SIZE ! a_total
+.long 0 ! a_syms
+.data
+.blkb _etext
+.even
+.text
+!----------------------------------------------------------------------------
+
+STACK_SIZE = 0x10000
+
+.data
+var:
+.word $1234
+
+.text
+ int $20
+ mov ax,var
+ mov bx,_edata
+ push ax
+ ret
+
+!----------------------------------------------------------------------------
+! This trailer must be at the end of the file.
+.text
+_etext:
+.data
+_edata:
+END
+
diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c
index 0f07735..4a036a6 100644
--- a/bootblocks/makeboot.c
+++ b/bootblocks/makeboot.c
@@ -4,17 +4,18 @@
#include <time.h>
#include "sysboot.v"
+#include "noboot.v"
#include "msdos.v"
#include "skip.v"
#include "tarboot.v"
char buffer[1024];
-#define FS_NONE 0
-#define FS_ADOS 1
-#define FS_DOS 2
-#define FS_TAR 3
-#define FS_STAT 4
+#define FS_NONE 0 /* Bootsector is complete */
+#define FS_ADOS 1 /* Bootsector needs 'normal' DOS FS */
+#define FS_DOS 2 /* Bootsector needs any DOS FS */
+#define FS_TAR 3 /* Bootsector needs GNU-tar volume label */
+#define FS_STAT 4 /* DOS bootsector is checked */
struct bblist {
char * name;
@@ -24,7 +25,7 @@ struct bblist {
} bblocks[] = {
{ "tar", tarboot_data, FS_TAR, "Bootable GNU tar volume lable" },
{ "dosfs", msdos_data, FS_ADOS, "Boots file BOOTFILE.SYS from dosfs" },
- { "none", sysboot_data, FS_DOS, "No OS bookblock, just message" },
+ { "none", noboot_data, FS_DOS, "No OS bookblock, just message" },
{ "skip", skip_data, FS_DOS, "Bypasses floppy boot with message" },
{ "stat", 0, FS_STAT, "Display dosfs superblock" },
{ "copy", 0, FS_STAT, "Copy boot block to makeboot.sav" },
@@ -41,6 +42,8 @@ int disk_sect = 63; /* These are initilised to the maximums */
int disk_head = 256; /* Set to the correct values when an MSDOS disk is */
int disk_trck = 256; /* successfully identified */
+int force = 0;
+
main(argc, argv)
int argc;
char ** argv;
@@ -51,6 +54,10 @@ char ** argv;
progname = argv[0];
+ if( argc == 4 && strcmp(argv[1], "-f") == 0 )
+ {
+ argv++; argc--; force++;
+ }
if( argc != 3 ) Usage();
if( (i=strlen(argv[1])) < 2 ) Usage();
@@ -355,12 +362,12 @@ not_zapped:
if( csum != osum )
{
fprintf(stderr, "TAR file checksum failed, this isn't a tar file.\n");
- exit(9);
+ if(!force) exit(9);
}
if( buff_tar.linkflag != 'V' )
{
fprintf(stderr, "Tar file doesn't start with a volume label\n");
- exit(8);
+ if(!force) exit(8);
}
strcpy(vbuf, boot_tar.name); strcat(vbuf, " Volume 1");
@@ -568,24 +575,26 @@ check_msdos()
{
disk_sect = dosflds[DOS_SPT].value;
disk_head = dosflds[DOS_HEADS].value;
- disk_trck = dosflds[DOS_MAXSECT].value/disk_head/disk_sect;
+ if( disk_sect > 0 && disk_head > 0 )
+ disk_trck = dosflds[DOS_MAXSECT].value/disk_head/disk_sect;
return;
}
- exit(2);
+ if(!force) exit(2);
}
check_simpledos()
{
- int numclust;
+ int numclust = 0xFFFF;
char * err = 0;
check_msdos();
/* Work out how many real clusters there are */
- numclust = ( dosflds[DOS_MAXSECT].value
- - dosflds[DOS_RESV].value
- - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value
- - ((dosflds[DOS_NROOT].value+15)/16)
- ) / dosflds[DOS_MAXSECT].value + 2;
+ if( dosflds[DOS_MAXSECT].value + 2 > 2 )
+ numclust = ( dosflds[DOS_MAXSECT].value
+ - dosflds[DOS_RESV].value
+ - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value
+ - ((dosflds[DOS_NROOT].value+15)/16)
+ ) / dosflds[DOS_MAXSECT].value + 2;
if( dosflds[DOS_NFAT].value > 2 )
err = "Too many fat copies on disk";
@@ -607,7 +616,7 @@ check_simpledos()
fprintf(stderr, "ERROR: %s\n\n", err);
print_super(buffer);
- exit(2);
+ if(!force) exit(2);
}
/**************************************************************************/
diff --git a/bootblocks/minix.c b/bootblocks/minix.c
index 8242707..cfcfb38 100644
--- a/bootblocks/minix.c
+++ b/bootblocks/minix.c
@@ -7,6 +7,7 @@
*/
#include <a.out.h>
+#include "minix.h"
#undef DOTS /* define to have dots printed */
#define zone_shift 0 /* for any < 32M (non-zero not supported yet) */
@@ -16,10 +17,20 @@
#define BOOTSEG (0x07c0)
#define LOADSEG (0x1000)
+#define TRY_FLOPPY
+
#ifdef HARDDISK
#define get_now()
#endif
+#ifdef zone_shift
+#if zone_shift == 0
+#define load_zone load_block
+#endif
+#else
+static short zone_shift;
+#endif
+
#asm
! BOOTSEG = 0x07c0
! LOADSEG = 0x1000 ! This must be sector aligned
@@ -57,11 +68,13 @@ org dos_sysid
mov sp,ax
#ifndef HARDDISK
+loopy:
mov ax,#$0204 ! Read 4 sectors, code + superblock.
mov bx,#start ! Where this _should_ be
mov cx,#$0001 ! From sector 1
xor dx,dx ! Of the floppy drive head zero
int $13
+ jc loopy
#else
mov cx,#$100 ! Move 256 words
@@ -88,117 +101,7 @@ org dos_sysid
#endasm
/****************************************************************************/
-/* Super block table. The root file system and every mounted file system
- * has an entry here. The entry holds information about the sizes of the bit
- * maps and inodes. The s_ninodes field gives the number of inodes available
- * for files and directories, including the root directory. Inode 0 is
- * on the disk, but not used. Thus s_ninodes = 4 means that 5 bits will be
- * used in the bit map, bit 0, which is always 1 and not used, and bits 1-4
- * for files and directories. The disk layout is:
- *
- * Item # blocks
- * boot block 1
- * super block 1
- * inode map s_imap_blocks
- * zone map s_zmap_blocks
- * inodes (s_ninodes + 1 + INODES_PER_BLOCK - 1)/INODES_PER_BLOCK
- * unused whatever is needed to fill out the current zone
- * data zones (s_nzones - s_firstdatazone) << s_log_zone_size
- *
- * A super_block slot is free if s_dev == NO_DEV.
- */
-
-#define BLOCK_SIZE 1024 /* # bytes in a disk block */
-
-/* Flag bits for i_mode in the inode. */
-#define I_TYPE 0170000 /* this field gives inode type */
-#define I_REGULAR 0100000 /* regular file, not dir or special */
-#define I_BLOCK_SPECIAL 0060000 /* block special file */
-#define I_DIRECTORY 0040000 /* file is a directory */
-#define I_CHAR_SPECIAL 0020000 /* character special file */
-#define I_SET_UID_BIT 0004000 /* set effective uid on exec */
-#define I_SET_GID_BIT 0002000 /* set effective gid on exec */
-#define ALL_MODES 0006777 /* all bits for user, group and others */
-#define RWX_MODES 0000777 /* mode bits for RWX only */
-#define R_BIT 0000004 /* Rwx protection bit */
-#define W_BIT 0000002 /* rWx protection bit */
-#define X_BIT 0000001 /* rwX protection bit */
-#define I_NOT_ALLOC 0000000 /* this inode is free */
-
-/* Type definitions */
-typedef unsigned short unshort; /* must be 16-bit unsigned */
-typedef unshort block_nr; /* block number */
-typedef unshort inode_nr; /* inode number */
-typedef unshort zone_nr; /* zone number */
-typedef unshort bit_nr; /* if inode_nr & zone_nr both unshort,
- then also unshort, else long */
-
-typedef unshort sect_nr;
-
-typedef long zone_type; /* zone size */
-typedef unshort mask_bits; /* mode bits */
-typedef unshort dev_nr; /* major | minor device number */
-typedef char links; /* number of links to an inode */
-typedef long real_time; /* real time in seconds since Jan 1, 1970 */
-typedef long file_pos; /* position in, or length of, a file */
-typedef short uid; /* user id */
-typedef char gid; /* group id */
-
-/* Tables sizes */
-#define NR_ZONE_NUMS 9 /* # zone numbers in an inode */
-#define NAME_SIZE 14 /* # bytes in a directory component */
-
-/* Miscellaneous constants */
-#define SUPER_MAGIC 0x137F /* magic number contained in super-block */
-
-#define BOOT_BLOCK (block_nr)0 /* block number of boot block */
-#define SUPER_BLOCK (block_nr)1 /* block number of super block */
-#define ROOT_INODE (inode_nr)1 /* inode number for root directory */
-
-/* Derived sizes */
-#define NR_DZONE_NUM (NR_ZONE_NUMS-2) /* # zones in inode */
-#define INODES_PER_BLOCK (BLOCK_SIZE/sizeof(d_inode)) /* # inodes/disk blk */
-#define NR_INDIRECTS (BLOCK_SIZE/sizeof(zone_nr)) /* # zones/indir blk */
-#define INTS_PER_BLOCK (BLOCK_SIZE/sizeof(int)) /* # integers/blk */
-
-struct super_block {
- inode_nr s_ninodes; /* # usable inodes on the minor device */
- zone_nr s_nzones; /* total device size, including bit maps etc */
- unshort s_imap_blocks; /* # of blocks used by inode bit map */
- unshort s_zmap_blocks; /* # of blocks used by zone bit map */
- zone_nr s_firstdatazone; /* number of first data zone */
- short s_log_zone_size; /* log2 of blocks/zone */
- file_pos s_max_size; /* maximum file size on this device */
- short s_magic; /* magic number to recognize super-blocks */
-
-} ;
-
-/* Type definitions local to the File System. */
-typedef struct { /* directory entry */
- inode_nr d_inum; /* inode number */
- char d_name[NAME_SIZE]; /* character string */
-} dir_struct;
-
-/* Declaration of the disk inode used in rw_inode(). */
-typedef struct { /* disk inode. Memory inode is in "inotab.h" */
- mask_bits i_mode; /* file type, protection, etc. */
- uid i_uid; /* user id of the file's owner */
- file_pos i_size; /* current file size in bytes */
- real_time i_modtime; /* when was file data last changed */
- gid i_gid; /* group number */
- links i_nlinks; /* how many links to this file */
- zone_nr i_zone[NR_ZONE_NUMS]; /* block nums for direct, ind, and dbl ind */
-} d_inode;
-
-/****************************************************************************/
-
-#ifdef zone_shift
-#if zone_shift == 0
-#define load_zone load_block
-#endif
-#else
-static short zone_shift;
-#endif
+/* /* */
/* The name of the file and inode to start */
extern char bootfile[];
@@ -222,8 +125,10 @@ extern unsigned ldaddr;
extern dir_struct * dirptr;
extern unsigned flength;
+#ifndef HARDDISK
/* The 'shape' of the floppy - intuit from superblock */
extern unsigned n_sectors;
+#endif
/*
* #define b_super (*(struct super_block *) 1024)
@@ -237,16 +142,19 @@ extern zone_nr b_zone[NR_INDIRECTS];
extern dir_struct directory[];
/****************************************************************************/
+/* /* */
#asm
! A few variables we need to know the positions of for patching, so export
! them and as86_encaps will make some variables.
.text
-export _inode ! Inode to search
+export inode ! Inode to search
+inode:
_inode: .word 1 ! ROOT_INODE
-export _bootfile ! File to boot, make this whatever you like,
-_bootfile: ! 'boot' is good too.
+export bootfile ! File to boot, make this whatever you like,
+bootfile: ! 'boot' is good too.
+_bootfile:
.ascii "linux"
.byte 0,0,0,0,0,0,0,0,0
@@ -266,6 +174,9 @@ code:
#endasm
+/************************************/
+/* Hard disk device driver */
+/************************************/
#ifdef HARDDISK
#asm
@@ -319,7 +230,7 @@ real_block:
!
! Load AL sectors from linear sector DX:CX into location ES:BX
-! Linear sector zero is a [bootpart]
+! Linear sector zero is at [bootpart]
! This loads one sector at a time, but that's OK cause even in the _very_
! worst case it'll take no more that 5 seconds to load a 16 bit executable.
!
@@ -384,10 +295,20 @@ onesect:
pop bx ! ES:BX for int 1302
pop es
+ mov di,#5 ! Lots of retries for a hd
+retry:
mov ax,#$0201
int $13
- jc _nogood
+ jnc got_hd_sect
+
+ xor ax,ax ! Reset between each try.
+ int $13
+ dec di
+ jnz retry
+ jmp _nogood
+
+got_hd_sect:
pop dx
pop cx
pop si
@@ -402,62 +323,9 @@ onesect:
#endasm
#else
-#asm
-_set_bpb:
-bios_tabl=dosfs_stat ! Temp space.
-bios_disk=dosfs_stat+4 !
-
-#ifndef __CALLER_SAVES__
- push si
- push di
-#endif
-
- mov di,#bios_disk
- mov bx,#0x78
-! 0:bx is parameter table address
-
- push ds
- push di
-
- mov si,[bx]
- mov ax,[bx+2]
- mov [bios_tabl],si
- mov [bios_tabl+2],ax
- push ax
-
- pop ds
-! ds:si is source
-
-! copy 12 bytes
- mov cl,#6
- cld
- rep
- movsw
-
- pop di
- pop ds
- mov ax,[_n_sectors]
- movb 4[di],al ! patch sector count
-
- mov [bx],di
- mov 2[bx],es
-
-#ifndef __CALLER_SAVES__
- pop si
- pop di
-#endif
- ret
-
-_unset_bpb:
-! 0:0x78 is parameter table address
-
- mov ax,[bios_tabl]
- mov [0x78],ax
- mov ax,[bios_tabl+2]
- mov [0x78+2],ax
- ret
-
-#endasm
+/************************************/
+/* Floppy disk device driver */
+/************************************/
static
load_block(address, blkno)
@@ -505,6 +373,8 @@ static
get_now()
{
#asm
+ mov si,#5
+retry_get:
xor dx,dx
mov cx,[_firstsect]
shr ch,#1
@@ -515,8 +385,13 @@ get_now()
test ax,ax
jz no_load
mov ah,#2
+ int $13 ! Try fetch
+ jnc no_load
+ xor ax,ax ! Bad, retry.
int $13
- jc nogood
+ dec si
+ jnz retry_get
+ jmp nogood
no_load:
xor ax,ax
mov [_loadcount],ax
@@ -548,7 +423,47 @@ zero_block(address)
#endasm
}
-#endif /* !HARDDISK */
+#ifdef TRY_FLOPPY
+#asm
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+! These are the number of sectors per track that will be scanned for.
+! For 3.5 inch floppies 36 is 2.88 Mb, 18 is 1.44Mb, 21 is 1.68Mb on
+! a 1.44Mb floppy drive. 15 and 9 are for 5.25 inch floppies.
+
+disksizes: .byte 36,21,18,15,9
+
+! It seems that there is no BIOS call to get the number of sectors. Guess
+! 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
+! 15 if sector 15 can be read. Otherwise guess 9.
+
+_probe_sectors:
+ mov si,#disksizes ! table of sizes to try
+
+probe_loop:
+ lodsb
+ cbw ! extend to word
+ mov _n_sectors, ax
+ cmp al,#9
+ je got_sectors ! if all else fails, try 9
+ xchg ax, cx ! cx = track and sector
+ xor dx, dx ! drive 0, head 0
+ mov bx,#probe_buf ! address after setup (es = cs)
+ mov ax,#0x0201 ! service 2, 1 sector
+ int 0x13
+ jc probe_loop ! try next value
+got_sectors:
+
+ ret
+#endasm
+#else
+probe_sectors()
+{
+ n_sectors = b_super.s_nzones / 80;
+ if( n_sectors < 5 ) n_sectors = b_super.s_nzones / 40;
+}
+#endif
+#endif
#ifdef DOTS
static
@@ -566,10 +481,10 @@ bios_putc(c)
}
#endif
+#if defined(HARDDISK) && !defined(SKIPBOOT)
static
nogood()
{
-#ifdef HARDDISK
#asm
mov si,#fail_fs
min_nextc:
@@ -589,7 +504,13 @@ min_eos: ! Wait for a key then reboot
fail_fs:
.asciz "Inital boot failed, press return to reboot\r\n"
#endasm
+}
+
#else
+
+static
+nogood()
+{
/* This didn't work, chain the boot sector of the HD */
#asm
push cs
@@ -603,8 +524,8 @@ hcode:
jc hcode ! Keep trying forever!
jmpi BOOTADDR,0
#endasm
-#endif
}
+#endif
/****************************************************************************/
#asm
@@ -616,6 +537,8 @@ end_of_part1:
#endasm
/****************************************************************************/
+/* Part two, code to load directories then a file into memory from the device
+ */
static
loadprog()
@@ -624,10 +547,9 @@ loadprog()
bios_putc('+');
#endif
if( b_super.s_magic != SUPER_MAGIC ) nogood();
- n_sectors = b_super.s_nzones / 80;
- if( n_sectors < 5 ) n_sectors = b_super.s_nzones / 40;
-
#ifndef HARDDISK
+ probe_sectors();
+
set_bpb();
#endif
@@ -723,20 +645,80 @@ register char * p = dirptr->d_name;
#endif
}
+#ifndef HARDDISK
+#asm
+_set_bpb:
+bios_tabl=dosfs_stat ! Temp space.
+bios_disk=dosfs_stat+4 !
+
+#ifndef __CALLER_SAVES__
+ push si
+ push di
+#endif
+
+ mov di,#bios_disk
+ mov bx,#0x78
+! 0:bx is parameter table address
+
+ push ds
+ push di
+
+ mov si,[bx]
+ mov ax,[bx+2]
+ mov [bios_tabl],si
+ mov [bios_tabl+2],ax
+ push ax
+
+ pop ds
+! ds:si is source
+
+! copy 12 bytes
+ mov cl,#6
+ cld
+ rep
+ movsw
+
+ pop di
+ pop ds
+ mov ax,[_n_sectors]
+ movb 4[di],al ! patch sector count
+
+ mov [bx],di
+ mov 2[bx],es
+
+#ifndef __CALLER_SAVES__
+ pop si
+ pop di
+#endif
+ ret
+
+_unset_bpb:
+! 0:0x78 is parameter table address
+
+ mov ax,[bios_tabl]
+ mov [0x78],ax
+ mov ax,[bios_tabl+2]
+ mov [0x78+2],ax
+ ret
+
+#endasm
+#endif
+
static
runprog()
{
-/* This did work, run the loaded executable */
+/* It all worked, run the loaded executable */
#asm
#ifdef HARDDISK
mov dx,[bootpart+2]
xchg dh,dl ! DX => hard drive
push [bootpart] ! CX => partition offset
+ xor si,si
#else
xor dx,dx ! DX=0 => floppy drive
push dx ! CX=0 => partition offset = 0
-#endif
mov si,[_n_sectors] ! Save for monitor.out
+#endif
mov bx,#LOADSEG
mov ds,bx ! DS = loadaddress
@@ -787,7 +769,9 @@ islu:
libend:
vars:
+#ifndef HARDDISK
_n_sectors: .word 0
+#endif
_next_zone: .word 0
_end_zone: .word 0
_indirect: .word 0
@@ -798,7 +782,7 @@ varend:
end_of_prog:
if *>start+0x400
- fail
+ fail! Part 2 too large!
endif
.blkb 0x3FF+start-*
@@ -807,6 +791,7 @@ end_of_prog:
_b_super: .blkb 1024
_b_inode: .blkb 1024
_b_zone: .blkb 1024
+probe_buf:
_directory: .blkb 32768
#endasm
diff --git a/bootblocks/minix.h b/bootblocks/minix.h
new file mode 100644
index 0000000..984a6bc
--- /dev/null
+++ b/bootblocks/minix.h
@@ -0,0 +1,103 @@
+/****************************************************************************/
+/* Super block table. The root file system and every mounted file system
+ * has an entry here. The entry holds information about the sizes of the bit
+ * maps and inodes. The s_ninodes field gives the number of inodes available
+ * for files and directories, including the root directory. Inode 0 is
+ * on the disk, but not used. Thus s_ninodes = 4 means that 5 bits will be
+ * used in the bit map, bit 0, which is always 1 and not used, and bits 1-4
+ * for files and directories. The disk layout is:
+ *
+ * Item # blocks
+ * boot block 1
+ * super block 1
+ * inode map s_imap_blocks
+ * zone map s_zmap_blocks
+ * inodes (s_ninodes + 1 + INODES_PER_BLOCK - 1)/INODES_PER_BLOCK
+ * unused whatever is needed to fill out the current zone
+ * data zones (s_nzones - s_firstdatazone) << s_log_zone_size
+ *
+ * A super_block slot is free if s_dev == NO_DEV.
+ */
+
+#define BLOCK_SIZE 1024 /* # bytes in a disk block */
+
+/* Flag bits for i_mode in the inode. */
+#define I_TYPE 0170000 /* this field gives inode type */
+#define I_REGULAR 0100000 /* regular file, not dir or special */
+#define I_BLOCK_SPECIAL 0060000 /* block special file */
+#define I_DIRECTORY 0040000 /* file is a directory */
+#define I_CHAR_SPECIAL 0020000 /* character special file */
+#define I_SET_UID_BIT 0004000 /* set effective uid on exec */
+#define I_SET_GID_BIT 0002000 /* set effective gid on exec */
+#define ALL_MODES 0006777 /* all bits for user, group and others */
+#define RWX_MODES 0000777 /* mode bits for RWX only */
+#define R_BIT 0000004 /* Rwx protection bit */
+#define W_BIT 0000002 /* rWx protection bit */
+#define X_BIT 0000001 /* rwX protection bit */
+#define I_NOT_ALLOC 0000000 /* this inode is free */
+
+/* Type definitions */
+typedef unsigned short unshort; /* must be 16-bit unsigned */
+typedef unshort block_nr; /* block number */
+typedef unshort inode_nr; /* inode number */
+typedef unshort zone_nr; /* zone number */
+typedef unshort bit_nr; /* if inode_nr & zone_nr both unshort,
+ then also unshort, else long */
+
+typedef unshort sect_nr;
+
+typedef long zone_type; /* zone size */
+typedef unshort mask_bits; /* mode bits */
+typedef unshort dev_nr; /* major | minor device number */
+typedef char links; /* number of links to an inode */
+typedef long real_time; /* real time in seconds since Jan 1, 1970 */
+typedef long file_pos; /* position in, or length of, a file */
+typedef short uid; /* user id */
+typedef char gid; /* group id */
+
+/* Tables sizes */
+#define NR_ZONE_NUMS 9 /* # zone numbers in an inode */
+#define NAME_SIZE 14 /* # bytes in a directory component */
+
+/* Miscellaneous constants */
+#define SUPER_MAGIC 0x137F /* magic number contained in super-block */
+
+#define BOOT_BLOCK (block_nr)0 /* block number of boot block */
+#define SUPER_BLOCK (block_nr)1 /* block number of super block */
+#define ROOT_INODE (inode_nr)1 /* inode number for root directory */
+
+/* Derived sizes */
+#define NR_DZONE_NUM (NR_ZONE_NUMS-2) /* # zones in inode */
+#define INODES_PER_BLOCK (BLOCK_SIZE/sizeof(d_inode)) /* # inodes/disk blk */
+#define NR_INDIRECTS (BLOCK_SIZE/sizeof(zone_nr)) /* # zones/indir blk */
+#define INTS_PER_BLOCK (BLOCK_SIZE/sizeof(int)) /* # integers/blk */
+
+struct super_block {
+ inode_nr s_ninodes; /* # usable inodes on the minor device */
+ zone_nr s_nzones; /* total device size, including bit maps etc */
+ unshort s_imap_blocks; /* # of blocks used by inode bit map */
+ unshort s_zmap_blocks; /* # of blocks used by zone bit map */
+ zone_nr s_firstdatazone; /* number of first data zone */
+ short s_log_zone_size; /* log2 of blocks/zone */
+ file_pos s_max_size; /* maximum file size on this device */
+ short s_magic; /* magic number to recognize super-blocks */
+
+} ;
+
+/* Type definitions local to the File System. */
+typedef struct { /* directory entry */
+ inode_nr d_inum; /* inode number */
+ char d_name[NAME_SIZE]; /* character string */
+} dir_struct;
+
+/* Declaration of the disk inode used in rw_inode(). */
+typedef struct { /* disk inode. Memory inode is in "inotab.h" */
+ mask_bits i_mode; /* file type, protection, etc. */
+ uid i_uid; /* user id of the file's owner */
+ file_pos i_size; /* current file size in bytes */
+ real_time i_modtime; /* when was file data last changed */
+ gid i_gid; /* group number */
+ links i_nlinks; /* how many links to this file */
+ zone_nr i_zone[NR_ZONE_NUMS]; /* block nums for direct, ind, and dbl ind */
+} d_inode;
+
diff --git a/bootblocks/monitor.c b/bootblocks/monitor.c
index dbf2d64..5c78aaf 100644
--- a/bootblocks/monitor.c
+++ b/bootblocks/monitor.c
@@ -1,12 +1,11 @@
-#define VERSION "0.1.1-ALPHA"
-
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <dos.h>
#include "i86_funcs.h"
#include "readfs.h"
+#include "version.h"
#ifdef __STANDALONE__
#define NOT_VT52COLOUR
@@ -60,7 +59,7 @@ static char minibuf[2] = " ";
if( x86 > 2 && !x86_emu ) /* Check some basics */
cmd_bzimage((void*)0);
else
- printf("System is not a 386+ in real mode, load aborted.\nUse 'bzimage' command toattempt load.\n");
+ printf("System is not an 80386 compatible in real mode, load aborted.\nUse 'bzimage' command to attempt load.\n");
}
for (;;)
@@ -135,7 +134,11 @@ void init_prog()
#ifdef VT52COLOUR
printf("\033E\033Rg\033Sa\033J");
#endif
- printf("Linux x86 boot monitor Version %s\n", VERSION);
+#ifdef VERSION
+ printf("Linux x86 boot monitor, Version %s.\n", VERSION);
+#else
+ printf("Linux x86 boot monitor.\n");
+#endif
cpu_check();
mem_check();
diff --git a/bootblocks/noboot.s b/bootblocks/noboot.s
new file mode 100644
index 0000000..7ab9f4e
--- /dev/null
+++ b/bootblocks/noboot.s
@@ -0,0 +1,32 @@
+
+org $7c00
+
+include sysboot.s
+
+org dos_sysid
+ .ascii "PANIC" ! System ID
+
+org codestart
+ xor ax,ax
+ mov ds,ax
+ mov ss,ax
+ mov sp,ax
+ jmpi code,#0
+
+no_os:
+ .asciz "PANIC! NO OS Found!\r\n"
+
+code: ! SI = pointer to error message
+ mov si,#no_os
+nextc:
+ lodsb
+ cmp al,#0
+ jz eos
+ mov bx,#7
+ mov ah,#$E ! Can't use $13 cause that's AT+ only!
+ int $10
+ jmp nextc
+eos: ! Wait for a key then reboot
+ xor ax,ax
+ int $16
+ jmpi $0,$FFFF ! Wam! Try or die!
diff --git a/bootblocks/readfs.h b/bootblocks/readfs.h
new file mode 100644
index 0000000..aa6b87c
--- /dev/null
+++ b/bootblocks/readfs.h
@@ -0,0 +1,17 @@
+
+/* Functions for reading from one file at a time in the root directory
+ * of a raw filesystem.
+ */
+
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+
+int open_file P((char * fname));
+int rewind_file P((void));
+int close_file P((void));
+long file_length P((void));
+int read_block P((char * buffer));
+
diff --git a/bootblocks/standalone.c b/bootblocks/standalone.c
new file mode 100644
index 0000000..57634d4
--- /dev/null
+++ b/bootblocks/standalone.c
@@ -0,0 +1,309 @@
+
+#include <errno.h>
+#asm
+entry _int_80 ! Tell ld86 we really do need this file.
+ ! then call the init stuff before main.
+
+ loc 1 ! Make sure the pointer is in the correct segment
+auto_func: ! Label for bcc -M to work.
+ .word _pre_main ! Pointer to the autorun function
+ .word no_op ! Space filler cause segs are padded to 4 bytes.
+ .text ! So the function after is also in the correct seg.
+#endasm
+
+void int_80();
+
+static void pre_main()
+{
+ /* Set the int 0x80 pointer to here */
+ __set_es(0);
+ __doke_es(0x80*4+0, int_80);
+ __doke_es(0x80*4+2, __get_cs());
+ bios_coninit();
+}
+
+void int_80()
+{
+#asm
+SYS_EXIT=1
+SYS_FORK=2
+SYS_READ=3
+SYS_WRITE=4
+SYS_OPEN=5
+SYS_CLOSE=6
+SYS_CHDIR=12
+SYS_LSEEK=19
+ENOSYS=38
+
+ push es
+ push si
+ push di
+ push dx
+ push cx
+ push bx
+ cmp ax,#SYS_READ
+ jne L1
+ call _func_read
+ jmp L0
+L1:
+ cmp ax,#SYS_WRITE
+ jne L2
+ call _func_write
+ jmp L0
+L2:
+ cmp ax,#SYS_LSEEK
+ jne L3
+ call _func_lseek
+ jmp L0
+L3:
+ cmp ax,#SYS_EXIT
+ jne L4
+ call _func_exit
+ jmp L0
+L4:
+ mov ax,#-ENOSYS
+L0:
+ pop bx
+ pop cx
+ pop dx
+ pop di
+ pop si
+ pop es
+ iret
+#endasm
+}
+
+func_lseek() { return -38; }
+
+func_write(bx,cx,dx,di,si,es)
+int bx,dx;
+char * cx;
+{
+ register int v, c;
+ if(bx == 1 || bx == 2)
+ {
+ for(v=dx; v>0; v--)
+ {
+ c= *cx++;
+ if( c == '\n') bios_putc('\r');
+ bios_putc(c);
+ }
+ return dx;
+ }
+ return -EBADF;
+}
+
+func_read(bx,cx,dx,di,si,es)
+int bx,dx;
+char * cx;
+{
+ if(bx == 0) return read_line(cx, dx);
+ return -EBADF;
+}
+
+read_line(buf, len)
+char * buf;
+int len;
+{
+ int ch;
+ int pos=0;
+
+ if( len == 1 )
+ {
+ buf[0]=((ch=bios_getc())&0xFF?ch&0xFF:((ch>>8)&0xFF|0x80));
+ return 1;
+ }
+
+ for(ch=0;;)
+ {
+ if(ch != '\003')
+ {
+ ch = bios_getc();
+ if( pos == 0 && (ch&0xFF) == 0 )
+ {
+ buf[0] = ((ch>>8)|0x80);
+ return 1;
+ }
+ ch &= 0x7F;
+ }
+ if( ch == '\r' )
+ {
+ bios_putc('\r'); bios_putc('\n');
+ buf[pos++] = '\n';
+ return pos;
+ }
+ if( ch >= ' ' && ch != 0x7F && pos < len-1)
+ bios_putc(buf[pos++] = ch);
+ else if( (ch == '\003' || ch == '\b') && pos > 0 )
+ {
+ bios_putc('\b'); bios_putc(' '); bios_putc('\b');
+ pos--;
+ }
+ else if( ch == '\003' )
+ return 0;
+ else
+ bios_putc('\007');
+ }
+}
+
+#define CTRL(x) ((x)&0x1F)
+static int last_attr = 0x07;
+static int con_mode;
+static int con_size = 0x184F;
+static int con_colour = 0;
+
+bios_coninit()
+{
+#asm
+ mov ax,#$0F00
+ int $10
+ mov _con_mode,ax
+#endasm
+ if( (con_mode &0xFF) > 39 ) con_size = (con_size&0xFF00) + (con_mode&0xFF);
+ if( (con_mode&0xFF00) != 0x700)
+ con_colour = 1;
+}
+
+bios_putc(c)
+int c;
+{
+static char tbuf[3];
+static int tcnt=0;
+ if(tcnt)
+ {
+ tbuf[tcnt++] = c;
+ if( tcnt < 3 && (tbuf[0] != CTRL(']') || tbuf[1] < '`' || tbuf[1] > 'p'))
+ return;
+ if( tbuf[0] == CTRL('P') )
+ {
+ if( tbuf[1] >= 32 && tbuf[1] <= 56
+ && tbuf[2] >= 32 && tbuf[2] <= 111 )
+ asm_cpos((tbuf[1]-32), (tbuf[2]-32));
+ }
+ else
+ {
+ if( tbuf[1] >= '`' )
+ last_attr = ( (tbuf[1]&0xF) | (last_attr&0xF0));
+ else
+ last_attr = ( (tbuf[2]&0xF) | ((tbuf[1]&0xF)<<4));
+
+ if( !con_colour )
+ last_attr = (last_attr&0x88) + ((last_attr&7)?0x07:0x70);
+ }
+ tcnt=0;
+ return;
+ }
+ if( c & 0xE0 ) { asm_colour(last_attr) ; asm_putc(c); }
+ else switch(c)
+ {
+ case CTRL('L'):
+ asm_cpos(0,0);
+ asm_cls();
+ break;
+ case CTRL('P'):
+ case CTRL(']'):
+ tbuf[tcnt++] = c;
+ break;
+ default:
+ asm_putc(c);
+ break;
+ }
+ return;
+}
+
+static asm_putc(c)
+{
+#asm
+#if !__FIRST_ARG_IN_AX__
+ mov bx,sp
+ mov ax,[bx+2]
+#endif
+ mov ah,#$0E
+ mov bx,#7
+ int $10
+#endasm
+}
+
+static asm_colour(c)
+{
+#asm
+#if __FIRST_ARG_IN_AX__
+ mov bx,ax
+#else
+ mov bx,sp
+ mov bx,[bx+2]
+#endif
+ mov ah,#$08
+ int $10
+ mov ah,#$09
+ mov cx,#1
+ int $10
+#endasm
+}
+
+static asm_cls()
+{
+#asm
+ push bp ! Bug in some old BIOS's
+ !mov ax,#$0500
+ !int $10
+ mov ax,#$0600
+ mov bh,_last_attr
+ mov cx,#$0000
+ mov dx,_con_size
+ int $10
+ pop bp
+#endasm
+}
+
+static asm_cpos(r,c)
+{
+#asm
+#if __FIRST_ARG_IN_AX__
+ mov bx,sp
+ mov dh,al
+ mov ax,[bx+2]
+ mov dl,al
+#else
+ mov bx,sp
+ mov ax,[bx+2]
+ mov dh,al
+ mov ax,[bx+4]
+ mov dl,al
+#endif
+ mov ah,#$02
+ mov bx,#7
+ int $10
+#endasm
+}
+
+bios_getc()
+{
+#asm
+ xor ax,ax
+ int $16
+#endasm
+}
+
+static void be_safe()
+{
+#asm
+ iret
+#endasm
+}
+
+func_exit(bx,cx,dx,di,si,es) /* AKA reboot! */
+{
+ __set_es(0);
+ __doke_es(0xE6*4+2,__get_cs());
+ __doke_es(0xE6*4+0,be_safe);
+#asm
+ mov ax,#$FFFF
+ int $E6 ! Try to exit DOSEMU
+ mov ax,#$0040 ! If we get here we're not in dosemu.
+ mov es,ax
+ seg es
+ mov [$72],#$1234 ! Warm reboot.
+ jmpi $0000,$FFFF
+#endasm
+}
diff --git a/bootblocks/sysboot.s b/bootblocks/sysboot.s
index 3bc7c57..ee62e69 100644
--- a/bootblocks/sysboot.s
+++ b/bootblocks/sysboot.s
@@ -46,36 +46,11 @@ dos4_label: .blkb 11 ! Disk Label (DOS 4+)
dos4_fattype: .blkb 8 ! FAT type
!
-! This is where the code will be overlaid, the default is an 'oops'
+! This is where the code will be overlaid, the default is a hang
.blkb sysboot_start+0x3E-*
public codestart
codestart:
- xor ax,ax
- mov ds,ax
- mov es,ax
- mov ss,ax
- mov sp,ax
- jmpi sys_code+$7C00-sysboot_start,#0
-
-sys_code: ! SI now has pointer to error message
- mov si,#sys_no_os+$7C00-sysboot_start
-sys_nextc:
- lodsb
- cmp al,#0
- jz sys_eos
- mov bx,#7
- mov ah,#$E ! Can't use $13 cause that's AT+ only!
- int $10
- jmp sys_nextc
-sys_eos: ! Wait for a key then reboot
- xor ax,ax
- int $16
- !int $19 ! This should be OK as we haven't touched anything.
- jmpi $0,$FFFF ! Wam! Try or die!
-
-sys_no_os:
- .asciz "PANIC! NO OS Found!\r\n"
-
+ j codestart
! Partition table
public partition_1
diff --git a/bootblocks/tarboot.s b/bootblocks/tarboot.s
index 0fb85d3..be68ecd 100644
--- a/bootblocks/tarboot.s
+++ b/bootblocks/tarboot.s
@@ -137,7 +137,11 @@ blk_uid: .blkb 8
blk_gid: .blkb 8
blk_size: .blkb 12
blk_mtime: .asciz "6141567743 "
-blk_chksum: .asciz " 131141"
+if DEBUG
+blk_chksum: .asciz " 142273"
+else
+blk_chksum: .asciz " 127270"
+endif
blk_link: .byte 'V
! Sneaks here, overlay zero init vars on tar data.
@@ -476,14 +480,16 @@ endif
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-if DEBUG = 0
- locn(510)
! This isn't a hard disk boot sector so don't give it an HD magic
+! locn(510)
! .word 0xAA55
+if DEBUG = 0
+locn(510)
.word 0
endif
! From here down is where we load stuff.
+locn(512)
blk_load: ! Address of block load
tar_name: .blkb 100