k0

This page contains the necessary resource for students undertaking the k0 stage.

BIOS Interrupts

In order to call the BIOS interrupt N,M, one needs to put M in ah and trigger the interrupt N through the instruction int N. Be careful, the interrupt code is always given in its hexadecimal representation. Therefore, INT 10 stands for INT 0x10.

Set the Cursor Position --- INT 10,2

Inputs:

  • AH = 0x02
  • BH = page number (0 for graphics modes)
  • DH = row
  • DL = column

Note that the 80x25 mode uses coordinates (0, 0) to (24, 79).

Read the Cursor Position and Size --- INT 10,3

Inputs:

  • AH = 0x03
  • BH = page number (0 for graphics modes)

Outputs:

  • CH = cursor starting scan line (low order 5 bits)
  • CL = cursor ending scan line (low order 5 bits)
  • DH = row
  • DL = column

Write Text in Teletype Mode --- INT 10,E

Inputs:

  • AH = 0x0e
  • AL = ASCII character to write
  • DH = page number (text modes)
  • BL = foreground pixel color (graphics mode)

Note that the cursor advances once the write has been performed.

Reset the Disk System --- INT 13,0

Inputs:

  • AH = 0x00
  • DL = drive number

Outputs:

  • AH = disk operation status
  • CF = 0 if successful, 1 if error

Read Disk Sectors --- INT 13,2

Inputs:

  • AH = 0x02
  • AL = number of sectors to read
  • CH = track/cylinder number
  • CL = sector number
  • DH = head number
  • DL = drive number
  • ES:BX = pointer to buffer

Outputs:

  • AH = disk operation status
  • AL = number of sectors read
  • CF = 0 if successful, 1 if error

Wait for Key Being Pressed and Read Character --- INT 16,0

Inputs:

  • AH = 0x00

Outputs:

  • AH = keyboard scan code
  • AL = ASCII character or zero if special function key

VGA Frame Buffer

The VGA frame buffer is a mapped I/0 device to which one can write in order to display text. The mapped device starts at the address 0xb8000 and is composed of 80x24 cells of the following structure:

struct          s_cell
{
  char          ascii_code : 8;
  char          fg_color : 3;
  char          intensity : 1;
  char          bg_color : 3;
  char          blink : 1;
}               __attribute__((__packed__));

ELF

The structure of the ELF can be found, on most UNIX systems, in /usr/include/elf.h. However, a simplified version of the ELF definitions is given below.

typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Word;
typedef uint32_t Elf32_Addr;
typedef uint32_t Elf32_Off;

/* The ELF file header. This appears at the start of every ELF file */

#define EI_NIDENT (16)

typedef struct                      /* Offset Description */
{
  unsigned char e_ident[EI_NIDENT]; /* +0     Magic number and other info */
  Elf32_Half    e_type;             /* +16    Object file type */
  Elf32_Half    e_machine;          /* +18    Architecture */
  Elf32_Word    e_version;          /* +20    Object file version */
  Elf32_Addr    e_entry;            /* +24    Entry point virtual address */
  Elf32_Off     e_phoff;            /* +28    Program header table file offset */
  Elf32_Off     e_shoff;            /* +32    Section header table file offset */
  Elf32_Word    e_flags;            /* +36    Processor-specific flags */
  Elf32_Half    e_ehsize;           /* +40    ELF header size in bytes */
  Elf32_Half    e_phentsize;        /* +42    Program header table entry size */
  Elf32_Half    e_phnum;            /* +44    Program header table entry count */
  Elf32_Half    e_shentsize;        /* +46    Section header table entry size */
  Elf32_Half    e_shnum;            /* +48    Section header table entry count */
  Elf32_Half    e_shstrndx;         /* +50    Section header string table index */
} Elf32_Ehdr;                       /* sizeof(Elf32_Ehdr) = 52 */

/* Conglomeration of the identification bytes, for easy testing as a word.  */

#define ELFMAG          "\177ELF"
#define SELFMAG         4

typedef struct                      /* Offset Description */
{
  Elf32_Word    p_type;             /* +0     Segment type */
  Elf32_Off     p_offset;           /* +4     Segment file offset */
  Elf32_Addr    p_vaddr;            /* +8     Segment virtual address */
  Elf32_Addr    p_paddr;            /* +12    Segment physical address */
  Elf32_Word    p_filesz;           /* +16    Segment size in file */
  Elf32_Word    p_memsz;            /* +20    Segment size in memory */
  Elf32_Word    p_flags;            /* +24    Segment flags */
  Elf32_Word    p_align;            /* +28    Segment alignment */
} Elf32_Phdr;                       /* sizeof(Elf32_Phdr) = 32 */

The file below can be used to try loading an ELF file.

An ELF example file

Note that this file has been linked with the following LD script:

ENTRY("_start")

PHDRS
{
  code PT_LOAD;
  data PT_LOAD;
}

SECTIONS
{
  . = 0x100000;

  .text :
  {
    *(.text*)
  } : code

  .data :
  {
    *(.data*)
  } : data

  .bss :
  {
    *(.bss*)
  } : data
}