ncoverby@ndsuvax.UUCP (Glen Overby) (06/16/89)
Since I first posted my new bootstrapper, I've added support to boot directly off of a hard disk. Replace the files in my origional posting (Article-IDs: {265[789],2660}@ndsuvax.UUCP) with these and install as before. It sure is nice to be able to boot up without touching floppies! It's a lot faster! Glen Overby <ncoverby@plains.nodak.edu> uunet!ndsuvax!ncoverby (UUCP) ncoverby@ndsuvax (Bitnet) #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # b1/bootblok.asm4 # b1/fdboot.uu # b1/hdboot.uu # b1/mfdisk.asm # b2b/Makefile # b2b/bsu.s # MANIFEST # This archive created: Thu Jun 15 22:54:32 1989 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(11877 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^X//' << \SHAR_EOF > 'README' X A New Bootstrapper for Minix X Version 2 X X Glen Overby X North Dakota State University X Fargo, North Dakota X X X X June 15, 1989 X X X XThe objective of this project is to improve the verasility of the XMinix boot-up process by reading the major pieces of the system Xfrom files on a filesystem, rather than from an image diskette. X XIn doing this, I have completely rewritten the Minix bootstrap Xprocess. I now have a two-stage process to load the system and a Xspecial hard disk loader program. X Xthe first stage resides in the boot block of a Minix filesystem Xand is loaded by the PC's ROM or the hard disks's loader. When Xstage 1 takes over, it reads the root directory of /dev/fd0 look- Xing for a stripped file (no "a.out" header) named "boot" to load. XAfter control is passed to stage 2, it loads four "a.out" files Xcontaining the Kernel, Memory Manager, File System and Init, Xbuilding a normal process stacks with process arguments for each. X XThe new hard disk loader, written by Motti Bazar, asks the user Xwhich partition to boot from, and loads that partition's boot Xblock to 0:7C00H. It then executes it, passing a pointer to the Xboot partition's disk table entry (somewhere in the relocated Xhard disk boot loader located at 0:600H) and the cylinder offset Xof the partition. The need for these two parameters is the only Xreason I changed from the standard DOS boot block to Motti's. XAfter using itI have found it nice to be able to boot off of any Xpartition I want. X XThe first stage is written entirely in assembler by an associate Xof mine, Dan Thureen. Dan used the MicroSoft Macro Assembler X(version 4.0 works OK; I've had trouble with 5.0 complaining Xabout not having a stack segment and such). Microsoft's assem- Xbler was used because we did not know all of the syntax of XMinix's asld, and there were a few required addressing modes X(such as jump indirect) that we did not know how to code. X XI have heavily modified Dan's origional loader to support the Xhard drive, and to fit better with my second stage loader. X XStage 2 is written primarily in C, with some assembler support Xroutines. It loads "a.out" format files from Minix format Xfilesystems on any disk or partition; it knows about partitioned Xhard disks as well as floppy diskettes. After all processes are Xloaded, stacks are built for each of the processes. The kernel's Xstack contains "struct proc" entries for kernel memory, MM, FS Xand Init. These are used by the proc table initialization rou- Xtines as a replacement for the sizes[] array. X XFile loader.c contains the code that does all of the filesystem Xreading. Routines with double sides are the only ones intended Xfor use outside this module. X X X ================= X || Open_File || X ================= X _______/ | \_______ X / | \ X --------------- | -------------- X | Follow_Path | | | Device_Map | X --------------- | -------------- X _______/ / \ | X / / \ | X------------- / -------------- | X| Next_Name | / | Search_Dir | | X------------- / -------------- | X / / | X / / | X / =============== | =============== X | || Read_File || | || Load_File || X | =============== \ =============== X | | \_________ \ / | X | | | \ / | X-------------- ----------------- | ____ \ _____/ ----------------- X| Read_Inode | | L_Load_Blocks | | | \ | F_Load_Blocks | X-------------- ----------------- | | \ ----------------- X \ \ | | _______ \ _________/ | X \ \ | | | \ | X \ \ | | | -------------- ------------- X \ \ | | | | Read_Super | | Phys_Copy | X \ \ | | | -------------- ------------- X \_____________ \ | | | _____/ \ X \ \ | | | / \ X -------------- ------------- X | Block_Read | | Read_Part | X -------------- ------------- X | ________________/ X | / X ----------------- X | LL_Block_Read | X ----------------- X | X ---------- X | diskio | X ---------- X X XThe filenames used by the loader have been extended to allow Xspecification of what device to load the file from, in the for- Xmat: X device[.partition]:path X XThe devices that loader knows about are: X fd0, fd1, fd2, fd3 floppy diskettes X hd0.1, hd0.2, hd0.3, hd0.4 hard disk 0 parititons 1-4 X hd1.1, hd1.2, hd1.3, hd1.4 hard disk 1 parititons 1-4 X X XCHANGES TO MINIX X XI attempted to keep the number of changes to the Minix internals Xto a minimum. I think I have succeeded fairly well with this. X XThe Kernel start-up in mpx88 was changed to expect arguments on Xthe stack for main. This is passed along in the same manner as Xfor a normal process. The kernel's "proc" table initialization Xsection copies from the arguments rather than calculating it from Xthe "sizes" array, which no longer exists. The first element X(argv[0]) contains information about the kernel; the next three Xelements (argv[1,2,3]) are for MM, FS and Init, respectively. XWith the removal of the sizes array, changes to the interrupt Xvector initialization and memory driver initialization (for X/dev/kmem) were requred. Set_Vec was changed to use the physical Xdata segment of the "Hardware" process rather than calculating it Xfrom "base_click+sizes[0]". The memory driver was similarily Xmodified, but using the virtual address of the stack segment for Xthe size of the kmem driver. X XThe Memory Manager no longer waits for the file system to tell it Xthe top of the ram disk; instead, it uses a call added to the XSYSTEM process, GET_MAP, to get a process' segment maps. The X"BRK2" call has now been changed to allocate any size out of the Xglobal memory pool, rather than within a process' 64K data seg- Xment. This call is used by the file system to allocate the ram Xdisk's memory. X XThe File System uses it's parameters to determine which device to Xmount as the root filesystem, and if it is necessary to pre-load Xthat device from another device (i.e. if it's a ram disk). This Xchange wasn't necessary to to the bootstrap process, but it was Xat the top of my list of change I wanted to make and I did it Xwhile giving the bootstrapper some time to "break in". X XCHANGES IN THE SECOND VERSION X XMy first version would not load from the hard drive; this second Xversion has changed that. X XThe loader now offsets all requests with the cylinder starting Xsector (passed from Motti's hard disk loader), and the drive Xparameters for are configured from BIOS call 13h. There is one X"hack" to calculate the drive number when using a partitioned Xhard drive; the partition is calculated by subtracting an abso- Xlute address from the partition table entry passed from the main Xhard disk loader. There is now a define to determine which type Xof device (floppy or hard disk) is being booted from. X XThe second stage program now saves the default boot device passed Xfrom the bootblock. I also fixed a bug in the hard disk parame- Xter settings; I had hard-coded the number of heads on my drive. XThat is now obtained from the BIOS. X XFUTURE ENHACNEMENTS X XThe block-read makes two ROM calls to read each sector of the Xblock. This should be changed to one call, with logic for the Xerrors returned when a track or cylinder is crossed. X XMemory size should be acquired from the ROM and passed on the XMemory Manager's stack rather than using the current memory size Xcalculation which twiddles with the segment registers and pokes Xthru all existing memory to find out how much there is there. X XAll RAM disk types should be separate minor devices in the Memory Xdriver. This would theoretically allow three RAM disks: PC X(under 640K), AT (Extended memory) and EMS. Currently, it is ei- Xther PC or AT type RAM disk, determined by the size of the RAM Xdisk. X XConfiguration of some device driver parameters (such as keyboard Xtype, primary printer port, video adapter type, and CPU type) Xcould be done in the second stage and passed in on the Kernel's Xstack. X XMore server processes could be configured into the system. This Xwould require the constant "LOW_USER" to become a variable passed Xto the kernel. X XA Hard-Disk stage 1 bootstrapper needs to be written so Minix can Xboot fully off the hard drive. One that might work, called X"BOOTCODE.ASM" by W.D. Caglewas posted in Oct. 87. X XINSTALLING THE CHANGES X XMy changes add two directories to the Minix hierarchy, "b1" and X"b2b". The directory "b2b" was origionally named "b2", but what XI'm sending out is the third major revision and I put each in Xseparate directories. Directory "b1" contains the first stage of Xthe bootsrapper in source and binary. If you wish to reassemble Xthe sources, write bootblok.asm to a dos disk and reassemble it Xfrom dos. Follow the instructions at the beginning of the code Xfor writing it directly to a Minix filesystem disk's boot block; Xotherwise, run uudecode on the ".uu" file in the "b1" directory, Xand use X dd if=bootblok of=/dev/fd0 Xto write it to the boot block of a Minix filesystem. X XCompiling the second stage, in "b2b" simply requires a "make" in Xthat directory. Before compiling you may want to change the dev- Xice and file names of the system files in main.c. It would real- Xly be nice to have a configuration file to tell what files to Xload for each piece of the system, but I haven't written that Xyet. X XNext, patch all the diffs into your Kernel, FS, MM, header and Xlibrary files, and copy in the new mpx88.s file. All diffs are Xcontext diffs and require "patch" to install them. If you are Xpatching into a full set of Minix sources, you will not be able Xto use the makefiles. The way I do most of my development is Xwith a parallel copy of the sources, only copying necessary Xfiles. My work source directory is /usr/src/minix, and the Xparallel directory is /usr/src/minix/newboot. If you do not use Xthe makefiles, you will need to merge some changes I have made to Xthem into the generic Minix ones; first, I use "crtso.s" rather Xthan "head.s" for FS, MM and Init. This allows me to link with X"cc" rather than "asld". I have added the changed library file X"syslib.s" to the end of my link commands so that I don't have to Xrebuild my entire library with the changed file. This was simply Xeasier for testing. Lastly, I "chmem" all executables down to X2000 bytes of stack space. X X X X X X X X X X X X X X X X X X X X X X X SHAR_EOF if test 11877 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 11877 characters)' fi fi # end of overwriting check echo shar: extracting "'b1/bootblok.asm4'" '(17454 characters)' if test -f 'b1/bootblok.asm4' then echo shar: will not over-write existing file "'b1/bootblok.asm4'" else sed 's/^X//' << \SHAR_EOF > 'b1/bootblok.asm4' X page ,132 X;----------------------------------------------------------------------------- X; X; MINIX primary bootstrap loader X; X; Dan Thureen X; Glen Overby X; North Dakota State University X; <ncoverby@plains.nodak.edu> X; {uunet,umn-cs}!ndsuvax!ncoverby, X; ncoverby@ndsuvax (bitnet) X; X; 1) ROM monitor loads bootstrap sector from floppy (512 bytes) X; to address 0000:7C00 and executes starting at 7C00. X; X; 2) Bootstrap program loads second sector of boot block right X; after the already-loaded first sector, completing the program X; binary. X; X; 3) Loader reads superblock, loads root directory (inode #1) X; into memory and searches for file named "boot". X; X; 4) The file "boot" is loaded into memory at address 3200:0000 X; and executed. X; X; X; The file boot is an executable image, WITHOUT an a.out header. X; X; A small library of character and string I/O routines is provided X; for future expansion. Also some small debugging routines for X; doing memory dumps, etc. X; X; Note: All of the code below will not fit into the 1K block X; allocated by the MINIX file system for the boot block. The X; optional sections are placed at the very end and the executable X; image truncated to the 1K size limit. An expanded ( 1K+ ) X; version can be run on a ZENITH clone by the following steps: X; X; Load it into memory with the DOS DEBUG program X; Move it to 3000:7C00 X; Trap to the ROM monitor <ctrl><alt><return> X; Use the monitor routines to execute, single-step, etc. X; X; Because the .EXE file starting address is not CS:0100 the EXE2BIN X; utility cannot be used to convert to a straight binary image. This X; can, however, be done with DEBUG. X; X; DEBUG BOOTBLOK.EXE - loads at CS:7C00 X; -WCS:7C00 0 0 2 - writes 2 sectors to block 0,1 of drive A. X; MINIX file system disk must be in drive A X; for this step X; X; If a DOS file image is desired use DEBUG again: X; X; DEBUG BOOTBLOK.EXE - loads at CS:7C00, sets BX:CS to file size X; -NBOOTBLOK - select name for image file X; -RBX X; BX xxxx X; :0000 - set image file size to 1024 bytes (400h) X; -RCX X; CX xxxx X; :0400 X; -WCS:7C00 - write 1024 bytes to file from CS:7C00 X; X; This can be transferred to MINIX using dosread and patched in with dd. X; X; Changes: X; X; 01/10/88 DT Initial Release, for NDSU CS548 X; This release loaded a Minix image (built with "build") X; from the "/boot" file. X; 03/01/88 GPO Start adding an inteligent second stage. X; Leave 1st stage at 0:7C00 and load second stage to 3200:0 X; 04/29/88 GPO Reduce the ammount of chatter X; 06/05/89 GPO Support hard disk bootstrapper. X; Requires the multi-partition hard disk boot loader X; by Motti Bazar. X; Added the "HARD_DISK" variable. Rerequires separate X; compilation for hard disk and floppy versions. X; Drive number is passed to stage 2 in BX X; if DEBUG is not defined, don't even assemble unneded code. X;----------------------------------------------------------------------------- X X_text segment para public 'code' X assume cs:_text, ds:_text ; Tiny data model with CS=DS=SS X XDEBUG EQU 0 ; Set non-0 if debug code to be X ; included X XHARD_DISK EQU 01 ; Set non-zero if this will be in X ; the boot sector of a hard disk X XS_IMAP_BLOCKS_OFF equ 4 XS_ZMAP_BLOCKS_OFF equ 6 XNR_DZONE_NUM equ 7 XI_ZONE_OFF equ 14 XI_SIZE_OFF equ 4 XIND_ZONE_OFF equ 28 XBOOT_2_SEG equ 3200h ; Where the second stage boot program XBOOT_2_OFF equ 0000h ; is loaded to XBOOT_OFF equ 7c00h ; starting point of Boot1 X XBOOT_2 segment at BOOT_2_SEG ; Define starting segment address X ; for second stage boot program. X org BOOT_2_OFF ; Entry point at offset 0000. Xstage2 label byte XBOOT_2 ends X X org BOOT_OFF Xstart1: X mov ax, cs ; set up segment registers X mov ds, ax ; tiny memory model CS=DS=SS X mov ss, ax X mov sp, offset estack ; CS=AX=HIGH_BOOT_SEG? X Xif HARD_DISK X ; the hard disk boot loader will pass the starting cylinder of the X ; partition in BS, and the partition entry at (now destroyed) DS:SI. X mov startcyl, bx ; save starting cylinder X mov partoff, si ; save ptr to partition table X ; Calculate tracksiz and cylsize from ROM parameters X mov ah, 8 ; Return current drive parameters X mov dl, drive ; hard-disk X int 013h X and cl, 03Fh ; discard cylinder number high bits X xor ch, ch ; CX - Number of sectors per track X mov tracksize, cx X mov al, dh ; cylsize = heads * tracksize X inc al X xor ah, ah X mul cl X mov cylsize, ax Xendif X X call reset ; reset drive X X mov lsn, 1 ; read the boot block's second sector X mov bx, ds ; from disk (partition) sector 1. X mov es, bx ; (the ROM or Hard Disk primary boot X mov bx, 7e00h ; only loads the first sector X call read_sector Xdie: jc die ; if there's a read error now, hang. X ; message printing isn't loaded! X Xif DEBUG X mov ax, offset block_buf ; hex dump of boot block X push ax X call _print_block X pop ax X call getchar ; wait for key pressed Xendif X Xif DEBUG X call _newline ; print tracksize, cylsize and X mov ax, tracksize ; starting cylinder X call put4x X mov al, ' ' X call putchar X mov ax, cylsize X call put4x X mov al, ' ' X call putchar X mov ax, startcyl X call put4x X call _newline Xendif X X mov inode_no, 1 ; load root directory (inode=1) X mov fseg, ds X mov foff, offset dir_buf X call load_file X Xif DEBUG X call _newline X mov ax, n_blocks ; show file size X call put4x X call _newline Xendif X X mov ax, n_blocks ; loop to search for file "boot" X mov cl, 10 X shl ax, cl ; ax = # of bytes in directory X mov bx, 0 Xsearch_loop: X cmp bx, ax ; bx = byte offset within directory X jge no_match X cmp word ptr dir_buf[bx], 0 ; ignore files with inode# 0 X je next_name X lea si, dir_buf+2[bx] ; compare filename with boot_file_name X lea di, boot_file_name X call strcmp X je found_file Xnext_name: X add bx, 16 ; next directory entry X jmp search_loop Xno_match: X mov bx, offset not_found_err ; file not found X jmp terminate Xfound_file: X mov ax, word ptr dir_buf[bx] ; get inode # X mov inode_no, ax X X mov fseg, BOOT_2_SEG ; load file to BOOT_2_SEG X mov foff, 0 X; mov fseg, ds ; test load into data segment X; mov foff, offset fil_buf X X call load_file X Xif DEBUG X mov bx, offset file_loaded X call puts X mov ax, n_blocks X call put4x X call _newline X call getchar Xendif X Xget_equals: X mov bx, offset ram_load X call puts Xif DEBUG X call getchar ; pause for contemplation... X cmp al, '=' X jne get_equals Xendif X Xif HARD_DISK X mov ax, partoff ; Drive = Partition + 41h X sub ax, 7beh ; !!!! Warning: Loader dependent address !!!! X mov cl, 16 X div cl X xor ah, ah X add ax, 41h X mov dx, ax Xelse X mov dl, drive ; send drive in DX X xor dh, dh Xendif X jmp far ptr stage2 X Xreset: xor ah, ah X mov dl, drive X int 13h X ret X Xread_block: ; lbn = logical block # X ; bseg_no = segment# X ; boff_no = offset X mov ax, lbn Xif DEBUG X call put4x X call _newline Xendif X mov ax, lbn X add ax, ax ; sector # = 2 * block # X mov lsn, ax X X mov bx, ds ; es:bx = block load address X mov es, bx ; use double buffering to avoid X mov bx, offset block_buf ; DMA across 64K boundary problems X X call read_sector X jc done_read_block ; read error X inc lsn X X mov bx, offset block_buf + 512 ; load 2nd sector of block X call read_sector X jc done_read_block ; read error X Xmovit: lea si, block_buf ; move block form buffer X mov di, bseg_no ; to desired address (bseg_no:boff_no) X mov es, di X mov di, boff_no X mov cx, 512 X cld X rep movsw X Xdone_read_block: X ret X Xread_sector: ; lsn = logical sector # X ; ES = segment# X ; BX = offset X mov retry, 10 Xread_again: X dec retry ; retry 9 more times on error X js done_read_sector ; abort X X mov ax, lsn X X xor dx, dx ; dx:ax / cylinder size X div cylsize X add ax, startcyl ; add HD partition start cylinder X mov cl, ah ; high bits of cl get bits 8,9 of X ror cl, 1 ; cylinder # X ror cl, 1 X mov ch, al ; low byte of cylinder # X mov ax, dx X xor dx, dx X div tracksize X mov dh, al ; dh = head # X or cl, dl ; or in sector # bits X inc cl ; start sector # at 1 rather than 0 X mov dl, drive ; drive # X mov ax, 0201h ; read 1 sector X int 13h X X jc read_again ; try again on error Xdone_read_sector: X ret X Xget_inode: ; input: inode_no X ; returns pointer to corresponding X ; inode in inode_p X X mov lbn, 1 ; fetch super_block X mov bseg_no, ds X mov boff_no, offset super_buf X call read_block X jnc okay_super Xif DEBUG X call read_error Xendif X mov bx, offset super_err X jmp terminate X Xokay_super: X Xif DEBUG X mov ax, offset super_buf X push ax X call _print_block X pop ax X call getchar Xendif X X mov ax, inode_no X dec ax X xor dx, dx X div inodes_per_block X mov i_offset, dx X add ax, super_buf + S_IMAP_BLOCKS_OFF X add ax, super_buf + S_ZMAP_BLOCKS_OFF X add ax, 2 X mov i_block, ax X mov lbn, ax X mov bseg_no, ds X mov boff_no, offset inode_buf X call read_block X jnc okay_inode X Xif DEBUG X call read_error Xendif X mov bx, offset inode_err X jmp terminate X Xokay_inode: X Xif DEBUG X mov ax, offset inode_buf X push ax X call _print_block X pop ax X call getchar Xendif X X mov bx, i_offset X mov cx, 5 X shl bx, cl X add bx, offset inode_buf X mov inode_p, bx X ret X X; The following variables must be located in the first 512 bytes X; because they are used in the primary stage running at 0000:7C00 and the X; BIOS ROM only loads 1 sector Xcylsize dw 12h ; defaults for 48 TPI floppy Xtracksize dw 09h Xif HARD_DISK X drive db 080h Xelse X drive db 0 Xendif Xstartcyl dw 0 Xpartoff dw 0 Xblock_size dw 1024 Xinodes_per_block dw 32 X X;----------------------------------------------------------------------------- X; The boot signature X; identifies this partition as containing a valid boot program X; X; This marks the end of the first sector of the stage 0 bootstrapper. X; Beware that the basic necessities of the bootstrapper must fit in X; the first sector! The rest of the bootstrapper must fit in the X; second sector of the boot block. X;----------------------------------------------------------------------------- X X org 07dfeh X dw 0AA55h X X;----------------------------------------------------------------------------- X Xload_file: ; load file at fseg:foff given inode_no X ; returns file size in n_blocks X call get_inode X mov bx, inode_p X mov ax, I_SIZE_OFF[bx] X mov dx, I_SIZE_OFF+2[bx] X div block_size X mov n_blocks, ax ; calculate # of blocks to load X test dx, dx X jz no_spill X inc n_blocks ; partial block Xno_spill: X cmp n_blocks, NR_DZONE_NUM ; are there indirect blocks? X jle no_indirect X mov ax, IND_ZONE_OFF[bx] ; if so, read indirect block first X mov lbn, ax X mov bseg_no, ds X mov boff_no, offset ind_buf X call read_block X jnc no_indirect X Xif DEBUG X call read_error Xendif X mov bx, offset ind_err X jmp terminate X Xno_indirect: ; set up loop to read all blocks in file X mov ax, fseg X mov bseg_no, ax X mov ax, foff X mov boff_no, ax X mov load_i, 0 Xload_loop: X mov bx, load_i ; for load_i := 0 to n_blocks-1 do X cmp bx, n_blocks X jge done_load X add bx, bx ; calculate block# X cmp bx, NR_DZONE_NUM*2 X jge indirect_block X add bx, inode_p X mov ax, I_ZONE_OFF[bx] X jmp cont_load Xindirect_block: X mov ax, ind_buf-14[bx] Xcont_load: ; read the block X mov lbn, ax X call read_block X jnc next_block X Xif DEBUG X call read_error Xendif X mov bx, offset file_err X jmp terminate X Xnext_block: X Xif DEBUG X mov ax, bseg_no ; print segment:offset loaded to X call put4x X mov al, ':' X call putchar X mov ax, 0 X call put4x X call _newline Xendif X add bseg_no, 40h ; increment seg for next block X inc load_i X jmp load_loop Xdone_load: X ret X Xstrcmp: ; string compare X push ds X pop es ; addresses in SI & DI X cld X mov cx, 0Eh X repe cmpsb X ret ; returns with flags set based X ; upon compare result X Xram_load db 13, 10, 'Second boot stage loaded. ' Xif DEBUG X db 'Type "=" to start MINIX -> ', 0 Xelse X db 'Starting ...', 13, 10, 0 Xendif X;boot_err db 'Error reading Boot block', 13, 10, 0 Xsuper_err db 'Error reading Super_block', 13, 10, 0 Xinode_err db 'Error reading Inode', 13, 10, 0 Xind_err db 'Error reading Indirect Block', 13, 10, 0 Xfile_err db 'Error reading file', 13, 10, 0 Xnot_found_err db 'Boot file not found', 13, 10, 0 Xif DEBUG Xfile_loaded db 'File loaded - blocks = ', 0 Xendif Xboot_file_name db 'boot', 12 dup (0) X X;----------------------------------------------------------------------------- X; I/O Routines. Many can be eliminated if the program grows too large X; to fit in 1K. X;----------------------------------------------------------------------------- X Xterminate: X call puts Xexit: jmp exit ; hang in harmless loop on error X Xputchar: ; char in AL, return code in AX X mov ah, 0Eh X xor bl, bl X int 10h X ret X Xputs: ; print string, address in BX X mov al, byte ptr [bx] X test al, al X je doneputs X push bx X call putchar X pop bx X inc bx X jmp puts Xdoneputs: X ret X X X;----------------------------------------------------------------------------- X; X; All routines which follow are optional, mostly character I/O X; procedures for debugging purposes, which can be stripped out X; if necessary. Total code and initialized data must come first X; and must fit into 1K. X; X;----------------------------------------------------------------------------- X Xif DEBUG X_newline: X mov al, 13 X call putchar X mov al, 10 X call putchar X ret X Xgetchar: ; char returned in AL X xor ah, ah X int 16h X cmp al, 03h X je exit X push ax X push bx X call putchar X pop bx X pop ax X ret X Xgets: ; read string into buffer X call getchar ; address in bx X cmp al, 0Dh X je done_gets X mov byte ptr [bx], al X inc bx X jmp gets Xdone_gets: X mov byte ptr [bx], 0 X ret Xendif ;! Xput2x: ; print hex byte in AL X push ax X shr ax, 1 X shr ax, 1 X shr ax, 1 X shr ax, 1 X call put_byte X pop ax Xput_byte: X and al, 0Fh X add al, 30h X cmp al, 39h X jle nothex X add al, 07h Xnothex: call putchar X ret X Xput4x: ; print hex word in AX X push ax X xchg al, ah X call put2x X pop ax X call put2x X ret Xif DEBUG ;! Xread_error: X push ax X push bx X push es X push cx X push dx X push cx X push dx X call _newline X X pop ax ; print drive# X call put2x X mov al, ' ' X call putchar X X pop ax ; print cylinder# X xchg ah, al X call put2x X mov al, ' ' X call putchar X X pop ax ; print head# X xchg ah, al X call put2x X mov al, ' ' X call putchar X X pop ax ; print sector# X call put2x X mov al, ' ' X call putchar X X pop ax ; print segment X call put4x X mov al, ':' X call putchar X X pop ax ; print offset X call put4x X call _newline X X pop ax X mov al, ah X call put2x X mov al, ' ' X call putchar X ret X X X_print_block proc near X push bp X mov bp,sp X push word ptr [bp+4] X call near ptr _print_sector X pop cx X mov ax,word ptr [bp+4] X add ax,512 X push ax X call near ptr _print_sector X pop cx X@1: X pop bp X ret X_print_block endp X X X_print_sector proc near X push si X push di X push bp X mov bp,sp X dec sp X dec sp X xor si,si X call near ptr _newline X xor di,di X jmp short @6 X@5: X mov ax, si X call put4x X mov bx, offset _s@ X mov word ptr [bp-2],0 X jmp short @10 X@9: X mov ax,si X inc si X mov bx,ax X add bx,word ptr [bp+8] X mov al,byte ptr [bx] X call put2x X mov al,' ' X call putchar X@8: X inc word ptr [bp-2] X@10: X cmp word ptr [bp-2],16 X jb @9 X@7: X mov ax,16 X push ax X mov ax,word ptr [bp+8] X add ax,si X add ax,-16 X push ax X call near ptr _prints X pop cx X pop cx X@4: X inc di X@6: X cmp di,32 X jb @5 X@3: X call near ptr _newline X@2: X mov sp,bp X pop bp X pop di X pop si X ret X_print_sector endp X X X_prints proc near X push si X push di X push bp X mov bp,sp X mov si,word ptr [bp+8] X mov bx,offset _s@+3 X call puts X xor di,di X jmp short @15 X@14: X cmp byte ptr [si],32 X jl @16 X cmp byte ptr [si],126 X jg @16 X mov al,byte ptr [si] X call putchar X jmp short @17 X@16: X mov al, '.' X call putchar X@17: X@13: X inc di X inc si X@15: X cmp di,word ptr [bp+10] X jl @14 X@12: X call near ptr _newline X@11: X pop bp X pop di X pop si X ret X_prints endp X X_s@ label byte X db 32 X db 32 X db 0 X db 32 X db 32 X db 32 X db 32 X db 0 X Xendif X X;----------------------------------------------------------------------------- X; X; Most of the following declarations are necessary but are all X; uninitialized data areas so they can go anywhere after the X; necessary code. Declarations which are followed by * are for X; debug purposes only. X; X;----------------------------------------------------------------------------- X X Xretry db ? ; dist read retry counter Xlbn dw ? ; logical block # Xbseg_no dw ? ; block load segment # Xboff_no dw ? ; block load offset # Xlsn dw ? ; logical sector # X Xi_block dw ? ; inode block # Xi_offset dw ? ; inode block offset Xinode_no dw ? ; inode number Xinode_p dw ? ; pointer to inode structure X Xload_i dw ? ; loop counter for file load Xfseg dw ? ; segment for file load Xfoff dw ? ; offset for file load Xn_blocks dw ? ; file size in blocks X Xblock_buf db 1024 dup (?) ; I/O buffer for all disk reads X;boot_buf db 1024 dup (?) ; Boot block copied here Xsuper_buf dw 512 dup (?) ; Super block loaded here Xinode_buf dw 512 dup (?) ; Inode block loaded here Xind_buf dw 512 dup (?) ; Indirect block loaded here (sometimes) Xdir_buf dw 512 dup (?) ; root file directory loaded here X;fil_buf db 20 dup (1024 dup (?)) ; temporary file load area X Xstack dw 100 dup (?) ; small stack area for boot only Xestack label word ; init SP here X X_text ends X X end start1 SHAR_EOF if test 17454 -ne "`wc -c < 'b1/bootblok.asm4'`" then echo shar: error transmitting "'b1/bootblok.asm4'" '(should have been 17454 characters)' fi fi # end of overwriting check echo shar: extracting "'b1/fdboot.uu'" '(1437 characters)' if test -f 'b1/fdboot.uu' then echo shar: will not over-write existing file "'b1/fdboot.uu'" else sed 's/^X//' << \SHAR_EOF > 'b1/fdboot.uu' Xbegin 644 fdboot XMC,B.V([0O&N4Z'D QP:1?P$ C-N.P[L ?NBJ '+^QP:7?P$ C!Z=?\<&GW^C XMC^C/ :&A?[$*T^"[ [V'T9@[^CCP!T#8VWI8^-/CE_Z#@"= N#PQ#KX[LC XM?^GK HN'HX^CEW_'!IU_ #+'!I]_ #HC &[DG[HVP**%F9],O;J ,C+D XMBA9F?<T3PZ&+?Z&+?P/ HY%_C-N.P[NC?^@C '(@_P:1?[NC@>@7 '(4C3:C XM?XL^C7^.QXL^CW^Y +\\Z7#Q@:*?PJ0_@Z*?W@NH9%_,]+W-F)] P9G?8K, XMT,G0R8KHB\(STO<V9'V*\ K*_L&*%F9]N $"S1-RS,/'!HM_ 0",'HU_QP:/ XM?Z.#Z'K_<P:[O7[I+0*AEW](,]+W-FU]B1:5?P,&IX,#!JF#!0( HY-_HXM_ XMC!Z-?\<&CW^CA^A&_W,&N]E^Z?D!BQZ5?[D% -/C@<.CAXD>F7_#$@ ) XM 0@ XM XM XM 5:KH_OZ+'IE_BT<$BU<&]S9K?:.A?X72= 3_!J%_ XM@SZA?P=^&XM''*.+?XP>C7_'!H]_HXOH6/YS!KOO?ND+ :&=?Z.-?Z&??Z./ XM?\<&FW\ (L>FW\['J%_?2X#VX/[#GT* QZ9?XM'#NL%D(N'E8NCBW_H&?YS XM!KL.?^G, (,&C7] _P:;?^O(PQX'_+D. /.FPPT*4V5C;VYD(&)O;W0@<W1A XM9V4@;&]A9&5D+B!3=&%R=&EN9R N+BX-"@!%<G)O<B!R96%D:6YG(%-U<&5R XM7V)L;V-K#0H 17)R;W(@<F5A9&EN9R!);F]D90T* $5R<F]R(')E861I;F<@ XM26YD:7)E8W0@0FQO8VL-"@!%<G)O<B!R96%D:6YG(&9I;&4-"@!";V]T(&9I XM;&4@;F]T(&9O=6YD#0H 8F]O= .@) .O^M XRV\T0PXH' XMA,!T"%/H[_];0^ORPU#1Z-'HT>C1Z.@! %@D#P0P/#E^ @0'Z-#_PU"&Q.C? XM_UCHV__# XM XB X Xend SHAR_EOF if test 1437 -ne "`wc -c < 'b1/fdboot.uu'`" then echo shar: error transmitting "'b1/fdboot.uu'" '(should have been 1437 characters)' fi fi # end of overwriting check echo shar: extracting "'b1/hdboot.uu'" '(1437 characters)' if test -f 'b1/hdboot.uu' then echo shar: will not over-write existing file "'b1/hdboot.uu'" else sed 's/^X//' << \SHAR_EOF > 'b1/hdboot.uu' Xbegin 644 hdboot XMC,B.V([0O&N4B1Z6?8DVF'VT"(H6E7W-$X#A/S+MB0Z3?8K&_L RY/;AHY%] XMZ(0 QP:1?P$ C-N.P[L ?NBU '+^QP:7?P$ C!Z=?\<&GW^CC^BK :&A?[$* XMT^"[ [V'T9@[^CCP!T#8VWI8^-/CE_Z!0"= N#PQ#KX[LC?^G' HN'HX^C XMEW_'!IU_ #+'!I]_ #H: &[DG[HMP*AF'TMO@>Q$/;Q,N0%00"+T.H R XM,N2*%I5]S1/#H8M_H8M_ \"CD7^,VX[#NZ-_Z", <B#_!I%_NZ.!Z!< <A2- XM-J-_BSZ-?X['BSZ/?[D OSSI</&!HI_"I#^#HI_>"ZAD7\STO<VD7T#!I9] XMBLS0R=#)BNB+PC/2]S:3?8KP"LK^P8H6E7VX 0+-$W+,P\<&BW\! (P>C7_' XM!H]_HX/H>O]S!KN]?NG^ :&7?T@STO<VG'V)%I5_ P:G@P,&J8,% @"CDW^C XMBW^,'HU_QP:/?Z.'Z$;_<P:[V7[IR@&+'I5_N04 T^.!PZ.'B1Z9?\,2 D XM@ !" XM XM 5:KH+?^+'IE_BT<$BU<&]S::?:.A?X72= 3_!J%_ XM@SZA?P=^&XM''*.+?XP>C7_'!H]_HXOHA_YS!KOO?ND+ :&=?Z.-?Z&??Z./ XM?\<&FW\ (L>FW\['J%_?2X#VX/[#GT* QZ9?XM'#NL%D(N'E8NCBW_H2/YS XM!KL.?^G, (,&C7] _P:;?^O(PQX'_+D. /.FPPT*4V5C;VYD(&)O;W0@<W1A XM9V4@;&]A9&5D+B!3=&%R=&EN9R N+BX-"@!%<G)O<B!R96%D:6YG(%-U<&5R XM7V)L;V-K#0H 17)R;W(@<F5A9&EN9R!);F]D90T* $5R<F]R(')E861I;F<@ XM26YD:7)E8W0@0FQO8VL-"@!%<G)O<B!R96%D:6YG(&9I;&4-"@!";V]T(&9I XM;&4@;F]T(&9O=6YD#0H 8F]O= .@) .O^M XRV\T0PXH' XMA,!T"%/H[_];0^ORPU#1Z-'HT>C1Z.@! %@D#P0P/#E^ @0'Z-#_PU"&Q.C? XM_UCHV__# XM XB X Xend SHAR_EOF if test 1437 -ne "`wc -c < 'b1/hdboot.uu'`" then echo shar: error transmitting "'b1/hdboot.uu'" '(should have been 1437 characters)' fi fi # end of overwriting check echo shar: extracting "'b1/mfdisk.asm'" '(17596 characters)' if test -f 'b1/mfdisk.asm' then echo shar: will not over-write existing file "'b1/mfdisk.asm'" else sed 's/^X//' << \SHAR_EOF > 'b1/mfdisk.asm' X page ,132 X title MFDISK - FDISK clone & multiple boot-record modifier X X;------------------------------------------------------------------------------ X; This program will write a new boot sector to the first HD drive X; that prompts for the partition you want to boot from (1-4). X; To the question 'Boot partition (1-4):' you have to answer with X; the number of the partition you want to boot from (1-4). X; X; The program must be compiled as a .COM file (remember exe2bin) X; and run under MesSDOS. X; X; The makefile for compiling under MesSDOS should look like: X; X; mfdisk.obj: mfdisk.asm X; masm mfdisk; X; X; mfdisk.com: mfdisk.obj X; link mfdisk; X; exe2bin mfdisk.exe mfdisk.com X; del mfdisk.exe X; X; When the program is run, it produces a message telling you what X; it is going to do. At this time you can abort it by typing X; <CTRL-C> or type <CR> to allow it to modify the hard-disk. X; X; Now you can boot multiple operating systems (MesSDOS, OS/2, X; SCO Xenix and Minix) from the same hard-disk). To do so you X; had to partition your hard-disk to separate partitions, each X; with another operating-system boot. X; X; Motti (Mordehai) Bazar X; X; uucp : ..uunet!ocsmd!motti X; bitnet : motti%ocsmd@uunet.uu.net X; internet: motti@ocsmd.uu.net OR X; resrote@gwusun.gwu.edu (put my name on subject line) X; X; snail: Online Computer Systems, Inc. X; 20251 Century Blvd. X; Germantown, MD 20874 X; X; vox: (301) 428-3700 X; X; X; This utility is distributed for personal use only. Use it, modify it X; or do anything you like, just live this comment and let me know of X; any bugs or enhancements you made to it, thanks. X; X;------------------------------------------------------------------------------ X X X;------------------------- X; First, some definitions X;------------------------- X XVIDEO equ 10h XKBD equ 16h XDISKIO equ 13h XDOS equ 21h X XCR equ 0Dh XLF equ 0Ah X X X;--------------------------- X; Here comes the real thing X;--------------------------- X XCODE segment byte public 'CODE' X assume cs:CODE, ds:CODE X X org 100h X XWRITBOOT: X jmp START ; jump around X XDISKBUF db 512 dup(?) X XHELLOMS db CR, LF X db 'MFDISK - Multiple boot FDISK clone', CR, LF X db CR, LF X db 'This program will read the boot sector from the first disk', CR, LF X db 'and merge the partition table from it with the boot program', CR, LF X db 'supplied and write it all back to the disk overlaying what', CR, LF X db 'was there. The resultant boot program will prompt for the', CR, LF X db 'desired partition for booting (1-4).', CR, LF X db CR, LF X db 'The original boot program will be saved in a file named', CR, LF X db 'IBMBOOT.SVE in the default directory.', CR, LF X db CR, LF X db '<CR> = continue, CONTROL-C = abort ... $' X XCRLF db CR, LF, '$' X XIBMBOOT db 'IBMBOOT.SVE',0 X XOKMSG db CR, LF, 'Boot sector updated', CR, LF, '$' XERMSG1 db CR, LF, 'Error reading boot sector', CR, LF, '$' XERMSG2 db CR, LF, 'Cannot open save file', CR, LF, '$' XERMSG3 db CR, LF, 'Cannot write save file', CR, LF, '$' XERMSG4 db CR, LF, 'Cannot close save file', CR, LF, '$' XERMSG5 db CR, LF, 'Cannot write boot sector', CR, LF, '$' X XBOOTHDL dw 0 ; Boot backup file handle X X XSTART: X ;---------------------- X ; Show opening message X ;---------------------- X mov dx, offset HELLOMS X mov ah, 9 X int DOS X XRDCNS: X ;--------------------------------------------------------- X ; Get user's response: <CR> or CONTROL-C (aborted by DOS) X ;--------------------------------------------------------- X mov ah, 0Ch X mov al, 1 X int DOS X cmp al, CR ; <CR> key ? X jne RDCNS ; No, retry X X ;----------------------------------------- X ; <CR> typed, go and modify the hard-disk X ;----------------------------------------- X mov dx, offset CRLF ; Echo <CR><LF> X mov ah, 9 X int DOS X X ;------------------------------------ X ; Read the sector from the hard-disk X ;------------------------------------ X mov si, 5 ; Retry for 5 times XRDDSK: X push si ; Save retry counter X mov ah, 2 ; Read disk X mov al, 1 ; 1 sector X mov bx, offset DISKBUF ; Point to buffer X mov ch, 0 ; Cylinder 0 X mov cl, 1 ; Sector 1 X mov dh, 0 ; Track 0 X mov dl, 80h ; Harddisk 0 X int DISKIO X pop si X jnc RDOK ; Good read X dec si ; More tries? X jnz RDDSK ; Yes, try again X mov dx, offset ERMSG1 ; No, point to trouble message X mov ah, 9 ; say console write X int DOS ; can't read boot sector X mov ah, 4Ch ; say terminate X mov al, 1 ; error return code X int DOS X X ;--------------------------------- X ; Create the file to save it into X ;--------------------------------- XRDOK: X mov dx, offset IBMBOOT ; get file name X mov ah, 3Ch ; say create it X sub cx, cx ; zero attribute X int DOS X jnc OPENOK ; file opened X mov dx, offset ERMSG2 ; can't open save file X mov ah, 9 X int DOS ; tell 'em X mov ah, 4Ch ; say terminate X mov al, 2 ; reason X int DOS X X ;--------------------------------- X ; Write sector to the backup file X ;--------------------------------- XOPENOK: X mov BOOTHDL, ax ; save handle X mov bx, ax ; and put in bx X mov ah, 40h ; say write to file X mov dx, offset DISKBUF ; get location X mov cx, 512 ; say 1 sector X int DOS ; ask to have it done X jnc WRTOK ; good write X mov dx, offset ERMSG3 ; can't write to save file X mov ah, 9 X int DOS ; tell 'em X mov ah, 4Ch ; say terminate X mov al, 3 ; reason X int DOS X X ;------------------- X ; Close backup file X ;------------------- XWRTOK: X mov ah, 3Eh ; say close file X mov bx, BOOTHDL X int DOS X jnc CLOSOK ; closed ok X mov dx, offset ERMSG4 ; can't close save file X mov ah, 9 X int DOS ; tell 'em X mov ah, 4Ch ; say terminate X mov al, 4 ; reason X int DOS X X ;----------------------------------------------------- X ; Copy the read partition table into our sector so it X ; will use it when booting. X ;----------------------------------------------------- XCLOSOK: X push si X mov si, offset DISKBUF+1BEh ; start of partition table X mov di, offset BOOTSEC+1BEh ; ditto for new sector X cld ; make direction positive X mov cx, 4*16+2 ; how many bytes to move X rep movsb ; move em X X ;---------------------------------------- X ; Write our sector back to the hard-disk X ;---------------------------------------- X mov si, 5 ; 5 retries XWRTBOOT: X push si X mov ah, 3 ; say write to disk X mov al, 1 ; say 1 sector X mov bx, offset BOOTSEC ; point to sector to write X mov cx, 1 ; say sector 1 X mov dx, 80h X int DISKIO ; do the io X pop si X jnc UPDOK ; good write to boot sector X dec si ; count retries X jnz WRTBOOT ; try again X X mov dx, offset ERMSG5 ; can't write boot sector file X mov ah, 9 X int DOS ; tell 'em X mov ah, 4Ch ; say terminate X mov al, 5 ; reason X int DOS X X ;---------------------------------------------------------- X ; Inform the user that the operation finished successfully X ; and exit back to DOS. X ;---------------------------------------------------------- XUPDOK: X mov dx, offset OKMSG ; say we did it X mov ah, 9 X int DOS ; tell 'em X mov ah, 4Ch ; say terminate X mov al, 0 ; good return code X int DOS X X X X;**************************************************************** X;* BOOTSEC * X;* * X;* Here comes the sector patched into the hard-disk * X;**************************************************************** X XBOOTSEC: X XBSTART equ $ ; Start offset of our boot sector XBOOTLOC equ 7C00h ; Boot sector loaded there XBOOTSIG equ 7DFEh ; Boot sector signal address XMOVETO equ 600h ; Where to move it XPARTTBL equ BSTART + 1BEh ; Start of partition table in our code X X X cli X xor ax, ax ; (AX) = 0 X mov ss, ax ; (SS) = Set stack segment to 0 X mov sp, offset BOOTLOC ; Get boot code address X mov si, sp ; (SI) = Source address X mov es, ax ; (ES) = 0 X mov ds, ax ; (DS) = 0 X sti X cld X mov di, MOVETO ; (DI) = Destination address X mov cx, 100h ; (CX) = # of words to move X rep movsw ; Move it X X ;------------------------------------ X ; Setup to continue the boot process X ;------------------------------------ X mov ax, MOVETO + offset RELBOOT - BSTART X push ax X ret X XRELBOOT: X ;---------------------------------- X ; Set all partitions as not active X ;---------------------------------- X mov bx, MOVETO + 1BEh X mov byte ptr [bx], 0 X mov byte ptr 16[bx], 0 X mov byte ptr 32[bx], 0 X mov byte ptr 48[bx], 0 X X ;------------------------------------------ X ; Show boot prompt 'Boot partition (1-4):' X ;------------------------------------------ XWRPRMPT: X mov si, MOVETO + offset BOOTMSG - BSTART X lodsb X mov cl, al X xor ch, ch XWR000: X lodsb X mov bx, 7 X mov ah, 0Eh X int VIDEO X loop WR000 X X ;------------------------------- X ; Get user's response & show it X ;------------------------------- X mov ah, 0 ; Get keyboard input X int KBD X push ax X mov ah, 10 ; Show it X mov cx, 1 X int VIDEO X pop ax X X ;---------------------------------- X ; Check for legal partition number X ;---------------------------------- X cmp al, '1' ; # below 1 ? X jb WRPRMPT ; Yes, error X cmp al, '4' ; # above 4 ? X ja WRPRMPT ; Yes, error X X ;-------------------------------------- X ; AL contains partition # to boot from X ;-------------------------------------- X and al, 7 ; Mask partition # X X ;---------------------------------------- X ; Calculate partition table entry to use X ;---------------------------------------- X mov si, MOVETO + 1BEh ; point to first entry XCALCPART: X dec al X jz GOTPART X add si, 16 ; Advance to next partition X jmp short CALCPART X X XGOTPART: X ;----------------------------------------------------- X ; Set the requested partition as the active partition X ;----------------------------------------------------- X mov byte ptr[si], 80h X push si X push bx X mov ax, 0301h X mov bx, MOVETO X mov cx, 1 X mov dx, 80h X int diskio X pop bx X pop si X X ;------------------------------------------------------------- X ; Now go and try to read the selected partition's boot sector X ;------------------------------------------------------------- X mov dx, [si] ; (DH) = drive, (DL) = head X mov cx, [si+2] ; (CH) = track, (CL) = sector X mov bp, si ; Save partition pointer X mov di, 5 ; Set retry count XRDBOOT: X mov bx, BOOTLOC ; Location for boot X mov ax, 0201h ; Read 1 sector X push di X int DISKIO ; Go read X X pop di X jnc GOODRD ; Good read X X xor ax, ax ; Recalibrate X int DISKIO X dec di ; Decrement retries count X jnz RDBOOT ; Counter at zero ? X X ;--------------------------------------------------- X ; Can't read boot sector, show a message and hangup X ;--------------------------------------------------- X mov si, MOVETO + offset MSG2 - BSTART XWRMSG: X lodsb ; Get message length X mov cl, al X xor ch, ch XWR002: X lodsb X mov bx, 7 X mov ah, 0Eh X int VIDEO X loop WR002 X jmp WRPRMPT X X X ;------------------------------------------------ X ; Boot sector read, check for the boot signature X ;------------------------------------------------ XGOODRD: X mov si, MOVETO + offset MSG3 - BSTART ; Point to no boot msg X mov bx, BOOTSIG X cmp word ptr [bx], 0AA55h ; Check for the boot signature X jne WRMSG X X ;----------------------------------------------------------------- X ; Finaly, go and boot. X ; X ; Before booting set: X ; SI - points to partition table entry we are booting from X ; BX - starting cylinder number of this partition X ;----------------------------------------------------------------- X mov si, bp ; Restore partition table pointer X X mov ax, word ptr 2[si] ; AH-cyl, AL-sec X xor bh, bh X mov bl, al X shl bx, 1 X shl bx, 1 ; BH-2 msb bits X mov bl, ah ; BL-8 lsb bits X X mov ax, offset BOOTLOC ; Where partition boot start X push ax X ret X X XBOOTMSG db LMSGB, CR, LF, 'Boot partition (1-4): ' XLMSGB equ ($-BOOTMSG)-1 X XMSG2 db LMSG2, CR, LF, 'Error loading operating system' XLMSG2 equ ($-MSG2)-1 X XMSG3 db LMSG3, CR, LF, 'Missing operating system' XLMSG3 equ ($-MSG3)-1 X X org BSTART + 512 X XCODE ends X end WRITBOOT X X SHAR_EOF if test 17596 -ne "`wc -c < 'b1/mfdisk.asm'`" then echo shar: error transmitting "'b1/mfdisk.asm'" '(should have been 17596 characters)' fi fi # end of overwriting check echo shar: extracting "'b2b/Makefile'" '(239 characters)' if test -f 'b2b/Makefile' then echo shar: will not over-write existing file "'b2b/Makefile'" else sed 's/^X//' << \SHAR_EOF > 'b2b/Makefile' XCFLAGS=-I/usr/src/minix -Di8088 X X#.c.s: X# cc $(CFLAGS) -c $*.c X Xall: loader.s stack.s standalone.s main.s X asld -T. -s -o b2 bsu.s main.s loader.s stack.s standalone.s /usr/lib/libc.a /usr/lib/end.s > b2.sym X dd if=b2 of=boot bs=32 skip=1 SHAR_EOF if test 239 -ne "`wc -c < 'b2b/Makefile'`" then echo shar: error transmitting "'b2b/Makefile'" '(should have been 239 characters)' fi fi # end of overwriting check echo shar: extracting "'b2b/bsu.s'" '(5666 characters)' if test -f 'b2b/bsu.s' then echo shar: will not over-write existing file "'b2b/bsu.s'" else sed 's/^X//' << \SHAR_EOF > 'b2b/bsu.s' X| X| Second-Stage Bootstrap assembly level run-time support X| Derrived from "tools/fsck1.s" and "kernel/klib88.s" X| XSTACKSIZE = 16384 X X.globl _main, endtext, enddata, endbss X.globl __putc, __getc, _reset_diskette, _diskio, _hd_param X.globl csv, cret, begtext, begdata, begbss X.globl _cylsiz, _tracksiz, _def_dev X.globl _ds, _lcopy, _sp X X.text Xbegtext: Xstart: X mov ax,cs | ds=es=ss=cs X mov es,ax X mov ds,ax X mov ss,ax X| mov dx,bx | bootblok puts boot device in BX X xor ax,ax X mov bx,#enddata | prepare to clear bss X mov cx,#endbss X sub cx,bx X shr cx,*1 Xst.1: mov (bx),ax | clear bss X add bx,#2 X loop st.1 X X mov _def_dev,dx X mov sp,#kerstack+STACKSIZE X call _main Xst.2: mov bx,ax | put scan code for '=' in bx X| mov bp,#_sizes | bp points to 'sizes' array X mov sp,_ksp | sp first 'cause we'll destroy ds X mov dx,_kds X mov ds,dx X mov ss,dx X nop X cli X| mov dx,#0x60 X|leave ES where it is so kernel can find the a.out table... X| mov es,dx X nop X jmpi 0,0x60 | jmp to kernel X X|_exit: X| mov bx,_tracksiz X jmp start X X X__putc: X xor ax,ax X call csv X movb al,4(bp) | al contains char to be printed X movb ah,#14 | 14 = print char X movb bl,*1 | foreground color X push bp | not preserved X int 0x10 | call BIOS VIDEO_IO X pop bp X jmp cret X X__getc: X xorb ah,ah X int 0x16 X ret X X_ds: X mov ax,ds X ret X_sp: X mov ax,sp X ret X X_reset_diskette: X xor ax,ax X call csv X push es | not preserved X int 0x13 | call BIOS DISKETTE_IO X pop es X jmp cret X X X| handle diskio(RW, sector_number, buffer, sector_count, drive) call X| Do not issue a BIOS call that crosses a track boundary X_diskio: X xor ax,ax X call csv X mov tmp1,#0 | tmp1 = # sectors actually transferred X mov di,10(bp) | di = # sectors to transfer X mov tmp2,di | di = # sectors to transfer Xd0: mov ax,6(bp) | ax = sector number to start at X xor dx,dx | dx:ax is dividend X div _cylsiz | ax = cylinder, dx = sector within cylinder X movb cl,ah | cl = hi-order bits of cylinder X rorb cl,#1 | BIOS expects hi bits in a funny place X rorb cl,#1 | ditto X movb ch,al | cx = sector # in BIOS format X mov ax,dx | ax = sector offset within cylinder X xor dx,dx | dx:ax is dividend X div _tracksiz | ax = head, dx = sector X movb dh,al | dh = head X orb cl,dl | cl = 2 high-order cyl bits || sector X incb cl | BIOS counts sectors starting at 1 X movb dl,12(bp) | dl = drive code (0-3 or 0x80 - 0x81) X mov bx,8(bp) | bx = address of buffer X movb al,cl | al = sector # X addb al,10(bp) | compute last sector X decb al | al = last sector to transfer X cmpb al,_tracksiz | see if last sector is on next track X jle d1 | jump if last sector is on this track X mov 10(bp),#1 | transfer 1 sector at a time Xd1: movb ah,4(bp) | ah = READING or WRITING X addb ah,*2 | BIOS codes are 2 and 3, not 0 and 1 X movb al,10(bp) | al = # sectors to transfer X mov tmp,ax | al is # sectors to read/write X push es | BIOS ruins es X int 0x13 | issue BIOS call X pop es | restore es X cmpb ah,*0 | ah != 0 means BIOS detected error X jne d2 | exit with error X mov ax,tmp | fetch count of sectors transferred X xorb ah,ah | count is in ax X add tmp1,ax | tmp1 accumulates sectors transferred X mov si,tmp1 | are we done yet? X cmp si,tmp2 | ditto X je d2 | jump if done X inc 6(bp) | next time around, start 1 sector higher X add 8(bp),#0x200 | move up in buffer by 512 bytes X jmp d0 Xd2: jmp cret X Xcsv: X pop bx X push bp X mov bp,sp X push di X push si X sub sp,ax X jmp (bx) X Xcret: X lea sp,*-4(bp) X pop si X pop di X pop bp X ret X X|*===========================================================================* X|* phys_copy * X|*===========================================================================* X| This routine copies a block of physical memory. It is called by: X| lcopy(destination segment, offset, source segment, offset, length) X| phys_copy( (long) source, (long) destination, (long) bytecount) X X_lcopy: X pushf | save flags X cli | disable interrupts X push bp | save the registers X push ax | save ax X push bx | save bx X push cx | save cx X push dx | save dx X push si | save si X push di | save di X push ds | save ds X push es | save es X mov bp,sp | set bp to point to saved es X X L0: mov ax,22(bp) | ax = segment of destination X mov di,24(bp) | di = offset of destination X mov es,ax | es = destination click X X mov ax,26(bp) | ax = segment of source X mov si,28(bp) | si = offset of source X X mov cx,30(bp) | cx = low-order word of byte count X X mov ds,ax | ds = source click X X test cx,*0x0001 | should we copy a byte or a word at a time? X jz L5 | jump if even X rep | copy 1 byte at a time X movb | byte copy X jmp L6 | check for more bytes X X L5: shr cx,*1 | word copy X rep | copy 1 word at a time X movw | word copy X X L6: pop es | restore all the saved registers X pop ds | restore ds X pop di | restore di X pop si | restore si X pop dx | restore dx X pop cx | restore cx X pop bx | restore bx X pop ax | restore ax X pop bp | restore bp X popf | restore flags X ret | return to caller X X| Get Hard Disk parameters X| hd_param(device) X| sets sectors per track in tracksiz and returns the number of heads. X_hd_param: X call csv X movb ah, #8 | Return current drive parameters X movb dl, 4(bp) | First hard-disk X int 0x13 X andb cl, #0x3F | discard cylinder number high bits X xorb ch, ch | CX - Number of sectors per track X mov _tracksiz, cx X movb al,dh | cylsize = heads * tracksize X incb al | It was 0 origin X xorb ah,ah | AX = Number of heads X mul cx X mov _cylsiz, ax X jmp cret X X.data Xbegdata: Xtmp: .word 0 Xtmp1: .word 0 Xtmp2: .word 0 X.bss Xbegbss: Xkerstack: .zerow STACKSIZE/2 | kernel stack SHAR_EOF if test 5666 -ne "`wc -c < 'b2b/bsu.s'`" then echo shar: error transmitting "'b2b/bsu.s'" '(should have been 5666 characters)' fi fi # end of overwriting check echo shar: extracting "'MANIFEST'" '(384 characters)' if test -f 'MANIFEST' then echo shar: will not over-write existing file "'MANIFEST'" else sed 's/^X//' << \SHAR_EOF > 'MANIFEST' XFile Name Kit Number X-------------- ---------- XMANIFEST 1 XREADME 1 Xb1/bootblok.asm4 1 Xb1/fdboot.uu 1 Xb1/hdboot.uu 1 Xb1/mfdisk.asm 1 Xb2b/Makefile 1 Xb2b/bsu.s 1 Xb2b/loader.c 2 Xb2b/main.c 2 SHAR_EOF if test 384 -ne "`wc -c < 'MANIFEST'`" then echo shar: error transmitting "'MANIFEST'" '(should have been 384 characters)' fi fi # end of overwriting check # End of shell archive exit 0