Reprogram the 8253 timer chip to generate interrupts at frequency HZ:
#define HZ 100 static const unsigned short foo = 1193182L / HZ; outportb(0x43, 0x36); /* channel 0, LSB/MSB, mode 3, binary */ outportb(0x40, foo & 0xFF); /* LSB */ outportb(0x40, foo >> 8); /* MSB */
Conserving energy:
|
|
#define DISCARDABLE_CODE(X) \
X __attribute__((section (".dtext"))); \
\
X
#define DISCARDABLE_DATA(X) \
extern X __attribute__((section (".ddata"))); \
\
X
#define HZ 100
DISCARDABLE_CODE(static void init_8253(void))
{ static const unsigned short foo = (3579545L / 3) / HZ;
outportb(0x43, 0x36); /* channel 0, LSB/MSB, mode 3, binary */
outportb(0x40, foo & 0xFF); /* LSB */
outportb(0x40, foo >> 8); } /* MSB */
DISCARDABLE_DATA(unsigned char g_boot_logo[]) =
{
0xFF, 0xFF, 0xFF /* ... */
};
ENTRY(entry)
LS_Phys = 0x100000; /* 1 meg = load (physical) address */
LS_Virt = 0xC0000000; /* 3 gig = virtual address */
SECTIONS
{ .text LS_Virt : AT(LS_Phys)
{ code = .; _code = .;
*(.text) /* kernel code at 3 gig */
*(.rodata*) /* read-only data */
. = ALIGN(4096);
d_code = .; _d_code = .;
*(.dtext) /* discardable kernel code */
. = ALIGN(4096); }
.data : AT(LS_Phys + (LS_Data - LS_Code))
{ data = .; _data = .;
*(.data) /* kernel data */
. = ALIGN(4096);
d_data = .; _d_data = .;
*(.ddata) /* discardable kernel data */
. = ALIGN(4096); }
.bss : AT(LS_Phys + (LS_Bss - LS_Code))
{ bss = .; _bss = .;
*(.bss) /* kernel BSS */
*(COMMON) /* 'common' vars */
. = ALIGN(4096); }
end = .; _end = .; }
extern char d_code[], data[], d_data[], bss[];
/* unmap (data - d_code) bytes at virtual address d_code */
unmap_mem(d_code, data - d_code);
unmap_mem(d_data, bss - d_data);
unsigned char _vc_width, _vc_height;
unsigned short crtc_base_adr, v_disp;
unsigned char temp, char_ht;
if((inportb(0x3CC) & 0x01) != 0)
crtc_base_adr = 0x3D4; /* color */
else
crtc_base_adr = 0x3B4; /* mono */
/* vertical scan lines displayed */
outportb(crtc_base_adr, 0x12);
v_disp = inportb(crtc_base_adr + 1);
/* pull in bits b8 and b9 from the dread overflow register */
outportb(crtc_base_adr, 0x07);
temp = inportb(crtc_base_adr + 1);
if((temp & 0x02) != 0)
v_disp |= 0x100;
if((temp & 0x40) != 0)
v_disp |= 0x200;
v_disp++;
/* scan lines/char */
outportb(crtc_base_adr, 0x09);
char_ht = (inportb(crtc_base_adr + 1) & 0x1F) + 1;
/* vertical resolution in characters is the quotient */
_vc_height = v_disp / char_ht;
/* horizontal resolution in characters */
outportb(crtc_base_adr, 0x01);
_vc_width = inportb(crtc_base_adr + 1) + 1;
printf("Screen resolution is %u x %u\n",
_vc_width, _vc_height);
#!/bin/sh BLOCKS=1440 FILE=diskette.img # create zeroed file dd if=/dev/zero bs=1k count=$BLOCKS of=$FILE # make Linux treat it as a disk device losetup /dev/loop0 $FILE # create FAT12 (DOS) -OR- ext2 (Linux) filesystem mkdosfs /dev/loop0 $BLOCKS # mke2fs /dev/loop0 $BLOCKS # mount the disk-as-file # mkdir mnt mount /dev/loop0 mnt # create directories on mnt, copy/delete/edit files, etc. # done with the simulated disk umount mnt # done with loopback device: losetup -d /dev/loop0 # configure bochs to use $FILE (diskette.img) bochs