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)