diff --git a/MP1/MP1_Sources/dev_kernel_grub.img b/MP1/MP1_Sources/dev_kernel_grub.img index 3233f66..d3732a2 100644 Binary files a/MP1/MP1_Sources/dev_kernel_grub.img and b/MP1/MP1_Sources/dev_kernel_grub.img differ diff --git a/MP2/MP2_Sources/bochsout.txt b/MP2/MP2_Sources/bochsout.txt deleted file mode 100644 index 3cc1677..0000000 --- a/MP2/MP2_Sources/bochsout.txt +++ /dev/null @@ -1,235 +0,0 @@ -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 0x7f048b2b5010. after alignment, vector=0x7f048b2b6000 -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 0x2bea560 -00000000000i[PLGIN] loaded plugin libbx_cmos.so -00000000000i[ ] lt_dlhandle is 0x2beaf80 -00000000000i[PLGIN] loaded plugin libbx_dma.so -00000000000i[ ] lt_dlhandle is 0x2beb9e0 -00000000000i[PLGIN] loaded plugin libbx_pic.so -00000000000i[ ] lt_dlhandle is 0x2bec220 -00000000000i[PLGIN] loaded plugin libbx_pit.so -00000000000i[ ] lt_dlhandle is 0x2becb90 -00000000000i[PLGIN] loaded plugin libbx_vga.so -00000000000i[ ] lt_dlhandle is 0x2bed2c0 -00000000000i[PLGIN] loaded plugin libbx_hdimage.so -00000000000i[ ] lt_dlhandle is 0x2bedb80 -00000000000i[PLGIN] loaded plugin libbx_floppy.so -00000000000i[ ] lt_dlhandle is 0x2bee770 -00000000000i[PLGIN] loaded plugin libbx_soundmod.so -00000000000i[ ] lt_dlhandle is 0x2befdc0 -00000000000i[PLGIN] loaded plugin libbx_pci.so -00000000000i[ ] lt_dlhandle is 0x2bf09f0 -00000000000i[PLGIN] loaded plugin libbx_pci2isa.so -00000000000i[ ] lt_dlhandle is 0x2bf12d0 -00000000000i[PLGIN] loaded plugin libbx_usb_common.so -00000000000i[ ] lt_dlhandle is 0x2bf1b30 -00000000000i[PLGIN] loaded plugin libbx_unmapped.so -00000000000i[ ] lt_dlhandle is 0x2bf23a0 -00000000000i[PLGIN] loaded plugin libbx_biosdev.so -00000000000i[ ] lt_dlhandle is 0x2bf2cd0 -00000000000i[PLGIN] loaded plugin libbx_speaker.so -00000000000i[ ] lt_dlhandle is 0x2bf3500 -00000000000i[PLGIN] loaded plugin libbx_extfpuirq.so -00000000000i[ ] lt_dlhandle is 0x2bf3d70 -00000000000i[PLGIN] loaded plugin libbx_gameport.so -00000000000i[ ] lt_dlhandle is 0x2bf46e0 -00000000000i[PLGIN] loaded plugin libbx_pci_ide.so -00000000000i[ ] lt_dlhandle is 0x2bf50b0 -00000000000i[PLGIN] loaded plugin libbx_acpi.so -00000000000i[ ] lt_dlhandle is 0x2bf59f0 -00000000000i[PLGIN] loaded plugin libbx_ioapic.so -00000000000i[ ] lt_dlhandle is 0x2bf63a0 -00000000000i[PLGIN] loaded plugin libbx_keyboard.so -00000000000i[ ] lt_dlhandle is 0x2bf6ba0 -00000000000i[PLGIN] loaded plugin libbx_harddrv.so -00000000000i[ ] lt_dlhandle is 0x2c08c70 -00000000000i[PLGIN] loaded plugin libbx_serial.so -00000000000i[ ] lt_dlhandle is 0x2c09ae0 -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 -00001019718i[BIOS ] Found 1 cpu(s) -00001036019i[BIOS ] bios_table_addr: 0x000fb778 end=0x000fcc00 -00001036086i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) -00001494893i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) -00001954380i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b -00001954427i[P2I ] PCI IRQ routing: PIRQB# set to 0x09 -00001954474i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b -00001954521i[P2I ] PCI IRQ routing: PIRQD# set to 0x09 -00001954537i[P2I ] write: ELCR2 = 0x0a -00001955474i[BIOS ] PIIX3 init: elcr=00 0a -00001975729i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 -00001978966i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 -00001981699i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 -00001982160i[PIDE ] new BM-DMA address: 0xc000 -00001983043i[BIOS ] region 4: 0x0000c000 -00001985619i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 -00001986119i[ACPI ] new irq line = 11 -00001986156i[ACPI ] new PM base address: 0xb000 -00001986218i[ACPI ] new SM base address: 0xb100 -00001986686i[CPU0 ] Enter to System Management Mode -00001986696i[CPU0 ] RSM: Resuming from System Management Mode -00001986730i[PCI ] setting SMRAM control register to 0x4a -00001987012i[PCI ] setting SMRAM control register to 0x0a -00002010293i[BIOS ] MP table addr=0x000fb850 MPC table addr=0x000fb780 size=0xd0 -00002012496i[BIOS ] SMBIOS table addr=0x000fb860 -00002015540i[BIOS ] ACPI tables: RSDP addr=0x000fb970 ACPI DATA addr=0x01ff0000 size=0x9d8 -00002035073i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush) -00002036085i[BIOS ] bios_table_cur_addr: 0x000fb994 -00500104718i[BIOS ] Booting from 0000:7c00 -00510000000i[XGUI ] charmap update. Font Height is 16 -00586200000i[XGUI ] charmap update. Font Height is 16 -00594600000i[XGUI ] charmap update. Font Height is 16 -00905192000p[XGUI ] >>PANIC<< POWER button turned off. -00905192000i[CPU0 ] CPU is in protected mode (active) -00905192000i[CPU0 ] CS.d_b = 32 bit -00905192000i[CPU0 ] SS.d_b = 32 bit -00905192000i[CPU0 ] EFER = 0x00000000 -00905192000i[CPU0 ] | RAX=0000000000000000 RBX=0000000000026260 -00905192000i[CPU0 ] | RCX=0000000000000f00 RDX=00000000000003d4 -00905192000i[CPU0 ] | RSP=0000000000104f90 RBP=0000000000104ff8 -00905192000i[CPU0 ] | RSI=00000000000263d3 RDI=00000000000263df -00905192000i[CPU0 ] | R8=0000000000000000 R9=0000000000000000 -00905192000i[CPU0 ] | R10=0000000000000000 R11=0000000000000000 -00905192000i[CPU0 ] | R12=0000000000000000 R13=0000000000000000 -00905192000i[CPU0 ] | R14=0000000000000000 R15=0000000000000000 -00905192000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf ZF af PF cf -00905192000i[CPU0 ] | SEG selector base limit G D -00905192000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D -00905192000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 -00905192000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 -00905192000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 -00905192000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1 -00905192000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 -00905192000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1 -00905192000i[CPU0 ] | MSR_FS_BASE:0000000000000000 -00905192000i[CPU0 ] | MSR_GS_BASE:0000000000000000 -00905192000i[CPU0 ] | RIP=0000000000100431 (0000000000100431) -00905192000i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000 -00905192000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000 -00905192000i[CPU0 ] 0x0000000000100431>> jmp .-2 (0x00100431) : EBFE -00905192000i[CMOS ] Last time is 946681426 (Fri Dec 31 17:03:46 1999) -00905192000i[XGUI ] Exit -00905192000i[ ] restoring default signal behavior -00905192000i[CTRL ] quit_sim called with exit code 1 diff --git a/MP2/MP2_Sources/dev_kernel_grub.img b/MP2/MP2_Sources/dev_kernel_grub.img index 78aca56..f490066 100755 Binary files a/MP2/MP2_Sources/dev_kernel_grub.img and b/MP2/MP2_Sources/dev_kernel_grub.img differ diff --git a/MP2/design.odt b/MP2/design.odt new file mode 100644 index 0000000..d5cf711 Binary files /dev/null and b/MP2/design.odt differ diff --git a/MP2/design.pdf b/MP2/design.pdf new file mode 100644 index 0000000..5abe55b Binary files /dev/null and b/MP2/design.pdf differ diff --git a/MP2/mp2.zip b/MP2/mp2.zip new file mode 100644 index 0000000..37fddee Binary files /dev/null and b/MP2/mp2.zip differ diff --git a/MP2/mp2/cont_frame_pool.C b/MP2/mp2/cont_frame_pool.C new file mode 100644 index 0000000..3c1af89 --- /dev/null +++ b/MP2/mp2/cont_frame_pool.C @@ -0,0 +1,404 @@ +/* + 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::pools = (ContFramePool *) FRAME_SIZE; // List of frame pools, managed by the class +unsigned int ContFramePool::nPools = 0; // Number of pools being managed + +ContFramePool::ContFramePool(unsigned long _base_frame_no, + unsigned long _n_frames, + unsigned long _info_frame_no, + unsigned long _n_info_frames) +{ + // Bitmap must fit in a single frame! + // NOTE: In theory, we don't need to make the bitmap any larger, + // since as stated in the instructions it is already big enough to + // hold for 128MB of memory with one bit per frame, so should still + // be enough for 64MB of memory with 2 bits per frame. + // Assertion changed to match max size of frames allowed. + assert(_n_frames <= FRAME_SIZE * 4); + + base_frame_no = _base_frame_no; + nframes = _n_frames; + nFreeFrames = _n_frames; + info_frame_no = _info_frame_no; + n_info_frames = _n_info_frames; + + // If _info_frame_no is zero then we keep management info in the first + // frame(s), else we use the provided frame(s) to keep management info + // NOTE: bitmap needs to be allocated with n_info_frames if specified. + if(info_frame_no == 0) + { + bitmap = (unsigned char *) (base_frame_no * FRAME_SIZE); + } + else + { + bitmap = (unsigned char *) (info_frame_no * FRAME_SIZE * n_info_frames); + } + + // Number of frames must "fill" the bitmap! + assert ((nframes % 8 ) == 0); + + + // Everything ok. Proceed to mark all bits in the bitmap + // NOTE: changed to reflect that I need 2 bits per frame now + for(int i=0; i*4 < _n_frames; i++) + { + bitmap[i] = 0xFF; + } + + // Mark the first frame as being used if it is being used + // NOTE: need to mark multiple frames if needed. + if(info_frame_no == 0) + { + bitmap[0] = 0x3F; + nFreeFrames--; + } + else + { + unsigned int i = info_frame_no / 4; + unsigned int r = info_frame_no % 4; + unsigned char mask = 0x80; + mask = mask >> r*2; + + unsigned int c = 0; + while(c < n_info_frames) + { + bitmap[i] = bitmap[i] ^ mask; + bitmap[i] = bitmap[i] ^ (mask >> 1); + if(mask == 0x02) + { + i++; + mask = 0x80; + } + c++; + nFreeFrames--; + } + + } + + pools[nPools] = *this; + nPools += 1; + + Console::puts("Frame Pool initialized\n"); +} + +unsigned long ContFramePool::get_frames(unsigned int _n_frames) +{ + // Are there enough frames left to allocate? + assert(nFreeFrames > _n_frames); + + // Find a frame that is not being used and return its frame index. + // Mark that frame as being used in the bitmap. + // NOTE: Must be updated to find a sequence of contiguous frames + // that are not being used and return the index of the head. + unsigned int frame_no = base_frame_no; + + // i is being used as the frame_no / 4 + // j is frame_no % 4 + // together, they will give the actual frame_no. + // c is used as a counter to count a squence of free frames. + unsigned int i = 0; + unsigned int j = 0; + unsigned int c = 0; + + while (true) + { + unsigned char mask = 0x80 >> (j*2); + // check every 2 bits for a free frame in the bitmap + while((mask & bitmap[i]) == 0 || ((mask >> 1) & bitmap[i]) == 0) + { + if(mask != 0x02) + { + j++; + mask = mask >> 2; + } + else + { + i++; + j = 0; + mask = 0x80; + } + } + // if frame is found, start checking for sequence + unsigned int temp = i; + c++; + while(c < _n_frames) + { + if(mask != 0x02) + { + mask = mask >> 2; + } + else + { + temp++; + mask = 0x80; + } + if((mask & bitmap[temp]) != 0 && ((mask >> 1) & bitmap[temp]) != 0) + { + c++; + } + else + { + c = 0; + break; + } + } + if(c == _n_frames) + { + nFreeFrames -= _n_frames; + break; + } + } + + frame_no += i*4 + j; + + // Update bitmap + // First: clear most significant bit to mark head of sequence. + bitmap[i] = bitmap[i] ^ (0x80 >> (j*2)); + // Second: clear both bits for all remaining frames in the sequence. + c = 1; + unsigned char mask = 0x80 >> j*2; + unsigned int temp = i; + while(c < _n_frames) + { + if(mask != 0x02) + { + mask = mask >> 2; + } + else + { + temp++; + mask = 0x80; + } + + bitmap[temp] = bitmap[temp] ^ mask; + bitmap[temp] = bitmap[temp] ^ (mask >> 1); + c++; + } + + return (frame_no); +} + +void ContFramePool::mark_inaccessible(unsigned long _base_frame_no, + unsigned long _n_frames) +{ + // Mark all frames in the range as being used. + int i ; + for(i = _base_frame_no; i < _base_frame_no + _n_frames; i++){ + mark_inaccessible(i); + } + nFreeFrames -= _n_frames; +} + +void ContFramePool::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) / 4; + unsigned char mask = 0x80 >> ((_frame_no - base_frame_no) % 4) * 2; + + // Is the frame being used already? + assert(((bitmap[bitmap_index] & mask) != 0) && (bitmap[bitmap_index] & (mask >> 1)) != 0); + + // Update bitmap + bitmap[bitmap_index] ^= mask; + bitmap[bitmap_index] ^= mask >> 1; + nFreeFrames--; +} + +void ContFramePool::release_frames(unsigned long _frame_no) +{ + unsigned int i = 0; + while(i < nPools) + { + if(_frame_no <= pools[i].base_frame_no || _frame_no > (pools[i].base_frame_no + pools[i].nframes)) + { + i++; + } + else + { + pools[i].release_frames_here(_frame_no); + return; + } + } +} + +void ContFramePool::release_frames_here(unsigned long _first_frame_no) +{ + unsigned char * bitmap = this->bitmap; + + unsigned int bitmap_index = (_first_frame_no - base_frame_no) / 4; + unsigned char mask = 0x80 >> ((_first_frame_no - base_frame_no) % 4) * 2; + + if(!((bitmap[bitmap_index] & mask) == 0 && (bitmap[bitmap_index] & (mask >> 1)) != 0)) + { + if((bitmap[bitmap_index] & mask) != 0 && (bitmap[bitmap_index] & (mask >> 1)) != 0) + { + Console::puts("Error, Frame being released is not being used\n"); + assert(false); + } + Console::puts("Error, Frame being released is not head of sequence\n"); + assert(false); + } + + bitmap[bitmap_index] ^= mask; + nFreeFrames++; + + if(mask != 0x02) + { + mask = mask >> 2; + } + else + { + mask = 0x80; + bitmap_index++; + } + + while(bitmap[bitmap_index] & mask == 0 && (bitmap[bitmap_index] & (mask >> 1)) == 0) + { + bitmap[bitmap_index] ^= mask; + bitmap[bitmap_index] ^= (mask >> 1); + if(mask != 0x02) + { + mask = mask >> 2; + } + else + { + mask = 0x80; + bitmap_index++; + } + nFreeFrames++; + } +} + +unsigned long ContFramePool::needed_info_frames(unsigned long _n_frames) +{ + return (_n_frames / (FRAME_SIZE * 4)) + (_n_frames % (FRAME_SIZE * 4) > 0 ? 1 : 0); +} diff --git a/MP2/mp2/cont_frame_pool.H b/MP2/mp2/cont_frame_pool.H new file mode 100755 index 0000000..13c7a07 --- /dev/null +++ b/MP2/mp2/cont_frame_pool.H @@ -0,0 +1,132 @@ +/* + 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. */ + + unsigned char * bitmap; // Remember the bitmap here needs 2 bits per frame + 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? + unsigned long n_info_frames; // Number of frames needed to store management info + static ContFramePool* pools; // List of frame pools, managed by the class + static unsigned int nPools; // Number of pools being managed + + void mark_inaccessible(unsigned long _frame_no); // Should be a frame marked as + // a head, otherwise fails + void release_frames_here(unsigned long _frame_no); // non-static member function + +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 _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/design.pdf b/MP2/mp2/design.pdf new file mode 100644 index 0000000..5abe55b Binary files /dev/null and b/MP2/mp2/design.pdf differ