Assignment #1 HELP

1. Install BCC (MUST) and dosemu (optional):
   Download and install from samples/BCC/

2. Download mys.s, myc.c and mk from samples/A1/HELP/
 
   Use mys.s myc.c to demonstrate booting start, and BIOS I/O
   Use mk to show how to use BCC : bcc, as86, ld86 to create bootable FD 
   Boot up from FD : on hardware PC or  xdosemu -A


================ PART 1: Boot MTX from FD ================================

3. Use boots.s file to show:
   floppy disk I/O: diskr()/diskw() using parameters in CHS format
                    get_block(blk, buf) in C ==> convert blk to CHS
   
   loading disk block to memory:
           get_block(blk, buf), where memory = (ES, buf)==>

           setes(segment), then get_block(blk, 0), then 
           inces() by block size (1KB or 0x40)
    
4. EXT2 file system:
   EXT2 FS, search for file=pathname to get its inode ==> all disk blocks.


5. use mtximage to demonstrate booter for MTX:

       boots.s (diskr() for floppy, setes(), inces())
       bootc.c: search for /boot/mtx ==> get its inode ==> all disk blocks
                load disk blocks to segment 0x1000
                return 0 to boots.s, which jmpi to (0x1000, 0) to start up MTX.



========== Part 2:Booting MTX/Linux from HD ============================

1. Partition table in MBR:

   struct partition {
	unsigned char drive;		/* 0x80 - active */

	unsigned char head;		/* starting head */
	unsigned char sector;		/* starting sector */
	unsigned char cylinder;		/* starting cylinder */

	unsigned char sys_type;		/* partition type */

	unsigned char end_head;		/* end head */
	unsigned char end_sector;	/* end sector */
	unsigned char end_cylinder;	/* end cylinder */

	unsigned long start_sector;	/* starting sector counting from 0 */
	unsigned long nr_sectors;       /* nr of sectors in partition */
   };


   PRE_WORK: In Linux: write a C program to display the partition table of HD

      int fd = open("/dev/hda", O_RDONLY);
      char buf[512];
      read (fd, buf, 512);
      struct partition *sp = &buf[0x1BE];
      Then use sp-> to acess the partition table entries

      For extended partition, traverse the extended partition link list.


2. READ HD sectors by extended BIOS INT 13/AH=0x42:

Int 13/AH=42h - IBM/MS INT 13 Extensions - EXTENDED READ - 
AH = 42h
DL = drive number
DS:SI - disk address packet (see #00272)
Return: CF clear if successful
AH = 00h
CF set on error
AH = error code (see #00234)

disk address packet's block count field set to number of blocks
successfully transferred

Format of disk address packet:

Offset Size    Description 
----   -----   -----------------------------------------------------------
00h    BYTE    size of packet (10h or 18h)
01h    BYTE    reserved (0)
02h    WORD    number of blocks to transfer (max 007Fh for Phoenix EDD)
04h    DWORD   -> transfer buffer
08h    QWORD   starting absolute block number
10h    QWORD   (EDD-3.0, optional) 64-bit flat address of transfer buffer;
               used if DWORD at 04h is FFFFh:FFFFh


===========================================================================
Example:
  
   .s file:
           .globl _dap, _diskr
   
   _diskr: 
         mov   dx, #0x0080      ! DL=0x80=drive number
	 mov   ax, #0x4200      ! AH=0x42
	 mov   si, #_dap        ! DS:SI = disk address in LBA format

         int  0x13              ! call BIOS to read the block 
         jb   error             ! to error if CarryBit is on [read failed]

	 ret
============================================================================
.c file:

struct dap{                   // for extended INT 13 with AX=0x42  
  unsigned char  op;          // dap length=0x10 (16 bytes)
  unsigned char  zero;        // must be 0  
  unsigned short nsector;     // number of sectors to read
  unsigned short addr;        // memory address = (segment:addr)
  unsigned short segment;    
  unsigned long  s1;          // low  4 bytes of sector#
  unsigned long  s2;          // high 4 bytes of sector#
} dap, *dp;

char mbr[512];

int main()
{
 // read MBR into mbr[512]
    dp = &dap;                 // dp points at the dap struct
    dp->op = 0x10;             // dap length = 0x10
    dp->zero = 0;              // must be 0
    dp->nsector = 1;           // number of sectors to read; 8 for 4KB block

    // memory address (offset, segment)
    dp->addr = (u16)mbr;       // memory address offset   
    dp->segment = getds();     // memory segment = DS segment of booter

    // LBA of disk
    dp->s1 = 0;                // sector 0 of disk 
    dp->s2 = 0;

    diskr();                   // call diskr() in boots.s
 
  // print partition table in mbr[ ]
}

OR : Write function in C:

get_block(blk, buf) u32 blk; char *buf;
{
  // fill dap struct with info from (blk, buf);
  diskr();
}


3. copy REAL memory to Extendd Memory by INT 15/AH=0x87

Int 15/AH=87h - SYSTEM - COPY EXTENDED MEMORY - 
AH = 87h
CX = number of words to copy (max 8000h)
ES:SI - global descriptor table (see #00499)
Return: CF set on error
CF clear if successful
AH = status (see #00498)

Notes: copy is done in protected mode with interrupts disabled by the default
BIOS handler; many 386 memory managers perform the copy with
interrupts enabled

Format of global descriptor table:

Offset  Size     Description 
----   --------  --------------------------------------------------------- 
00h    16 BYTEs  zeros (used by BIOS)
10h    WORD      source segment length in bytes (2*CX-1 or greater)
12h    3 BYTEs   24-bit linear source address, low byte first
15h    BYTE      source segment access rights (93h)
16h    WORD      (286) zero
                 (386+) extended access rights and high byte of source address
18h    WORD      destination segment length in bytes (2*CX-1 or greater)
1Ah    3 BYTEs   24-bit linear destination address, low byte first
1Dh    BYTE      destination segment access rights (93h)
1Eh    WORD      (286) zero
                 (386+) extended access rights and high byte of destin. address
20h    16 BYTEs  zeros (used by BIOS to build CS and SS descriptors)