diff --git a/MP2/MP2_Sources.zip b/MP2/MP2_Sources.zip new file mode 100644 index 0000000..161d942 Binary files /dev/null and b/MP2/MP2_Sources.zip differ diff --git a/MP2/MP2_Sources/.DS_Store b/MP2/MP2_Sources/.DS_Store new file mode 100644 index 0000000..4b840fb Binary files /dev/null and b/MP2/MP2_Sources/.DS_Store differ diff --git a/MP2/MP2_Sources/BIOS-bochs-latest b/MP2/MP2_Sources/BIOS-bochs-latest new file mode 100755 index 0000000..2cb4488 Binary files /dev/null and b/MP2/MP2_Sources/BIOS-bochs-latest differ diff --git a/MP2/MP2_Sources/README.TXT b/MP2/MP2_Sources/README.TXT new file mode 100755 index 0000000..b7b6851 --- /dev/null +++ b/MP2/MP2_Sources/README.TXT @@ -0,0 +1,82 @@ +CSCE 410/611/613: MP2 -- README.TXT + +This file describes the content of this directory. +A file marked with (*) may be of some interest to the +student, and he/she may want to have a look at it. +A file marked with (**) is important for this MP, and the +student is strongly encouraged to study the contents of this file. + +BOCH Environment: +================= + +FILE: DESCRIPTION: + +BIOS-bochs-latest BIOS file. +VGABIOS-lgpl-latest BIOS file for the graphics system. +dev_kernel_grub.img Image file of the boot floopy. +bochsrc.bxrc Description file for the system. + Type 'bochs -f bochsrc.bxrc' to + start emulation. + +COMPILATION: +=========== + +FILE: DESCRIPTION: + +makefile (**) Makefile for Linux 64-bit environment. + Works with the provided linux image. + Type "make" to create the kernel. +linker.ld The linker script. + +OS COMPONENTS: +============= + +FILE: DESCRIPTION: + +start.asm (*) The bootloader starts code in this file, which in turn + jumps to the main entry in File "kernel.C". +kernel.C (**) Main file, where the OS components are set up, and the + system gets going. + +assert.H/C Implements the "assert()" utility. +utils.H/C Various utilities (e.g. memcpy, strlen, etc..) + +console.H/C Routines to print to the screen. + +machine.H/C (*) Definitions of some system constants and low-level + machine operations. + (Primarily memory sizes, register set, and + enable/disable interrupts, I/O ports) + +machine_low.H/asm Low-level machine operations (only status register + at this point) + +simple_frame_pool.H/C (**) Definition and partial implementation of a + vanilla physical frame memory manager + that does NOT support contiguous + allocation. + THESE FILES ARE NOT USED IN THE CODE + and are only present to provide an + example implementation of a bitmap with + associated bit-manipulation operations. + +cont_frame_pool.H/C(**) Definition and empty implementation of a + physical frame memory manager that + DOES support contiguous + allocation. NOTE that the comments in + the implementation file give a recipe + of how to implement such a frame pool. + + +UTILITIES: +========== + +FILE: DESCRIPTION: + +copykernel.sh (**) Simple script to copy the kernel onto + the floppy image. + The script mounts the floppy image, copies the kernel + image onto it, and then unmounts the floppy image again. + In rare cases the paths in the file may need to be + edited to make them reflect the student's environment. + diff --git a/MP2/MP2_Sources/VGABIOS-lgpl-latest b/MP2/MP2_Sources/VGABIOS-lgpl-latest new file mode 100755 index 0000000..646216a Binary files /dev/null and b/MP2/MP2_Sources/VGABIOS-lgpl-latest differ diff --git a/MP2/MP2_Sources/assert.C b/MP2/MP2_Sources/assert.C new file mode 100755 index 0000000..e85ae1d --- /dev/null +++ b/MP2/MP2_Sources/assert.C @@ -0,0 +1,45 @@ +/* + File: assert.C + + Author: R. Bettati + Department of Computer Science + Texas A&M University + + Date : 05/01/23 + + Implementation of the assert() function. + +*/ + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "assert.H" + +#include "utils.H" +#include "console.H" + +/*--------------------------------------------------------------------------*/ +/* _assert() FUNCTION: gets called when assert() macro fails. */ +/*--------------------------------------------------------------------------*/ + +void _assert (const char* _file, const int _line, const char* _message ) { + /* Prints current file, line number, and failed assertion. */ + char temp[15]; + Console::puts("Assertion failed at file: "); + Console::puts(_file); + Console::puts(" line: "); + int2str(_line, temp); + Console::puts(temp); + Console::puts(" assertion: "); + Console::puts(_message); + Console::puts("\n"); + abort(); +}/* end _assert */ diff --git a/MP2/MP2_Sources/assert.H b/MP2/MP2_Sources/assert.H new file mode 100755 index 0000000..33c7a16 --- /dev/null +++ b/MP2/MP2_Sources/assert.H @@ -0,0 +1,56 @@ +/* + File: assert.H + + Author: R. Bettati + Department of Computer Science + Texas A&M University + + Date : 05/01/23 + + Header file for the "assert" macro. + + +*/ + +#ifndef __assert_H__ +#define __assert_H__ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "utils.H" + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* CONSTANTS */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* "ASSERT" MACRO */ +/*--------------------------------------------------------------------------*/ + +/* NOTE: The "assert" macros can be turned off by giving the -DNDEBUG + argument when compiling. */ + +#ifdef assert +# undef assert +#endif + +void _assert ( const char* _file, const int _line, const char* _message ); + +#ifdef NDEBUG +# define assert( m ) ( ( void ) 0 ) +#else +# define assert( m ) \ + if ( !(m) ) _assert( __FILE__, __LINE__, #m ); +#endif + +#endif diff --git a/MP2/MP2_Sources/bochsout.txt b/MP2/MP2_Sources/bochsout.txt new file mode 100644 index 0000000..2086560 --- /dev/null +++ b/MP2/MP2_Sources/bochsout.txt @@ -0,0 +1,236 @@ +00000000000i[ ] Bochs x86 Emulator 2.4.6 +00000000000i[ ] Build from CVS snapshot, on February 22, 2011 +00000000000i[ ] Compiled at Nov 11 2011, 09:31:18 +00000000000i[ ] System configuration +00000000000i[ ] processors: 1 (cores=1, HT threads=1) +00000000000i[ ] A20 line support: yes +00000000000i[ ] CPU configuration +00000000000i[ ] level: 6 +00000000000i[ ] SMP support: no +00000000000i[ ] APIC support: yes +00000000000i[ ] FPU support: yes +00000000000i[ ] MMX support: yes +00000000000i[ ] 3dnow! support: no +00000000000i[ ] SEP support: yes +00000000000i[ ] SSE support: sse2 +00000000000i[ ] XSAVE support: no +00000000000i[ ] AES support: no +00000000000i[ ] MOVBE support: no +00000000000i[ ] x86-64 support: yes +00000000000i[ ] 1G paging support: no +00000000000i[ ] VMX support: no +00000000000i[ ] Optimization configuration +00000000000i[ ] RepeatSpeedups support: yes +00000000000i[ ] Trace cache support: yes +00000000000i[ ] Fast function calls: yes +00000000000i[ ] Devices configuration +00000000000i[ ] ACPI support: yes +00000000000i[ ] NE2000 support: yes +00000000000i[ ] PCI support: yes, enabled=yes +00000000000i[ ] SB16 support: yes +00000000000i[ ] USB support: yes +00000000000i[ ] VGA extension support: vbe +00000000000i[MEM0 ] allocated memory at 0x7f3ed8511010. after alignment, vector=0x7f3ed8512000 +00000000000i[MEM0 ] 32.00MB +00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32 +00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('BIOS-bochs-latest') +00000000000i[MEM0 ] rom at 0xc0000/38400 ('VGABIOS-lgpl-latest') +00000000000i[VTIME] using 'realtime pit' synchronization method +00000000000i[ ] lt_dlhandle is 0x3837560 +00000000000i[PLGIN] loaded plugin libbx_cmos.so +00000000000i[ ] lt_dlhandle is 0x3837f80 +00000000000i[PLGIN] loaded plugin libbx_dma.so +00000000000i[ ] lt_dlhandle is 0x38389e0 +00000000000i[PLGIN] loaded plugin libbx_pic.so +00000000000i[ ] lt_dlhandle is 0x3839220 +00000000000i[PLGIN] loaded plugin libbx_pit.so +00000000000i[ ] lt_dlhandle is 0x3839b90 +00000000000i[PLGIN] loaded plugin libbx_vga.so +00000000000i[ ] lt_dlhandle is 0x383a2c0 +00000000000i[PLGIN] loaded plugin libbx_hdimage.so +00000000000i[ ] lt_dlhandle is 0x383ab80 +00000000000i[PLGIN] loaded plugin libbx_floppy.so +00000000000i[ ] lt_dlhandle is 0x383b770 +00000000000i[PLGIN] loaded plugin libbx_soundmod.so +00000000000i[ ] lt_dlhandle is 0x383cdc0 +00000000000i[PLGIN] loaded plugin libbx_pci.so +00000000000i[ ] lt_dlhandle is 0x383d9f0 +00000000000i[PLGIN] loaded plugin libbx_pci2isa.so +00000000000i[ ] lt_dlhandle is 0x383e2d0 +00000000000i[PLGIN] loaded plugin libbx_usb_common.so +00000000000i[ ] lt_dlhandle is 0x383eb30 +00000000000i[PLGIN] loaded plugin libbx_unmapped.so +00000000000i[ ] lt_dlhandle is 0x383f3a0 +00000000000i[PLGIN] loaded plugin libbx_biosdev.so +00000000000i[ ] lt_dlhandle is 0x383fcd0 +00000000000i[PLGIN] loaded plugin libbx_speaker.so +00000000000i[ ] lt_dlhandle is 0x3840500 +00000000000i[PLGIN] loaded plugin libbx_extfpuirq.so +00000000000i[ ] lt_dlhandle is 0x3840d70 +00000000000i[PLGIN] loaded plugin libbx_gameport.so +00000000000i[ ] lt_dlhandle is 0x38416e0 +00000000000i[PLGIN] loaded plugin libbx_pci_ide.so +00000000000i[ ] lt_dlhandle is 0x38420b0 +00000000000i[PLGIN] loaded plugin libbx_acpi.so +00000000000i[ ] lt_dlhandle is 0x38429f0 +00000000000i[PLGIN] loaded plugin libbx_ioapic.so +00000000000i[ ] lt_dlhandle is 0x38433a0 +00000000000i[PLGIN] loaded plugin libbx_keyboard.so +00000000000i[ ] lt_dlhandle is 0x3843ba0 +00000000000i[PLGIN] loaded plugin libbx_harddrv.so +00000000000i[ ] lt_dlhandle is 0x3855c70 +00000000000i[PLGIN] loaded plugin libbx_serial.so +00000000000i[ ] lt_dlhandle is 0x3856ae0 +00000000000i[PLGIN] loaded plugin libbx_parallel.so +00000000000i[CMOS ] Using specified time for initial clock +00000000000i[CMOS ] Setting initial clock to: Fri Dec 31 17:00:00 1999 (time0=946681200) +00000000000i[DMA ] channel 4 used by cascade +00000000000i[DMA ] channel 2 used by Floppy Drive +00000000000i[FDD ] fd0: 'dev_kernel_grub.img' ro=0, h=2,t=80,spt=18 +00000000000i[PCI ] 440FX Host bridge present at device 0, function 0 +00000000000i[PCI ] PIIX3 PCI-to-ISA bridge present at device 1, function 0 +00000000000i[VGA ] interval=50000 +00000000000i[MEM0 ] Register memory access handlers: 0x00000000000a0000 - 0x00000000000bffff +00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried +00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24 +00000000000i[MEM0 ] Register memory access handlers: 0x00000000e0000000 - 0x00000000e0ffffff +00000000000i[VGA ] VBE Bochs Display Extension Enabled +00000000000i[PLGIN] init_dev of 'unmapped' plugin device by virtual method +00000000000i[PLGIN] init_dev of 'biosdev' plugin device by virtual method +00000000000i[PLGIN] init_dev of 'speaker' plugin device by virtual method +00000000000i[SPEAK] Failed to open /dev/console: Resource temporarily unavailable +00000000000i[SPEAK] Deactivating beep on console +00000000000i[PLGIN] init_dev of 'extfpuirq' plugin device by virtual method +00000000000i[PLGIN] init_dev of 'gameport' plugin device by virtual method +00000000000i[PLGIN] init_dev of 'pci_ide' plugin device by virtual method +00000000000i[PCI ] PIIX3 PCI IDE controller present at device 1, function 1 +00000000000i[PLGIN] init_dev of 'acpi' plugin device by virtual method +00000000000i[PCI ] ACPI Controller present at device 1, function 3 +00000000000i[PLGIN] init_dev of 'ioapic' plugin device by virtual method +00000000000i[IOAP ] initializing I/O APIC +00000000000i[MEM0 ] Register memory access handlers: 0x00000000fec00000 - 0x00000000fec00fff +00000000000i[PLGIN] init_dev of 'keyboard' plugin device by virtual method +00000000000i[KBD ] will paste characters every 1000 keyboard ticks +00000000000i[PLGIN] init_dev of 'harddrv' plugin device by virtual method +00000000000i[HD ] Using boot sequence floppy, none, none +00000000000i[HD ] Floppy boot signature check is enabled +00000000000i[PLGIN] init_dev of 'serial' plugin device by virtual method +00000000000i[SER ] com1 at 0x03f8 irq 4 +00000000000i[PLGIN] init_dev of 'parallel' plugin device by virtual method +00000000000i[PAR ] parallel port 1 at 0x0378 irq 7 +00000000000i[PLGIN] register state of 'unmapped' plugin device by virtual method +00000000000i[PLGIN] register state of 'biosdev' plugin device by virtual method +00000000000i[PLGIN] register state of 'speaker' plugin device by virtual method +00000000000i[PLGIN] register state of 'extfpuirq' plugin device by virtual method +00000000000i[PLGIN] register state of 'gameport' plugin device by virtual method +00000000000i[PLGIN] register state of 'pci_ide' plugin device by virtual method +00000000000i[PLGIN] register state of 'acpi' plugin device by virtual method +00000000000i[PLGIN] register state of 'ioapic' plugin device by virtual method +00000000000i[PLGIN] register state of 'keyboard' plugin device by virtual method +00000000000i[PLGIN] register state of 'harddrv' plugin device by virtual method +00000000000i[PLGIN] register state of 'serial' plugin device by virtual method +00000000000i[PLGIN] register state of 'parallel' plugin device by virtual method +00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called +00000000000i[CPU0 ] cpu hardware reset +00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x00000000fee00000 +00000000000i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69 +00000000000i[CPU0 ] CPUID[0x00000001]: 00000f23 00000800 00002000 07cbfbff +00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x00000007]: 00000000 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000001 2a100800 +00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020 +00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75 +00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020 +00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000 +00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000 +00000000000i[CPU0 ] CPUID[0x80000008]: 00003028 00000000 00000000 00000000 +00000000000i[PLGIN] reset of 'unmapped' plugin device by virtual method +00000000000i[PLGIN] reset of 'biosdev' plugin device by virtual method +00000000000i[PLGIN] reset of 'speaker' plugin device by virtual method +00000000000i[PLGIN] reset of 'extfpuirq' plugin device by virtual method +00000000000i[PLGIN] reset of 'gameport' plugin device by virtual method +00000000000i[PLGIN] reset of 'pci_ide' plugin device by virtual method +00000000000i[PLGIN] reset of 'acpi' plugin device by virtual method +00000000000i[PLGIN] reset of 'ioapic' plugin device by virtual method +00000000000i[PLGIN] reset of 'keyboard' plugin device by virtual method +00000000000i[PLGIN] reset of 'harddrv' plugin device by virtual method +00000000000i[PLGIN] reset of 'serial' plugin device by virtual method +00000000000i[PLGIN] reset of 'parallel' plugin device by virtual method +00000000000i[XGUI ] [x] Mouse off +00000003302i[BIOS ] $Revision: 1.209 $ $Date: 2008/06/02 20:08:10 $ +00000318057i[KBD ] reset-disable command received +00000438667i[VBIOS] VGABios $Id: vgabios.c,v 1.67 2008/01/27 09:44:12 vruppert Exp $ +00000438738i[VGA ] VBE known Display Interface b0c0 +00000438770i[VGA ] VBE known Display Interface b0c4 +00000441695i[VBIOS] VBE Bios $Id: vbe.c,v 1.60 2008/03/02 07:47:21 vruppert Exp $ +00000600000i[XGUI ] charmap update. Font Height is 16 +00000764696i[BIOS ] Starting rombios32 +00000765523i[BIOS ] ram_size=0x02000000 +00000776678i[BIOS ] Found 1 cpu(s) +00000792979i[BIOS ] bios_table_addr: 0x000fb778 end=0x000fcc00 +00000793046i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00001251853i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00001711340i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b +00001711387i[P2I ] PCI IRQ routing: PIRQB# set to 0x09 +00001711434i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b +00001711481i[P2I ] PCI IRQ routing: PIRQD# set to 0x09 +00001711497i[P2I ] write: ELCR2 = 0x0a +00001712434i[BIOS ] PIIX3 init: elcr=00 0a +00001732689i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 +00001735926i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 +00001738659i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 +00001739120i[PIDE ] new BM-DMA address: 0xc000 +00001740003i[BIOS ] region 4: 0x0000c000 +00001742579i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 +00001743079i[ACPI ] new irq line = 11 +00001743116i[ACPI ] new PM base address: 0xb000 +00001743178i[ACPI ] new SM base address: 0xb100 +00001743646i[CPU0 ] Enter to System Management Mode +00001743656i[CPU0 ] RSM: Resuming from System Management Mode +00001743690i[PCI ] setting SMRAM control register to 0x4a +00001743972i[PCI ] setting SMRAM control register to 0x0a +00001767253i[BIOS ] MP table addr=0x000fb850 MPC table addr=0x000fb780 size=0xd0 +00001769456i[BIOS ] SMBIOS table addr=0x000fb860 +00001772500i[BIOS ] ACPI tables: RSDP addr=0x000fb970 ACPI DATA addr=0x01ff0000 size=0x9d8 +00001792033i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) +00001793045i[BIOS ] bios_table_cur_addr: 0x000fb994 +00374348939i[BIOS ] Booting from 0000:7c00 +00384200000i[XGUI ] charmap update. Font Height is 16 +00423200000i[XGUI ] charmap update. Font Height is 16 +00430800000i[XGUI ] charmap update. Font Height is 16 +00431000000i[XGUI ] charmap update. Font Height is 16 +00794756000p[XGUI ] >>PANIC<< POWER button turned off. +00794756000i[CPU0 ] CPU is in protected mode (active) +00794756000i[CPU0 ] CS.d_b = 32 bit +00794756000i[CPU0 ] SS.d_b = 32 bit +00794756000i[CPU0 ] EFER = 0x00000000 +00794756000i[CPU0 ] | RAX=0000000000000000 RBX=0000000000026260 +00794756000i[CPU0 ] | RCX=00000000000b8000 RDX=00000000000003d4 +00794756000i[CPU0 ] | RSP=0000000000102f68 RBP=0000000000102f68 +00794756000i[CPU0 ] | RSI=00000000000263d3 RDI=00000000000263df +00794756000i[CPU0 ] | R8=0000000000000000 R9=0000000000000000 +00794756000i[CPU0 ] | R10=0000000000000000 R11=0000000000000000 +00794756000i[CPU0 ] | R12=0000000000000000 R13=0000000000000000 +00794756000i[CPU0 ] | R14=0000000000000000 R15=0000000000000000 +00794756000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf ZF af PF cf +00794756000i[CPU0 ] | SEG selector base limit G D +00794756000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D +00794756000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 +00794756000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00794756000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00794756000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00794756000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00794756000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 +00794756000i[CPU0 ] | MSR_FS_BASE:0000000000000000 +00794756000i[CPU0 ] | MSR_GS_BASE:0000000000000000 +00794756000i[CPU0 ] | RIP=0000000000100033 (0000000000100033) +00794756000i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000 +00794756000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000 +00794756000i[CPU0 ] 0x0000000000100033>> jmp .-2 (0x00100033) : EBFE +00794756000i[CMOS ] Last time is 946681398 (Fri Dec 31 17:03:18 1999) +00794756000i[XGUI ] Exit +00794756000i[ ] restoring default signal behavior +00794756000i[CTRL ] quit_sim called with exit code 1 diff --git a/MP2/MP2_Sources/bochsrc.bxrc b/MP2/MP2_Sources/bochsrc.bxrc new file mode 100755 index 0000000..310979c --- /dev/null +++ b/MP2/MP2_Sources/bochsrc.bxrc @@ -0,0 +1,48 @@ +############################################################### +# bochsrc.txt file for DLX Linux disk image. +############################################################### + +# how much memory the emulated machine will have +megs: 32 + +# filename of ROM images +romimage: file=BIOS-bochs-latest +vgaromimage: file=VGABIOS-lgpl-latest + +# what disk images will be used +floppya: 1_44=dev_kernel_grub.img, status=inserted +#floppyb: 1_44=floppyb.img, status=inserted + +# hard disk +#ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +#ata0-master: type=disk, path="c.img", cylinders=306, heads=4, spt=17 +# choose the boot disk. +boot: floppy + +# default config interface is textconfig. +#config_interface: textconfig +#config_interface: wx + +#display_library: x +# other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga + +# where do we send log messages? +log: bochsout.txt + +# disable the mouse +mouse: enabled=0 + +# enable key mapping, using US layout as default. +# +# NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows. +# However, the key mapping tables are used in the paste function, so +# in the DLX Linux example I'm enabling keyboard_mapping so that paste +# will work. Cut&Paste is currently implemented on win32 and X windows only. + +#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-us.map +#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-fr.map +#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-de.map +#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-es.map + + +clock: sync=realtime, time0=946681200 # Sat Jan 1 00:00:00 2000 \ No newline at end of file diff --git a/MP2/MP2_Sources/console.C b/MP2/MP2_Sources/console.C new file mode 100755 index 0000000..2fc0899 --- /dev/null +++ b/MP2/MP2_Sources/console.C @@ -0,0 +1,213 @@ +/* + File: Console.C + + Author: R. Bettati + Department of Computer Science + Texas A&M University + Date : 09/02/2009 + +*/ + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + +#define CONSOLE_START_ADDRESS (unsigned short *)0xB8000 + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "console.H" + +#include "utils.H" +#include "machine.H" + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* CONSTANTS */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* FORWARDS */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* METHODS FOR CLASS C o n s o l e */ +/*--------------------------------------------------------------------------*/ + +/* -- GLOBAL VARIABLES -- */ + + int Console::attrib; /* background and foreground color */ + int Console::csr_x; /* position of cursor */ + int Console::csr_y; + unsigned short * Console::textmemptr; /* text pointer */ + +/* -- CONSTRUCTOR -- */ + +void Console::init(unsigned char _fore_color, + unsigned char _back_color) { + set_TextColor(_fore_color, _back_color); + csr_x = 0; + csr_y = 0; + textmemptr = CONSOLE_START_ADDRESS; + cls(); +} + + +void Console::scroll() { + + /* A blank is defined as a space... we need to give it + * backcolor too */ + unsigned blank = 0x20 | (attrib << 8); + + /* Row 25 is the end, this means we need to scroll up */ + if(csr_y >= 25) + { + /* Move the current text chunk that makes up the screen + * back in the buffer by a line */ + unsigned temp = csr_y - 25 + 1; + memcpy ((char*)textmemptr, (char*)(textmemptr + temp * 80), (25 - temp) * 80 * 2); + + /* Finally, we set the chunk of memory that occupies + * the last line of text to our 'blank' character */ + memsetw (textmemptr + (25 - temp) * 80, blank, 80); + csr_y = 25 - 1; + } +} + + +void Console::move_cursor() { + + /* The equation for finding the index in a linear + * chunk of memory can be represented by: + * Index = [(y * width) + x] */ + unsigned temp = csr_y * 80 + csr_x; + + /* This sends a command to indicies 14 and 15 in the + * Console Control Register of the VGA controller. These + * are the high and low bytes of the index that show + * where the hardware cursor is to be 'blinking'. To + * learn more, you should look up some VGA specific + * programming documents. A great start to graphics: + * http://www.brackeen.com/home/vga */ + Machine::outportb(0x3D4, (char)14); + //outportb(0x3D5, temp >> 8); + Machine::outportb(0x3D4, 15); + //outportb(0x3D5, (char)temp); +} + +/* Clear the screen */ +void Console::cls() { + + /* Again, we need the 'short' that will be used to + * represent a space with color */ + unsigned blank = 0x20 | (attrib << 8); + + /* Sets the entire screen to spaces in our current + * color */ + for(int i = 0; i < 25; i++) + memsetw (textmemptr + i * 80, blank, 80); + + /* Update out virtual cursor, and then move the + * hardware cursor */ + csr_x = 0; + csr_y = 0; + move_cursor(); +} + +/* Puts a single character on the screen */ +void Console::putch(const char _c){ + + + /* Handle a backspace, by moving the cursor back one space */ + if(_c == 0x08) + { + if(csr_x != 0) csr_x--; + } + /* Handles a tab by incrementing the cursor's x, but only + * to a point that will make it divisible by 8 */ + else if(_c == 0x09) + { + csr_x = (csr_x + 8) & ~(8 - 1); + } + /* Handles a 'Carriage Return', which simply brings the + * cursor back to the margin */ + else if(_c == '\r') + { + csr_x = 0; + } + /* We handle our newlines the way DOS and the BIOS do: we + * treat it as if a 'CR' was also there, so we bring the + * cursor to the margin and we increment the 'y' value */ + else if(_c == '\n') + { + csr_x = 0; + csr_y++; + } + /* Any character greater than and including a space, is a + * printable character. The equation for finding the index + * in a linear chunk of memory can be represented by: + * Index = [(y * width) + x] */ + else if(_c >= ' ') + { + unsigned short * where = textmemptr + (csr_y * 80 + csr_x); + *where = _c | (attrib << 8); /* Character AND attributes: color */ + csr_x++; + } + + /* If the cursor has reached the edge of the screen's width, we + * insert a new line in there */ + if(csr_x >= 80) + { + csr_x = 0; + csr_y++; + } + + /* Scroll the screen if needed, and finally move the cursor */ + scroll(); + move_cursor(); +} + +/* Uses the above routine to output a string... */ +void Console::puts(const char * _s) { + + for (int i = 0; i < strlen(_s); i++) { + putch(_s[i]); + } +} + +void Console::puti(const int _n) { + char foostr[15]; + + int2str(_n, foostr); + puts(foostr); +} + +void Console::putui(const unsigned int _n) { + char foostr[15]; + + uint2str(_n, foostr); + putch('<'); + puts(foostr); + putch('>'); +} + + +/* -- COLOR CONTROL -- */ +void Console::set_TextColor(const unsigned char _forecolor, + const unsigned char _backcolor) { + /* Top 4 bytes are the background, bottom 4 bytes + * are the foreground color */ + attrib = (_backcolor << 4) | (_forecolor & 0x0F); +} + diff --git a/MP2/MP2_Sources/console.H b/MP2/MP2_Sources/console.H new file mode 100755 index 0000000..aa24fda --- /dev/null +++ b/MP2/MP2_Sources/console.H @@ -0,0 +1,113 @@ +/* + File: Console.H + + Author : R. Bettati + Department of Computer Science + Texas A&M University + Date : 09/02/12 + + The class Console encapsulates the output operations ot the console + screen. Since the console is initialized at the very beginning of the + boot-up of the operating system, when no memory management is available + yet, all functions and storage for the console are static. + + The console is initialized with an "init" function instead of a + constructor. (We don't want to deal with constructors that are called + before the "main()" function.) + + By making all functions static, we can access them across all object + files without having to declare a global Console object or pass pointers + to a locally declared object. + +*/ + +#ifndef _Console_H_ // include file only once +#define _Console_H_ + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none -- */ + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + +typedef enum { + BLACK = 0, + BLUE = 1, + GREEN = 2, + CYAN = 3, + RED = 4, + MAGENTA = 5, + BROWN = 6, + LIGHT_GREY = 7, + DARK_GREY = 8, + LIGHT_BLUE = 9, + LIGHT_GREEN = 10, + LIGHT_CYAN = 11, + LIGHT_RED = 12, + LIGHT_MAGENTA = 13, + LIGHT_BROWN = 14, + WHITE = 15 +} COLOR_CODE; + + +/*--------------------------------------------------------------------------*/ +/* FORWARDS */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* CLASS C o n s o l e */ +/*--------------------------------------------------------------------------*/ + +class Console { +private: + static int attrib; /* background and foreground color */ + static int csr_x; /* position of cursor */ + static int csr_y; + static unsigned short * textmemptr; /* text pointer */ +public: + + /* -- INITIALIZER (we have no constructor, there is no memory mgmt yet.) */ + static void init(unsigned char _fore_color = WHITE, + unsigned char _back_color = BLACK); + + static void scroll(); + + static void move_cursor(); + /* Update the hardware cursor. */ + + static void cls(); + /* Clear the screen. */ + + static void putch(const char _c); + /* Put a single character on the screen. */ + + static void puts(const char * _s); + /* Display a NULL-terminated string on the screen.*/ + + static void puti(const int _i); + /* Display a integer on the screen.*/ + + static void putui(const unsigned int _u); + /* Display a unsigned integer on the screen.*/ + + static void set_TextColor(unsigned char _fore_color, unsigned char _back_color); + /* Set the color of the foreground and background. */ + +}; + + +#endif + + diff --git a/MP2/MP2_Sources/cont_frame_pool.C b/MP2/MP2_Sources/cont_frame_pool.C new file mode 100644 index 0000000..6ded45a --- /dev/null +++ b/MP2/MP2_Sources/cont_frame_pool.C @@ -0,0 +1,162 @@ +/* + File: ContFramePool.C + + Author: + Date : + + */ + +/*--------------------------------------------------------------------------*/ +/* + POSSIBLE IMPLEMENTATION + ----------------------- + + The class SimpleFramePool in file "simple_frame_pool.H/C" describes an + incomplete vanilla implementation of a frame pool that allocates + *single* frames at a time. Because it does allocate one frame at a time, + it does not guarantee that a sequence of frames is allocated contiguously. + This can cause problems. + + The class ContFramePool has the ability to allocate either single frames, + or sequences of contiguous frames. This affects how we manage the + free frames. In SimpleFramePool it is sufficient to maintain the free + frames. + In ContFramePool we need to maintain free *sequences* of frames. + + This can be done in many ways, ranging from extensions to bitmaps to + free-lists of frames etc. + + IMPLEMENTATION: + + One simple way to manage sequences of free frames is to add a minor + extension to the bitmap idea of SimpleFramePool: Instead of maintaining + whether a frame is FREE or ALLOCATED, which requires one bit per frame, + we maintain whether the frame is FREE, or ALLOCATED, or HEAD-OF-SEQUENCE. + The meaning of FREE is the same as in SimpleFramePool. + If a frame is marked as HEAD-OF-SEQUENCE, this means that it is allocated + and that it is the first such frame in a sequence of frames. Allocated + frames that are not first in a sequence are marked as ALLOCATED. + + NOTE: If we use this scheme to allocate only single frames, then all + frames are marked as either FREE or HEAD-OF-SEQUENCE. + + NOTE: In SimpleFramePool we needed only one bit to store the state of + each frame. Now we need two bits. In a first implementation you can choose + to use one char per frame. This will allow you to check for a given status + without having to do bit manipulations. Once you get this to work, + revisit the implementation and change it to using two bits. You will get + an efficiency penalty if you use one char (i.e., 8 bits) per frame when + two bits do the trick. + + DETAILED IMPLEMENTATION: + + How can we use the HEAD-OF-SEQUENCE state to implement a contiguous + allocator? Let's look a the individual functions: + + Constructor: Initialize all frames to FREE, except for any frames that you + need for the management of the frame pool, if any. + + get_frames(_n_frames): Traverse the "bitmap" of states and look for a + sequence of at least _n_frames entries that are FREE. If you find one, + mark the first one as HEAD-OF-SEQUENCE and the remaining _n_frames-1 as + ALLOCATED. + + release_frames(_first_frame_no): Check whether the first frame is marked as + HEAD-OF-SEQUENCE. If not, something went wrong. If it is, mark it as FREE. + Traverse the subsequent frames until you reach one that is FREE or + HEAD-OF-SEQUENCE. Until then, mark the frames that you traverse as FREE. + + mark_inaccessible(_base_frame_no, _n_frames): This is no different than + get_frames, without having to search for the free sequence. You tell the + allocator exactly which frame to mark as HEAD-OF-SEQUENCE and how many + frames after that to mark as ALLOCATED. + + needed_info_frames(_n_frames): This depends on how many bits you need + to store the state of each frame. If you use a char to represent the state + of a frame, then you need one info frame for each FRAME_SIZE frames. + + A WORD ABOUT RELEASE_FRAMES(): + + When we releae a frame, we only know its frame number. At the time + of a frame's release, we don't know necessarily which pool it came + from. Therefore, the function "release_frame" is static, i.e., + not associated with a particular frame pool. + + This problem is related to the lack of a so-called "placement delete" in + C++. For a discussion of this see Stroustrup's FAQ: + http://www.stroustrup.com/bs_faq2.html#placement-delete + + */ +/*--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "cont_frame_pool.H" +#include "console.H" +#include "utils.H" +#include "assert.H" + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* CONSTANTS */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* FORWARDS */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* METHODS FOR CLASS C o n t F r a m e P o o l */ +/*--------------------------------------------------------------------------*/ + +ContFramePool::ContFramePool(unsigned long _base_frame_no, + unsigned long _n_frames, + unsigned long _info_frame_no, + unsigned long _n_info_frames) +{ + // TODO: IMPLEMENTATION NEEEDED! + assert(false); +} + +unsigned long ContFramePool::get_frames(unsigned int _n_frames) +{ + // TODO: IMPLEMENTATION NEEEDED! + assert(false); +} + +void ContFramePool::mark_inaccessible(unsigned long _base_frame_no, + unsigned long _n_frames) +{ + // TODO: IMPLEMENTATION NEEEDED! + assert(false); +} + +void ContFramePool::release_frames(unsigned long _first_frame_no) +{ + // TODO: IMPLEMENTATION NEEEDED! + assert(false); +} + +unsigned long ContFramePool::needed_info_frames(unsigned long _n_frames) +{ + // TODO: IMPLEMENTATION NEEEDED! + assert(false); +} diff --git a/MP2/MP2_Sources/cont_frame_pool.H b/MP2/MP2_Sources/cont_frame_pool.H new file mode 100755 index 0000000..115964c --- /dev/null +++ b/MP2/MP2_Sources/cont_frame_pool.H @@ -0,0 +1,119 @@ +/* + File: cont_frame_pool.H + + Author: R. Bettati + Department of Computer Science + Texas A&M University + Date : 17/02/04 + + Description: Management of the CONTIGUOUS Free-Frame Pool. + + As opposed to a non-contiguous free-frame pool, here we can allocate + a sequence of CONTIGUOUS frames. + + */ + +#ifndef _CONT_FRAME_POOL_H_ // include file only once +#define _CONT_FRAME_POOL_H_ + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "machine.H" + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* C o n t F r a m e P o o l */ +/*--------------------------------------------------------------------------*/ + +class ContFramePool { + +private: + /* -- DEFINE YOUR CONT FRAME POOL DATA STRUCTURE(s) HERE. */ + +public: + + // The frame size is the same as the page size, duh... + static const unsigned int FRAME_SIZE = Machine::PAGE_SIZE; + + ContFramePool(unsigned long _base_frame_no, + unsigned long _n_frames, + unsigned long _info_frame_no, + unsigned long _n_info_frames); + /* + Initializes the data structures needed for the management of this + frame pool. + _base_frame_no: Number of first frame managed by this frame pool. + _n_frames: Size, in frames, of this frame pool. + EXAMPLE: If _base_frame_no is 16 and _n_frames is 4, this frame pool manages + physical frames numbered 16, 17, 18 and 19. + _info_frame_no: Number of the first frame that should be used to store the + management information for the frame pool. + NOTE: If _info_frame_no is 0, the frame pool is free to + choose any frames from the pool to store management information. + _n_info_frames: If _info_frame_no is 0, this argument specifies the + number of consecutive frames needed to store the management information + for the frame pool. + EXAMPLE: If _info_frame_no is 699 and _n_info_frames is 3, + then Frames 699, 700, and 701 are used to store the management information + for the frame pool. + NOTE: This function must be called before the paging system + is initialized. + */ + + unsigned long get_frames(unsigned int _n_frames); + /* + Allocates a number of contiguous frames from the frame pool. + _n_frames: Size of contiguous physical memory to allocate, + in number of frames. + If successful, returns the frame number of the first frame. + If fails, returns 0. + */ + + void mark_inaccessible(unsigned long _base_frame_no, + unsigned long _n_frames); + /* + Marks a contiguous area of physical memory, i.e., a contiguous + sequence of frames, as inaccessible. + _base_frame_no: Number of first frame to mark as inaccessible. + _n_frames: Number of contiguous frames to mark as inaccessible. + */ + + static void release_frames(unsigned long _first_frame_no); + /* + Releases a previously allocated contiguous sequence of frames + back to its frame pool. + The frame sequence is identified by the number of the first frame. + NOTE: This function is static because there may be more than one frame pool + defined in the system, and it is unclear which one this frame belongs to. + This function must first identify the correct frame pool and then call the frame + pool's release_frame function. + */ + + static unsigned long needed_info_frames(unsigned long _n_frames); + /* + Returns the number of frames needed to manage a frame pool of size _n_frames. + The number returned here depends on the implementation of the frame pool and + on the frame size. + EXAMPLE: For FRAME_SIZE = 4096 and a bitmap with a single bit per frame + (not appropriate for contiguous allocation) one would need one frame to manage a + frame pool with up to 8 * 4096 = 32k frames = 128MB of memory! + This function would therefore return the following value: + _n_frames / 32k + (_n_frames % 32k > 0 ? 1 : 0) (always round up!) + Other implementations need a different number of info frames. + The exact number is computed in this function.. + */ +}; +#endif diff --git a/MP2/MP2_Sources/copykernel.sh b/MP2/MP2_Sources/copykernel.sh new file mode 100755 index 0000000..afd49c3 --- /dev/null +++ b/MP2/MP2_Sources/copykernel.sh @@ -0,0 +1,5 @@ +# Replace "/mnt/floppy" with the whatever directory is appropriate. +sudo mount -o loop dev_kernel_grub.img /mnt/floppy +sudo cp kernel.bin /mnt/floppy +sleep 1s +sudo umount /mnt/floppy diff --git a/MP2/MP2_Sources/dev_kernel_grub.img b/MP2/MP2_Sources/dev_kernel_grub.img new file mode 100755 index 0000000..e548c4d Binary files /dev/null and b/MP2/MP2_Sources/dev_kernel_grub.img differ diff --git a/MP2/MP2_Sources/kernel.C b/MP2/MP2_Sources/kernel.C new file mode 100755 index 0000000..6b4e301 --- /dev/null +++ b/MP2/MP2_Sources/kernel.C @@ -0,0 +1,133 @@ +/* + File: kernel.C + + Author: R. Bettati + Department of Computer Science + Texas A&M University + Date : 02/02/17 + + + This file has the main entry point to the operating system. + +*/ + + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + +#define MB * (0x1 << 20) +#define KB * (0x1 << 10) +/* Makes things easy to read */ + +#define KERNEL_POOL_START_FRAME ((2 MB) / (4 KB)) +#define KERNEL_POOL_SIZE ((2 MB) / (4 KB)) +#define PROCESS_POOL_START_FRAME ((4 MB) / (4 KB)) +#define PROCESS_POOL_SIZE ((28 MB) / (4 KB)) +/* Definition of the kernel and process memory pools */ + +#define MEM_HOLE_START_FRAME ((15 MB) / (4 KB)) +#define MEM_HOLE_SIZE ((1 MB) / (4 KB)) +/* We have a 1 MB hole in physical memory starting at address 15 MB */ + +#define TEST_START_ADDR_PROC (4 MB) +#define TEST_START_ADDR_KERNEL (2 MB) +/* Used in the memory test below to generate sequences of memory references. */ +/* One is for a sequence of memory references in the kernel space, and the */ +/* other for memory references in the process space. */ + +#define N_TEST_ALLOCATIONS +/* Number of recursive allocations that we use to test. */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "machine.H" /* LOW-LEVEL STUFF */ +#include "console.H" + +#include "assert.H" +#include "cont_frame_pool.H" /* The physical memory manager */ + +/*--------------------------------------------------------------------------*/ +/* FORWARDS */ +/*--------------------------------------------------------------------------*/ + +void test_memory(ContFramePool * _pool, unsigned int _allocs_to_go); + +/*--------------------------------------------------------------------------*/ +/* MAIN ENTRY INTO THE OS */ +/*--------------------------------------------------------------------------*/ + +int main() { + + Console::init(); + + /* -- INITIALIZE FRAME POOLS -- */ + + /* ---- KERNEL POOL -- */ + + ContFramePool kernel_mem_pool(KERNEL_POOL_START_FRAME, + KERNEL_POOL_SIZE, + 0, + 0); + + + /* ---- PROCESS POOL -- */ + +/* + unsigned long n_info_frames = ContFramePool::needed_info_frames(PROCESS_POOL_SIZE); + + unsigned long process_mem_pool_info_frame = kernel_mem_pool.get_frames(n_info_frames); + + ContFramePool process_mem_pool(PROCESS_POOL_START_FRAME, + PROCESS_POOL_SIZE, + process_mem_pool_info_frame, + n_info_frames); + + process_mem_pool.mark_inaccessible(MEM_HOLE_START_FRAME, MEM_HOLE_SIZE); +*/ + /* -- MOST OF WHAT WE NEED IS SETUP. THE KERNEL CAN START. */ + + Console::puts("Hello World!\n"); + + /* -- TEST MEMORY ALLOCATOR */ + + test_memory(&kernel_mem_pool, 32); + + /* ---- Add code here to test the frame pool implementation. */ + + /* -- NOW LOOP FOREVER */ + Console::puts("Testing is DONE. We will do nothing forever\n"); + Console::puts("Feel free to turn off the machine now.\n"); + + for(;;); + + /* -- WE DO THE FOLLOWING TO KEEP THE COMPILER HAPPY. */ + return 1; +} + +void test_memory(ContFramePool * _pool, unsigned int _allocs_to_go) { + Console::puts("alloc_to_go = "); Console::puti(_allocs_to_go); Console::puts("\n"); + if (_allocs_to_go > 0) { + int n_frames = _allocs_to_go % 4 + 1; + unsigned long frame = _pool->get_frames(n_frames); + int * value_array = (int*)(frame * (4 KB)); + for (int i = 0; i < (1 KB) * n_frames; i++) { + value_array[i] = _allocs_to_go; + } + test_memory(_pool, _allocs_to_go - 1); + for (int i = 0; i < (1 KB) * n_frames; i++) { + if(value_array[i] != _allocs_to_go){ + Console::puts("MEMORY TEST FAILED. ERROR IN FRAME POOL\n"); + Console::puts("i ="); Console::puti(i); + Console::puts(" v = "); Console::puti(value_array[i]); + Console::puts(" n ="); Console::puti(_allocs_to_go); + Console::puts("\n"); + for(;;); + } + } + ContFramePool::release_frames(frame); + } +} + diff --git a/MP2/MP2_Sources/linker.ld b/MP2/MP2_Sources/linker.ld new file mode 100755 index 0000000..fbb9a12 --- /dev/null +++ b/MP2/MP2_Sources/linker.ld @@ -0,0 +1,36 @@ +OUTPUT_FORMAT("binary") +ENTRY(start) +phys = 0x00100000; +SECTIONS +{ + .text phys : AT(phys) { + code = .; + *(.text) + *(.gnu.linkonce.t.*) + *(.gnu.linkonce.r.*) + *(.rodata) + . = ALIGN(4096); + } + .data : AT(phys + (data - code)) + { + data = .; + *(.data) + start_ctors = .; + *(.ctor*) + end_ctors = .; + start_dtors = .; + *(.dtor*) + end_dtors = .; + *(.gnu.linkonce.d.*) + . = ALIGN(4096); + } + .bss : AT(phys + (bss - code)) + { + bss = .; + *(.bss) + *(.gnu.linkonce.b.*) + . = ALIGN(4096); + } + end = .; +} + diff --git a/MP2/MP2_Sources/machine.C b/MP2/MP2_Sources/machine.C new file mode 100755 index 0000000..2d756a7 --- /dev/null +++ b/MP2/MP2_Sources/machine.C @@ -0,0 +1,70 @@ +/* + File: machine.C + + Author: R. Bettati + Department of Computer Science + Texas A&M University + Date : 12/09/04 + + LOW-LEVEL MACHINE FUNCTIONS. + +*/ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "machine.H" +#include "machine_low.H" + +#include "assert.H" + +/*--------------------------------------------------------------------------*/ +/* INTERRUPTS */ +/*--------------------------------------------------------------------------*/ + +bool Machine::interrupts_enabled() { + /* We check the IF flag (INTERRUPT ENABLE) in the EFLAGS status register. */ + return get_EFLAGS() & (1 << 9); +} + +void Machine::enable_interrupts() { + assert(!interrupts_enabled()); + __asm__ __volatile__ ("sti"); +} + +void Machine::disable_interrupts() { + assert(interrupts_enabled()); + __asm__ __volatile__ ("cli"); +} + +/*--------------------------------------------------------------------------*/ +/* PORT I/O OPERATIONS */ +/*--------------------------------------------------------------------------*/ + +/* We will use this later on for reading from the I/O ports to get data +* from devices such as the keyboard. We are using what is called +* 'inline assembly' in these routines to actually do the work */ +char Machine::inportb (unsigned short _port) { + unsigned char rv; + __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} + +unsigned short Machine::inportw (unsigned short _port) { + unsigned short rv; + __asm__ __volatile__ ("inw %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} + +/* We will use this to write to I/O ports to send bytes to devices. This +* will be used in the next tutorial for changing the textmode cursor +* position. Again, we use some inline assembly for the stuff that simply +* cannot be done in C */ +void Machine::outportb (unsigned short _port, char _data) { + __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} + +void Machine::outportw (unsigned short _port, unsigned short _data) { + __asm__ __volatile__ ("outw %1, %0" : : "dN" (_port), "a" (_data)); +} diff --git a/MP2/MP2_Sources/machine.H b/MP2/MP2_Sources/machine.H new file mode 100755 index 0000000..68eb6df --- /dev/null +++ b/MP2/MP2_Sources/machine.H @@ -0,0 +1,123 @@ +/* + File: machine.H + + Author: R. Bettati + Department of Computer Science + Texas A&M University + Date : 12/09/05 + + Description: Low-level definitions for x86 architecture. + + - Register context + - Data and code segment for kernel. + - Interrupt enable/disable. + +*/ + +#ifndef _machine_H_ // include file only once +#define _machine_H_ + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + +/* REGISTER CONTEXT ON THE STACK WHEN EXCEPTION/INTERRUPT REACHES EXCEPTION + DISPATCHER OR INTERRUPT DISPATCHER. + THIS IS ALSO USED IN THREAD SCHEDULING (for context switching) */ +typedef struct regs { + + /* segment descriptors */ + unsigned int gs; + unsigned int fs; + unsigned int es; + unsigned int ds; + + /* General purpose registers, managed by pusha/popa in x86. */ + unsigned int edi; + unsigned int esi; + unsigned int ebp; + unsigned int esp; + unsigned int ebx; + unsigned int edx; + unsigned int ecx; + unsigned int eax; + + /* In the low-level handlers (i.e. before we call the + exception or interrupt dispatcher) we push number + of the interrupt and error code onto the stack. */ + unsigned int int_no; + unsigned int err_code; + + /* These registers are pushed on the stack when + the exception occurs. */ + unsigned int eip; + unsigned int cs; + unsigned int eflags; + + /* These registers are pushed on the stack only when + the exception occured in user mode. + As long as you are in kernel mode, the register context + is 68 bytes long, and not 76! */ + unsigned int useresp; + unsigned int ss; +} REGS; + + +/*--------------------------------------------------------------------------*/ +/* CLASS M a c h i n e */ +/*--------------------------------------------------------------------------*/ + +class Machine { + +public: + +/*---------------------------------------------------------------*/ +/* MEMORY MANAGEMENT */ +/*---------------------------------------------------------------*/ + + static const unsigned int PAGE_SIZE = 4096; + static const unsigned int PT_ENTRIES_PER_PAGE = 1024; + +/*---------------------------------------------------------------*/ +/* INTERRUPTS */ +/*---------------------------------------------------------------*/ + + /* + This is done by checking the Interrupt Enabled flag in the + EFLAG status register and by issuing STI/CLI instructions. + (NOTE: If we have multiple threads, each has its own status register.) + */ + + static bool interrupts_enabled(); + /* Returns whether interrupts are enabled. */ + + static void enable_interrupts(); + static void disable_interrupts(); + /* Issue CLI/STI instructions. */ + +/*---------------------------------------------------------------*/ +/* PORT I/O OPERATIONS */ +/*---------------------------------------------------------------*/ + + static char inportb (unsigned short _port); + static unsigned short inportw (unsigned short _port); + /* Read data from input port _port.*/ + + static void outportb (unsigned short _port, char _data); + static void outportw (unsigned short _port, unsigned short _data); + /* Write _data to output port _port.*/ + +}; +#endif diff --git a/MP2/MP2_Sources/machine_low.H b/MP2/MP2_Sources/machine_low.H new file mode 100755 index 0000000..ff58008 --- /dev/null +++ b/MP2/MP2_Sources/machine_low.H @@ -0,0 +1,31 @@ +/* + File: machine_low.H + + Author: R. Bettati + Department of Computer Science + Texas A&M University + Date : 12/09/03 + + + Low-level CPU operations. + +*/ + +#ifndef _machine_low_H_ // include file only once +#define _machine_low_H_ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + + /* (none) */ + +/*--------------------------------------------------------------------------*/ +/* LOW-LEVER CPU OPERATIONS */ +/*--------------------------------------------------------------------------*/ + +extern "C" unsigned long get_EFLAGS(); +/* Return value of the EFLAGS status register. */ + +#endif + diff --git a/MP2/MP2_Sources/machine_low.asm b/MP2/MP2_Sources/machine_low.asm new file mode 100755 index 0000000..1d0998e --- /dev/null +++ b/MP2/MP2_Sources/machine_low.asm @@ -0,0 +1,18 @@ +; File: machine_low.asm +; +; Low level CPU handling functions. +; +; September 3, 2012 + +; ---------------------------------------------------------------------- +; get_EFLAGS() +; +; Returns value of the EFLAGS status register. +; +; ---------------------------------------------------------------------- +global _get_EFLAGS +; this function is exported. +_get_EFLAGS: + pushfd ; push eflags + pop eax ; pop contents into eax + ret \ No newline at end of file diff --git a/MP2/MP2_Sources/makefile b/MP2/MP2_Sources/makefile new file mode 100755 index 0000000..de8f872 --- /dev/null +++ b/MP2/MP2_Sources/makefile @@ -0,0 +1,47 @@ +CPP = gcc +CPP_OPTIONS = -m32 -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector -fleading-underscore -fno-asynchronous-unwind-tables + +all: kernel.bin + +clean: + rm -f *.o *.bin + +start.o: start.asm + nasm -f aout -o start.o start.asm + +utils.o: utils.C utils.H + $(CPP) $(CPP_OPTIONS) -c -o utils.o utils.C + +assert.o: assert.C assert.H + $(CPP) $(CPP_OPTIONS) -c -o assert.o assert.C + + +# ==== VARIOUS LOW-LEVEL STUFF ===== + +machine.o: machine.C machine.H + $(CPP) $(CPP_OPTIONS) -c -o machine.o machine.C + +machine_low.o: machine_low.asm machine_low.H + nasm -f aout -o machine_low.o machine_low.asm + +# ==== DEVICES ===== + +console.o: console.C console.H + $(CPP) $(CPP_OPTIONS) -c -o console.o console.C + +# ==== MEMORY ===== + +cont_frame_pool.o: cont_frame_pool.C cont_frame_pool.H + $(CPP) $(CPP_OPTIONS) -c -o cont_frame_pool.o cont_frame_pool.C + +# ==== KERNEL MAIN FILE ===== + +kernel.o: kernel.C console.H + $(CPP) $(CPP_OPTIONS) -c -o kernel.o kernel.C + + +kernel.bin: start.o utils.o kernel.o assert.o console.o \ + cont_frame_pool.o machine.o machine_low.o + ld -melf_i386 -T linker.ld -o kernel.bin start.o utils.o \ + kernel.o assert.o console.o \ + cont_frame_pool.o machine.o machine_low.o diff --git a/MP2/MP2_Sources/simple_frame_pool.C b/MP2/MP2_Sources/simple_frame_pool.C new file mode 100644 index 0000000..711aa34 --- /dev/null +++ b/MP2/MP2_Sources/simple_frame_pool.C @@ -0,0 +1,127 @@ +#include "simple_frame_pool.H" +#include "console.H" +#include "utils.H" +#include "assert.H" + +SimpleFramePool::SimpleFramePool(unsigned long _base_frame_no, + unsigned long _nframes, + unsigned long _info_frame_no) +{ + // Bitmap must fit in a single frame! + assert(_nframes <= FRAME_SIZE * 8); + + base_frame_no = _base_frame_no; + nframes = _nframes; + nFreeFrames = _nframes; + info_frame_no = _info_frame_no; + + // If _info_frame_no is zero then we keep management info in the first + //frame, else we use the provided frame to keep management info + if(info_frame_no == 0) { + bitmap = (unsigned char *) (base_frame_no * FRAME_SIZE); + } else { + bitmap = (unsigned char *) (info_frame_no * FRAME_SIZE); + } + + // Number of frames must be "fill" the bitmap! + assert ((nframes % 8 ) == 0); + + + // Everything ok. Proceed to mark all bits in the bitmap + for(int i=0; i*8 < _nframes; i++) { + bitmap[i] = 0xFF; + } + + // Mark the first frame as being used if it is being used + if(_info_frame_no == 0) { + bitmap[0] = 0x7F; + nFreeFrames--; + } + + Console::puts("Frame Pool initialized\n"); +} + +unsigned long SimpleFramePool::get_frame() +{ + + // Any frames left to allocate? + assert(nFreeFrames > 0); + + // Find a frame that is not being used and return its frame index. + // Mark that frame as being used in the bitmap. + unsigned int frame_no = base_frame_no; + + unsigned int i = 0; + while (bitmap[i] == 0x0) { + i++; + } + + frame_no += i * 8; + + unsigned char mask = 0x80; + while ((mask & bitmap[i]) == 0) { + mask = mask >> 1; + frame_no++; + } + nFreeFrames--; + + // Update bitmap + bitmap[i] = bitmap[i] ^ mask; + + return (frame_no); +} + +void SimpleFramePool::mark_inaccessible(unsigned long _base_frame_no, + unsigned long _nframes) +{ + // Mark all frames in the range as being used. + int i ; + for(i = _base_frame_no; i < _base_frame_no + _nframes; i++){ + mark_inaccessible(i); + } + nFreeFrames -= _nframes; +} + +void SimpleFramePool::mark_inaccessible(unsigned long _frame_no) +{ + // Let's first do a range check. + assert ((_frame_no >= base_frame_no) && (_frame_no < base_frame_no + nframes)); + + unsigned int bitmap_index = (_frame_no - base_frame_no) / 8; + unsigned char mask = 0x80 >> ((_frame_no - base_frame_no) % 8); + + // Is the frame being used already? + assert((bitmap[bitmap_index] & mask) != 0); + + // Update bitmap + bitmap[bitmap_index] ^= mask; + nFreeFrames--; +} + +void SimpleFramePool::release_frame(unsigned long _frame_no) +{ + // -- WE LEAVE THE IMPLEMENTATION OF THIS FUNCTION TO YOU. + // NOTE: Keep in mind that you first need to identify the correct frame pool. + // The function is static, and you are only given a frame number. You do have + // to figure out which frame pool this frame belongs to before you can call the + // frame-pool-specific release_frame function. + + +#ifdef JUST_AS_EXAMPLE + // Inside the frame-pool specific release_frame function we mark the frame + // as released as follows: + + unsigned int bitmap_index = (_frame_no - base_frame_no) / 8; + unsigned char mask = 0x80 >> ((_frame_no - base_frame_no) % 8); + + if((bitmap[bitmap_index] & mask) != 0) { + Console::puts("Error, Frame being released is not being used\n"); + assert(false); + } + + bitmap[bitmap_index] ^= mask; + + nFreeFrames++; +#endif +} + diff --git a/MP2/MP2_Sources/simple_frame_pool.H b/MP2/MP2_Sources/simple_frame_pool.H new file mode 100755 index 0000000..8c95908 --- /dev/null +++ b/MP2/MP2_Sources/simple_frame_pool.H @@ -0,0 +1,108 @@ +/* + File: simple_frame_pool.H + + Author: R. Bettati + Department of Computer Science + Texas A&M University + Date : 12/09/03 + + Description: Management of the non-contiguous Free-Frame Pool. + + +*/ + +#ifndef _FRAME_POOL_H_ // include file only once +#define _FRAME_POOL_H_ + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "machine.H" + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + +/* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* S i m p l e F r a m e P o o l */ +/*--------------------------------------------------------------------------*/ + +class SimpleFramePool { + +private: + /* -- DEFINE YOUR FRAME POOL DATA STRUCTURE(s) HERE. */ + + + unsigned char * bitmap; // We implement the simple frame pool with a bitmap + unsigned int nFreeFrames; // + unsigned long base_frame_no; // Where does the frame pool start in phys mem? + unsigned long nframes; // Size of the frame pool + unsigned long info_frame_no; // Where do we store the management information? + + void mark_inaccessible(unsigned long _frame_no); + +public: + + static const unsigned int FRAME_SIZE = Machine::PAGE_SIZE; + + SimpleFramePool(unsigned long _base_frame_no, + unsigned long _nframes, + unsigned long _info_frame_no); + /* Initializes the data structures needed for the management of this + frame pool. This function must be called before the paging system + is initialized. + _base_frame_no is the frame number at the start of the physical memory + region that this frame pool manages. + _nframes is the number of frames in the physical memory region that this + frame pool manages. + e.g. If _base_frame_no is 16 and _nframes is 4, this frame pool manages + physical frames numbered 16, 17, 18 and 19 + _info_frame_no is the frame number (within the directly mapped region) of + the frame that should be used to store the management information of the + frame pool. However, if _info_frame_no is 0, the frame pool is free to + choose any frame from the pool to store management information. + */ + + unsigned long get_frame(); + /* Allocates a frame from the frame pool. If successful, returns the frame + * number of the frame. If fails, returns 0. */ + + void mark_inaccessible(unsigned long _base_frame_no, + unsigned long _nframes); + /* Mark the area of physical memory as inaccessible. The arguments have the + * same semanticas as in the constructor. + */ + + static void release_frame(unsigned long _frame_no); + /* Releases frame back to the given frame pool. + The frame is identified by the frame number. + NOTE: This function is static because there may be more than one frame pool + defined in the system, and it is unclear which one this frame belongs to. + This function must first identify the correct frame pool and then call the frame + pool's release_frame function. */ + + static unsigned long needed_info_frames(unsigned long _n_frames); + /* + Returns the number of frames needed to manage a frame pool of size _n_frames. + The number returned here depends on the implementation of the frame pool and + on the frame size. + EXAMPLE: For FRAME_SIZE = 4096 and a bitmap with a single bit per frame + (not appropriate for contiguous allocation) one would need one frame to manage a + frame pool with up to 8 * 4096 = 32k frames = 128MB of memory! + This function would therefore return the following value: + _n_frames / 32k + (_n_frames % 32k > 0 ? 1 : 0) (always round up!) + Other implementations need a different number of info frames. + The exact number is computed in this function. + */ + +}; +#endif diff --git a/MP2/MP2_Sources/start.asm b/MP2/MP2_Sources/start.asm new file mode 100755 index 0000000..513fda5 --- /dev/null +++ b/MP2/MP2_Sources/start.asm @@ -0,0 +1,57 @@ +; bkerndev - Bran's Kernel Development Tutorial +; By: Brandon F. (friesenb@gmail.com) +; Desc: Kernel entry point, stack, and Interrupt Service Routines. +; +; Notes: No warranty expressed or implied. Use at own risk. +; +; This is the kernel's entry point. We could either call main here, +; or we can use this to setup the stack or other nice stuff, like +; perhaps setting up the GDT and segments. Please note that interrupts +; are disabled at this point: More on interrupts later! +[BITS 32] +global start +start: + mov esp, _sys_stack ; This points the stack to our new stack area + jmp stublet + +; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4' +ALIGN 4 +mboot: + ; Multiboot macros to make a few lines later more readable + MULTIBOOT_PAGE_ALIGN equ 1<<0 + MULTIBOOT_MEMORY_INFO equ 1<<1 + MULTIBOOT_AOUT_KLUDGE equ 1<<16 + MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 + MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE + MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) + EXTERN code, bss, end + + ; This is the GRUB Multiboot header. A boot signature + dd MULTIBOOT_HEADER_MAGIC + dd MULTIBOOT_HEADER_FLAGS + dd MULTIBOOT_CHECKSUM + + ; AOUT kludge - must be physical addresses. Make a note of these: + ; The linker script fills in the data for these ones! + dd mboot + dd code + dd bss + dd end + dd start + +; This is an endless loop here. Make a note of this: Later on, we +; will insert an 'extern _main', followed by 'call _main', right +; before the 'jmp $'. +stublet: + extern _main + call _main + jmp $ + +; Here is the definition of our BSS section. Right now, we'll use +; it just to store the stack. Remember that a stack actually grows +; downwards, so we declare the size of the data before declaring +; the identifier '_sys_stack' +SECTION .bss + resb 8192 ; This reserves 8KBytes of memory here +_sys_stack: + diff --git a/MP2/MP2_Sources/utils.C b/MP2/MP2_Sources/utils.C new file mode 100755 index 0000000..15fd38a --- /dev/null +++ b/MP2/MP2_Sources/utils.C @@ -0,0 +1,167 @@ +/* + File: utils.C + + Author: R. Bettati + Department of Computer Science + Texas A&M University + + Date : 09/02/12 + +*/ + +/* Some of the code comes from Brandon Friesens OS Tutorial: +* bkerndev - Bran's Kernel Development Tutorial +* By: Brandon F. (friesenb@gmail.com) +* Desc: Interrupt Descriptor Table management +* +* Notes: No warranty expressed or implied. Use at own risk. */ + + +/*--------------------------------------------------------------------------*/ +/* DEFINES */ +/*--------------------------------------------------------------------------*/ + + /* -- (none ) -- */ + +/*--------------------------------------------------------------------------*/ +/* INCLUDES */ +/*--------------------------------------------------------------------------*/ + +#include "utils.H" + +/*--------------------------------------------------------------------------*/ +/* DATA STRUCTURES */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* CONSTANTS */ +/*--------------------------------------------------------------------------*/ + + /* -- (none) -- */ + +/*--------------------------------------------------------------------------*/ +/* ABORT (USED e.g. IN _ASSERT() */ +/*--------------------------------------------------------------------------*/ + +void abort() { + for(;;); +} + +/*--------------------------------------------------------------------------*/ +/* MEMORY OPERATIONS */ +/*--------------------------------------------------------------------------*/ + +void *memcpy(void *dest, const void *src, int count) +{ + const char *sp = (const char *)src; + char *dp = (char *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, char val, int count) +{ + char *temp = (char *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +unsigned short *memsetw(unsigned short *dest, unsigned short val, int count) +{ + unsigned short *temp = (unsigned short *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +/*--------------------------------------------------------------------------*/ +/* STRING OPERATIONS */ +/*--------------------------------------------------------------------------*/ + + +int strlen(const char *_str) { + /* This loops through character array 'str', returning how + * many characters it needs to check before it finds a 0. + * In simple words, it returns the length in bytes of a string */ + int len = 0; + while (*_str != 0) { + _str++; + len++; + } + return len; +} +void strcpy(char* _dst, char* _src) { + while (*_src != 0) { + *_dst = *_src; + _dst++; + _src++; + } + *_dst = 0; // put terminating 0 at end. +} + +void int2str(int _num, char * _str) { + /* -- THIS IMPLEMENTATION IS ONE PRETTY BAD HACK. */ + int i; + char temp[11]; + + temp[0] = '\0'; + for(i = 1; i <= 10; i++) { + temp[i] = _num % 10 + '0'; + _num /= 10; + } + for(i = 10; temp[i] == '0'; i--); + if( i == 0 ) + i++; + while( i >= 0 ) + *_str++ = temp[i--]; +} + + +void uint2str(unsigned int _num, char * _str) { + /* -- THIS IS A BAD HACK AS WELL. */ + int i; + char temp[11]; + + temp[0] = '\0'; + for(i = 1; i <= 10; i++) { + temp[i] = _num % 10 + '0'; + _num /= 10; + } + for(i = 10; temp[i] == '0'; i--); + if( i == 0 ) + i++; + while( i >= 0 ) + *_str++ = temp[i--]; +} + +/*--------------------------------------------------------------------------*/ +/* POERT I/O OPERATIONS */ +/*--------------------------------------------------------------------------*/ + +/* We will use this later on for reading from the I/O ports to get data +* from devices such as the keyboard. We are using what is called +* 'inline assembly' in these routines to actually do the work */ +char inportb (unsigned short _port) { + unsigned char rv; + __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} + +unsigned short inportw (unsigned short _port) { + unsigned short rv; + __asm__ __volatile__ ("inw %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} + +/* We will use this to write to I/O ports to send bytes to devices. This +* will be used in the next tutorial for changing the textmode cursor +* position. Again, we use some inline assembly for the stuff that simply +* cannot be done in C */ +void outportb (unsigned short _port, char _data) { + __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} + +void outportw (unsigned short _port, unsigned short _data) { + __asm__ __volatile__ ("outw %1, %0" : : "dN" (_port), "a" (_data)); +} diff --git a/MP2/MP2_Sources/utils.H b/MP2/MP2_Sources/utils.H new file mode 100755 index 0000000..71c6c4c --- /dev/null +++ b/MP2/MP2_Sources/utils.H @@ -0,0 +1,62 @@ +/* + File : utils.H + + Author : Riccardo Bettati + Modified : 2017/05/02 + + Description : Various definitions (NULL) and + utility functions (e.g. abort, memory and + string functions). +*/ + +#ifndef _utils_h_ +#define _utils_h_ + +/*---------------------------------------------------------------*/ +/* GENERAL CONSTANTS */ +/*---------------------------------------------------------------*/ + +#ifndef NULL +# define NULL 0 +#endif + +/*---------------------------------------------------------------*/ +/* ABORT */ +/*---------------------------------------------------------------*/ + +void abort(); +/* Stop execution. */ + +/*---------------------------------------------------------------*/ +/* SIMPLE MEMORY OPERATIONS */ +/*---------------------------------------------------------------*/ + +void *memcpy(void *dest, const void *src, int count); +/* Copy _count bytes from _src to _dest. (No check for uverlapping) */ + +void *memset(void *dest, char val, int count); +/* Set _count bytes to value _val, starting from location _dest. */ + +unsigned short *memsetw(unsigned short *dest, unsigned short val, int count); +/* Same as above, but operations are 16-bit wide. */ + +/*---------------------------------------------------------------*/ +/* SIMPLE STRING OPERATIONS (STRINGS ARE NULL-TERMINATED) */ +/*---------------------------------------------------------------*/ + +int strlen(const char * _str); +/* Determine the length of null-terminated string. */ + +void strcpy(char * _dst, char * _src); +/* Copy null-terminated string from _src to _dst. */ + +void int2str(int _num, char * _str); +/* Convert int to null-terminated string. */ + +void uint2str(unsigned int _num, char * _str); +/* Convert unsigned int to null-terminated string. */ + +#endif + + + diff --git a/MP2/__MACOSX/._MP2_Sources b/MP2/__MACOSX/._MP2_Sources new file mode 100644 index 0000000..8d5c554 Binary files /dev/null and b/MP2/__MACOSX/._MP2_Sources differ diff --git a/MP2/__MACOSX/MP2_Sources/._.DS_Store b/MP2/__MACOSX/MP2_Sources/._.DS_Store new file mode 100644 index 0000000..09fa6bd Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._.DS_Store differ diff --git a/MP2/__MACOSX/MP2_Sources/._BIOS-bochs-latest b/MP2/__MACOSX/MP2_Sources/._BIOS-bochs-latest new file mode 100644 index 0000000..c8e0fc7 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._BIOS-bochs-latest differ diff --git a/MP2/__MACOSX/MP2_Sources/._README.TXT b/MP2/__MACOSX/MP2_Sources/._README.TXT new file mode 100644 index 0000000..d88b46d Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._README.TXT differ diff --git a/MP2/__MACOSX/MP2_Sources/._VGABIOS-lgpl-latest b/MP2/__MACOSX/MP2_Sources/._VGABIOS-lgpl-latest new file mode 100644 index 0000000..d2c1004 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._VGABIOS-lgpl-latest differ diff --git a/MP2/__MACOSX/MP2_Sources/._assert.C b/MP2/__MACOSX/MP2_Sources/._assert.C new file mode 100644 index 0000000..82269bf Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._assert.C differ diff --git a/MP2/__MACOSX/MP2_Sources/._assert.H b/MP2/__MACOSX/MP2_Sources/._assert.H new file mode 100644 index 0000000..01c3466 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._assert.H differ diff --git a/MP2/__MACOSX/MP2_Sources/._bochsout.txt b/MP2/__MACOSX/MP2_Sources/._bochsout.txt new file mode 100644 index 0000000..86ffe4c Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._bochsout.txt differ diff --git a/MP2/__MACOSX/MP2_Sources/._bochsrc.bxrc b/MP2/__MACOSX/MP2_Sources/._bochsrc.bxrc new file mode 100644 index 0000000..9b7e9b1 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._bochsrc.bxrc differ diff --git a/MP2/__MACOSX/MP2_Sources/._console.C b/MP2/__MACOSX/MP2_Sources/._console.C new file mode 100644 index 0000000..9734208 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._console.C differ diff --git a/MP2/__MACOSX/MP2_Sources/._console.H b/MP2/__MACOSX/MP2_Sources/._console.H new file mode 100644 index 0000000..6d69437 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._console.H differ diff --git a/MP2/__MACOSX/MP2_Sources/._cont_frame_pool.C b/MP2/__MACOSX/MP2_Sources/._cont_frame_pool.C new file mode 100644 index 0000000..a41f54d Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._cont_frame_pool.C differ diff --git a/MP2/__MACOSX/MP2_Sources/._cont_frame_pool.H b/MP2/__MACOSX/MP2_Sources/._cont_frame_pool.H new file mode 100644 index 0000000..3994a1c Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._cont_frame_pool.H differ diff --git a/MP2/__MACOSX/MP2_Sources/._copykernel.sh b/MP2/__MACOSX/MP2_Sources/._copykernel.sh new file mode 100644 index 0000000..fc8dae3 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._copykernel.sh differ diff --git a/MP2/__MACOSX/MP2_Sources/._dev_kernel_grub.img b/MP2/__MACOSX/MP2_Sources/._dev_kernel_grub.img new file mode 100644 index 0000000..9e7abc1 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._dev_kernel_grub.img differ diff --git a/MP2/__MACOSX/MP2_Sources/._kernel.C b/MP2/__MACOSX/MP2_Sources/._kernel.C new file mode 100644 index 0000000..c1c9429 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._kernel.C differ diff --git a/MP2/__MACOSX/MP2_Sources/._linker.ld b/MP2/__MACOSX/MP2_Sources/._linker.ld new file mode 100644 index 0000000..31adeb3 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._linker.ld differ diff --git a/MP2/__MACOSX/MP2_Sources/._machine.C b/MP2/__MACOSX/MP2_Sources/._machine.C new file mode 100644 index 0000000..95f6db0 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._machine.C differ diff --git a/MP2/__MACOSX/MP2_Sources/._machine.H b/MP2/__MACOSX/MP2_Sources/._machine.H new file mode 100644 index 0000000..008aab0 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._machine.H differ diff --git a/MP2/__MACOSX/MP2_Sources/._machine_low.H b/MP2/__MACOSX/MP2_Sources/._machine_low.H new file mode 100644 index 0000000..ba6c265 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._machine_low.H differ diff --git a/MP2/__MACOSX/MP2_Sources/._machine_low.asm b/MP2/__MACOSX/MP2_Sources/._machine_low.asm new file mode 100644 index 0000000..c034200 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._machine_low.asm differ diff --git a/MP2/__MACOSX/MP2_Sources/._makefile b/MP2/__MACOSX/MP2_Sources/._makefile new file mode 100644 index 0000000..96c2129 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._makefile differ diff --git a/MP2/__MACOSX/MP2_Sources/._simple_frame_pool.C b/MP2/__MACOSX/MP2_Sources/._simple_frame_pool.C new file mode 100644 index 0000000..ef14f18 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._simple_frame_pool.C differ diff --git a/MP2/__MACOSX/MP2_Sources/._simple_frame_pool.H b/MP2/__MACOSX/MP2_Sources/._simple_frame_pool.H new file mode 100644 index 0000000..f6017f9 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._simple_frame_pool.H differ diff --git a/MP2/__MACOSX/MP2_Sources/._start.asm b/MP2/__MACOSX/MP2_Sources/._start.asm new file mode 100644 index 0000000..50eb7ea Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._start.asm differ diff --git a/MP2/__MACOSX/MP2_Sources/._utils.C b/MP2/__MACOSX/MP2_Sources/._utils.C new file mode 100644 index 0000000..4508bd0 Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._utils.C differ diff --git a/MP2/__MACOSX/MP2_Sources/._utils.H b/MP2/__MACOSX/MP2_Sources/._utils.H new file mode 100644 index 0000000..8db2f8c Binary files /dev/null and b/MP2/__MACOSX/MP2_Sources/._utils.H differ diff --git a/MP2/handout_mp2.pdf b/MP2/handout_mp2.pdf new file mode 100644 index 0000000..bbc6747 Binary files /dev/null and b/MP2/handout_mp2.pdf differ