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