mirror of
https://github.com/caperren/school_archives.git
synced 2025-11-09 21:51:15 +00:00
Added OS II assignments
This commit is contained in:
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
\section{Commands}
|
||||
\begin{itemize}
|
||||
\item mkdir /scratch/spring2018/4
|
||||
\item cd /scratch/spring20128/4
|
||||
\item git init
|
||||
\item wget http://git.yoctoproject.org/cgit.cgi/linux-yocto/snapshot/linux-yocto-3.19.2.tar.bz2
|
||||
\item tar xvjf linux-yocto-3.19.2.tar.bz2
|
||||
\item cp /scratch/files/bzImage-qemux86.bin .
|
||||
\item cp /scratch/files/core-image-lsb-sdk-qemux86.ext4 .
|
||||
\item cp /scratch/files/config-3.19.2-yocto-standard .config
|
||||
\item source /scratch/files/environment-setup-i586-poky-linux.csh
|
||||
\item make -j4
|
||||
\item qemu-system-i386 -gdb tcp::5004 -nographic -kernel bzImage-qemux86.bin -drive file=core-image-lsb-sdk-qemux86.ext4,if=virtio -enable-kvm -net none -usb -localtime --no-reboot --append "root=/dev/vda rw console=ttyS0 debug".
|
||||
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,53 @@
|
||||
\section{QEMU Flags}
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{-gdb tcp::????}
|
||||
|
||||
Waits for a GDB connection on the specified device, namely a TCP
|
||||
connection on port ????.
|
||||
|
||||
\item \texttt{-S}
|
||||
|
||||
Prevents the CPU from starting up when first launching the command.
|
||||
|
||||
\item \texttt{-nographic}
|
||||
|
||||
Disables graphical capabilities and turns qemu into a command line
|
||||
application.
|
||||
|
||||
\item \texttt{-kernel bzImage-qemux86.bin}
|
||||
|
||||
Uses the ``\texttt{bzImage-qemux86.bin}'' binary as the kernel image to boot.
|
||||
|
||||
\item \texttt{-drive file=core-image-lsb-sdk-qemux86.ext4,if=virtio}
|
||||
|
||||
Uses ``\texttt{core-image-lsb-sdk-qemux86.ext4}'' as the file for the virtual
|
||||
hard drive, and virtio as the I/O interface (virtio virtualizes I/O
|
||||
operations like disk reads/writes).
|
||||
|
||||
\item \texttt{-enable-kvm}
|
||||
|
||||
Enables use of kernel-based virtual machine technology.
|
||||
|
||||
\item \texttt{-net none}
|
||||
|
||||
Indicates that no network devices should be configured.
|
||||
|
||||
\item \texttt{-usb}
|
||||
|
||||
Enables USB drivers.
|
||||
|
||||
\item \texttt{-localtime}
|
||||
|
||||
Uses the local time from the host machine to set the time in the guest,
|
||||
instead of the default of UTC time.
|
||||
|
||||
\item \texttt{--no-reboot}
|
||||
|
||||
Shuts down the guest entirely on exit instead of rebooting.
|
||||
|
||||
\item \texttt{--append "root=/dev/vda rw console=ttyS0 debug"}
|
||||
|
||||
Uses \texttt{"root=/dev/vda rw console=ttyS0 debug"} as the initial command line,
|
||||
running it on initial boot.
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,107 @@
|
||||
\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran}
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{{./figures/}}
|
||||
|
||||
\usepackage{url}
|
||||
\usepackage{setspace}
|
||||
\usepackage{multicol}
|
||||
\usepackage{pdflscape}
|
||||
\usepackage{pdfpages}
|
||||
\usepackage[british]{babel}
|
||||
\usepackage{listings}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{listings}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{subfig}
|
||||
|
||||
\usepackage{geometry}
|
||||
\geometry{textheight=9.5in, textwidth=7in}
|
||||
|
||||
% \overfullrule=2in
|
||||
|
||||
|
||||
%Personal \newcommands
|
||||
|
||||
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
|
||||
\lstset{basicstyle=\ttfamily,
|
||||
backgroundcolor=\color{backcolor},
|
||||
showstringspaces=false,
|
||||
commentstyle=\color{red},
|
||||
keywordstyle=\color{blue},
|
||||
columns=fullflexible,
|
||||
breaklines=true,
|
||||
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
|
||||
}
|
||||
|
||||
\newcommand{\NameSigPair}[1]{
|
||||
\par
|
||||
\makebox[2.75in][r]{#1}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in]{\hrulefill}
|
||||
\hfill
|
||||
\makebox[.75in]{\hrulefill}
|
||||
}
|
||||
\par\vspace{-12pt}
|
||||
\textit{
|
||||
\tiny\noindent
|
||||
\makebox[2.75in]{}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in][r]{Signature}
|
||||
\hfill
|
||||
\makebox[.75in][r]{Date}
|
||||
}
|
||||
}
|
||||
}
|
||||
% 3. If the document is not to be signed, uncomment the command below
|
||||
\renewcommand{\NameSigPair}[1]{#1}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
\pagenumbering{gobble}
|
||||
\begin{singlespace}
|
||||
\par\vspace{2in}
|
||||
\centering
|
||||
\scshape{
|
||||
\huge Operating Systems II Homework 1 \par
|
||||
{\large\today}\par
|
||||
\vspace{.5in}
|
||||
\vfill
|
||||
\vspace{5pt}
|
||||
{\large Prepared by }\par
|
||||
Group 4 \par
|
||||
% 5. comment out the line below this one if you do not wish to name your team
|
||||
\vspace{5pt}
|
||||
{\Large
|
||||
\NameSigPair{Corinna Brown}\par
|
||||
\NameSigPair{Zachary Comito}\par
|
||||
\NameSigPair{Corwin Perren}\par
|
||||
}
|
||||
\vspace{20pt}
|
||||
\begin{abstract}
|
||||
The document is our groups submission for homework one covering the commands our group ran to finish the assignment, descriptions of qemu flags, answers to explicit assignment questions, a version control log, and work log.
|
||||
|
||||
|
||||
\end{abstract}
|
||||
}
|
||||
\end{singlespace}
|
||||
\end{titlepage}
|
||||
\newpage
|
||||
\pagenumbering{arabic}
|
||||
\tableofcontents
|
||||
\clearpage
|
||||
|
||||
\input{commands}
|
||||
\input{flags}
|
||||
\input{questions}
|
||||
\input{versioncontrollog}
|
||||
\input{worklog}
|
||||
|
||||
\end{document}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
# This config is copied from overleaf so output there will match compiled output here
|
||||
|
||||
# support for the glossaries package:
|
||||
add_cus_dep('glo', 'gls', 0, 'makeglossaries');
|
||||
add_cus_dep('acn', 'acr', 0, 'makeglossaries');
|
||||
sub makeglossaries {
|
||||
system("makeglossaries \"$_[0]\"");
|
||||
}
|
||||
|
||||
# support for the nomencl package:
|
||||
add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
|
||||
sub makenlo2nls {
|
||||
system("makeindex -s nomencl.ist -o \"$_[0].nls\" \"$_[0].nlo\"");
|
||||
}
|
||||
|
||||
# from the documentation for V. 2.03 of asymptote:
|
||||
sub asy {return system("asy \"$_[0]\"");}
|
||||
add_cus_dep("asy","eps",0,"asy");
|
||||
add_cus_dep("asy","pdf",0,"asy");
|
||||
add_cus_dep("asy","tex",0,"asy");
|
||||
|
||||
# metapost rule from http://tex.stackexchange.com/questions/37134
|
||||
add_cus_dep('mp', '1', 0, 'mpost');
|
||||
sub mpost {
|
||||
my $file = $_[0];
|
||||
my ($name, $path) = fileparse($file);
|
||||
pushd($path);
|
||||
my $return = system "mpost $name";
|
||||
popd();
|
||||
return $return;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# Makefile created by Corwin Perren
|
||||
# Generic makefile for all LaTeX projects downloaded from overleaf
|
||||
#
|
||||
# All this makefile does is call perl against latexmkrc, which is
|
||||
# the latex equivalent of make
|
||||
|
||||
LATEXMK_COMPILE_FLAGS = -cd -pdf homework1.tex
|
||||
LATEXMK_CLEAN_FLAGS = -c
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
all: latexmk_output clean
|
||||
|
||||
latexmk_output:
|
||||
perl latexmk.pl $(LATEXMK_COMPILE_FLAGS)
|
||||
mv homework1.pdf CS444_project1_4.pdf
|
||||
|
||||
clean:
|
||||
perl latexmk.pl $(LATEXMK_CLEAN_FLAGS)
|
||||
@@ -0,0 +1,12 @@
|
||||
\section{Questions}
|
||||
\subsection{Point of Assignment}
|
||||
The point of this assignment was to make sure that our group could properly get the course's development environment up and running. Additionally, it gave us initial experience with using qemu, as that will be a core tool used during this class. Setting up the git repository also was needed to ensure both the instructors and our group can keep track of changes made to the kernel as we work on assignments over the term.
|
||||
|
||||
\subsection{Problem Approach}
|
||||
We approached this problem by systematically following the directions on the homework page, and making adjustments as necessary to fit our particular development environment. Where needed, we also looked up documentation through man pages and the internet.
|
||||
|
||||
\subsection{Correctness}
|
||||
We know that the end result was correct as we were able to successfully compile the kernel and boot the kernel in the emulator.
|
||||
|
||||
\subsection{What Was Learned}
|
||||
We learned how to set up the environment needed to both build and run a custom modified linux kernel in a virtual machine.
|
||||
@@ -0,0 +1,10 @@
|
||||
\section{Version Control Log}
|
||||
\begin{center}
|
||||
\begin{tabular}{l l l l} \textbf{Detail} & \textbf{Author} & \textbf{Date} &\textbf{Description}\\\hline
|
||||
|
||||
\href{commit/c52f73e00546af6f3fe60b23584aeb9c598db667}{c52f73e} & Corwin Perren & 2018-04-09 17:39:17 -0700 &Added initial kernel to our group folder.\\\hline
|
||||
\href{commit/974b4529f98f277120295937f6491675832c97bc}{974b452} & Corwin Perren & 2018-04-09 18:48:36 -0700 &Initial commit after first build\\\hline
|
||||
|
||||
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
@@ -0,0 +1,11 @@
|
||||
\section{Work Log}
|
||||
\begin{itemize}
|
||||
\item 2018-04-09
|
||||
\begin{itemize}
|
||||
\item Group met in valley library
|
||||
\item Set up initial os2 server workspace
|
||||
\item Ran make on kernel for first time
|
||||
\item Booted virtual machine for first time
|
||||
\item Wrote latex document for homework 1
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
\section{Design}
|
||||
\begin{itemize}
|
||||
\item Elevator: LOOK
|
||||
\item Method of sorting items: Insertion Sort
|
||||
\end{itemize}
|
||||
|
||||
The framework for the LOOK elevator was taken from the no-op elevator. To adapt this framework into the LOOK elevator, the "sstf\_add\_request" function was changed so that each item is sorted as it is inserted into the queue rather than simply adding each new request to the end of the queue. The following is pseudocode that describes the "sstf\_add\_request" function.
|
||||
|
||||
\begin{lstlisting}[lineskip=3pt,keywords={if,else,while}]
|
||||
if (list is empty) {
|
||||
add request to queue
|
||||
}
|
||||
else {
|
||||
if (request > next) {
|
||||
while (request > next) {
|
||||
move up the queue
|
||||
}
|
||||
add request to queue before this point
|
||||
}
|
||||
else {
|
||||
while (request > prev) {
|
||||
move down the queue
|
||||
}
|
||||
add request to queue after this point
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
@@ -0,0 +1,278 @@
|
||||
diff -Naur '--exclude=*.o*' '--exclude=*.ko' '--exclude=*.builtin' linux-yocto-3.19.2_untouched/block/Kconfig.iosched linux-yocto-3.19.2/block/Kconfig.iosched
|
||||
--- linux-yocto-3.19.2_untouched/block/Kconfig.iosched 2018-05-04 15:14:42.027042321 -0700
|
||||
+++ linux-yocto-3.19.2/block/Kconfig.iosched 2018-05-04 19:08:10.346278748 -0700
|
||||
@@ -32,6 +32,12 @@
|
||||
|
||||
This is the default I/O scheduler.
|
||||
|
||||
+config IOSCHED_SSTF
|
||||
+ tristate "SSTF scheduler"
|
||||
+ default y
|
||||
+ ---help---
|
||||
+ SSTF for class
|
||||
+
|
||||
config CFQ_GROUP_IOSCHED
|
||||
bool "CFQ Group Scheduling support"
|
||||
depends on IOSCHED_CFQ && BLK_CGROUP
|
||||
@@ -55,6 +61,9 @@
|
||||
config DEFAULT_NOOP
|
||||
bool "No-op"
|
||||
|
||||
+ config DEFAULT_SSTF
|
||||
+ bool "SSTF" if IOSCHED_SSTF=y
|
||||
+
|
||||
endchoice
|
||||
|
||||
config DEFAULT_IOSCHED
|
||||
@@ -62,7 +71,7 @@
|
||||
default "deadline" if DEFAULT_DEADLINE
|
||||
default "cfq" if DEFAULT_CFQ
|
||||
default "noop" if DEFAULT_NOOP
|
||||
-
|
||||
+ default "sstf" if DEFAULT_SSTF
|
||||
endmenu
|
||||
|
||||
endif
|
||||
diff -Naur '--exclude=*.o*' '--exclude=*.ko' '--exclude=*.builtin' linux-yocto-3.19.2_untouched/block/Makefile linux-yocto-3.19.2/block/Makefile
|
||||
--- linux-yocto-3.19.2_untouched/block/Makefile 2018-05-04 15:14:42.055042785 -0700
|
||||
+++ linux-yocto-3.19.2/block/Makefile 2018-05-04 17:41:20.460575829 -0700
|
||||
@@ -18,8 +18,7 @@
|
||||
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
|
||||
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
|
||||
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
|
||||
-
|
||||
+obj-$(CONFIG_IOSCHED_SSTF) += sstf-iosched.o
|
||||
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
|
||||
obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o
|
||||
obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o
|
||||
-
|
||||
diff -Naur '--exclude=*.o*' '--exclude=*.ko' '--exclude=*.builtin' linux-yocto-3.19.2_untouched/block/sstf-iosched.c linux-yocto-3.19.2/block/sstf-iosched.c
|
||||
--- linux-yocto-3.19.2_untouched/block/sstf-iosched.c 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ linux-yocto-3.19.2/block/sstf-iosched.c 2018-05-05 16:33:00.528490307 -0700
|
||||
@@ -0,0 +1,226 @@
|
||||
+/* Developed by Corwin Perren and Corinna Brown
|
||||
+ * Date: May 4, 2018
|
||||
+ * Name: sstf-iosched.c
|
||||
+ */
|
||||
+#include <linux/blkdev.h>
|
||||
+#include <linux/elevator.h>
|
||||
+#include <linux/bio.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/init.h>
|
||||
+
|
||||
+//Main data type to store requests
|
||||
+struct sstf_data{
|
||||
+ struct list_head queue;
|
||||
+ int dir;
|
||||
+ sector_t head;
|
||||
+};
|
||||
+
|
||||
+/* Name: sstf_merge_requests
|
||||
+ * Description: merges requests
|
||||
+ * Parameters: request queue, request, next node
|
||||
+ */
|
||||
+static void sstf_merge_requests(struct request_queue *queue,
|
||||
+ struct request *req, struct request *next)
|
||||
+{
|
||||
+ list_del_init(&next->queuelist);
|
||||
+}
|
||||
+
|
||||
+/* Name: sstf_dispatch
|
||||
+ * Description: Main portion of code, runs the actual elevator
|
||||
+ * Parameters: request queue, force
|
||||
+ */
|
||||
+static int sstf_dispatch(struct request_queue *queue, int force)
|
||||
+{
|
||||
+ struct sstf_data *nd = queue->elevator->elevator_data;
|
||||
+
|
||||
+ if (!list_empty(&nd->queue)){
|
||||
+ struct request *req;
|
||||
+ req = list_entry(nd->queue.next, struct request, queuelist);
|
||||
+ list_del_init(&req->queuelist);
|
||||
+ elv_dispatch_sort(queue, req);
|
||||
+ printk(KERN_DEBUG "[SSTF_GROUP4] Dispatching: %s at %lu\n",
|
||||
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
|
||||
+ (long unsigned int) blk_rq_pos(req));
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Name: sstf_add_request
|
||||
+ * Description: adds a request to the queue
|
||||
+ * Parameters: Request queue, request
|
||||
+ */
|
||||
+static void sstf_add_request(struct request_queue *queue, struct request *req)
|
||||
+{
|
||||
+ struct sstf_data *nd = queue->elevator->elevator_data;
|
||||
+ struct request *next, *prev;
|
||||
+ struct request *iter;
|
||||
+
|
||||
+ // If the list is empty, we simply add it to the queue.
|
||||
+ if (list_empty(&nd->queue)){
|
||||
+ printk(KERN_DEBUG "[SSTF_GROUP4] Adding %s at %lu\n",
|
||||
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
|
||||
+ (long unsigned int) blk_rq_pos(req));
|
||||
+
|
||||
+ list_add(&req->queuelist, &nd->queue);
|
||||
+
|
||||
+ // Otherwise we'll need to find the right place to insert the request
|
||||
+ } else {
|
||||
+ // Get the next and previous entries from the queue
|
||||
+ next = list_entry(nd->queue.next, struct request, queuelist);
|
||||
+ prev = list_entry(nd->queue.prev, struct request, queuelist);
|
||||
+
|
||||
+ // If the request is larger than the "next" item, work UP the queue
|
||||
+ // until this isn't the case, and insert it directly before this point
|
||||
+ if (blk_rq_pos(req) > blk_rq_pos(next)){
|
||||
+ while (blk_rq_pos(req) > blk_rq_pos(next)) {
|
||||
+ prev = next;
|
||||
+ next = list_entry(next->queuelist.next, struct request,
|
||||
+ queuelist);
|
||||
+ }
|
||||
+ printk(KERN_DEBUG "[SSTF_GROUP4] Adding %s at %lu\n",
|
||||
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
|
||||
+ (long unsigned int) blk_rq_pos(req));
|
||||
+
|
||||
+ list_add(&req->queuelist, &prev->queuelist);
|
||||
+
|
||||
+ // Otherise, if the request is smaller than next, work DOWN the queue
|
||||
+ // unles this isn't the case, and insert direct after this point
|
||||
+ } else {
|
||||
+ while (blk_rq_pos(req) > blk_rq_pos(prev)) {
|
||||
+ next = prev;
|
||||
+ prev = list_entry(prev->queuelist.prev, struct request,
|
||||
+ queuelist);
|
||||
+ }
|
||||
+ printk(KERN_DEBUG "[SSTF_GROUP4] Adding %s at %lu\n",
|
||||
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
|
||||
+ (long unsigned int) blk_rq_pos(req));
|
||||
+
|
||||
+ list_add(&req->queuelist, &next->queuelist);
|
||||
+ }
|
||||
+
|
||||
+ // Prints out entries in queue, for verification
|
||||
+ printk(KERN_DEBUG "[SSTF_GROUP4] Priting current queue:\n");
|
||||
+ list_for_each_entry(iter, &nd->queue, queuelist) {
|
||||
+ printk(KERN_DEBUG "[SSTF_GROUP4] Item: %lu\n",
|
||||
+ (unsigned long) blk_rq_pos(iter));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Name: sstf_former_request
|
||||
+ * Description: stores former request in queue
|
||||
+ * Parameters: request queue, request
|
||||
+ */
|
||||
+static struct request *sstf_former_request(struct request_queue *queue,
|
||||
+ struct request *req)
|
||||
+{
|
||||
+ struct sstf_data *data = queue->elevator->elevator_data;
|
||||
+
|
||||
+ if(req->queuelist.prev == &data->queue)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return list_entry(req->queuelist.prev, struct request, queuelist);
|
||||
+}
|
||||
+
|
||||
+/* Name: sstf_latter_request
|
||||
+ * Description: stores latter request in queue
|
||||
+ * Parameters: request queue, request
|
||||
+ */
|
||||
+static struct request *sstf_latter_request(struct request_queue *queue,
|
||||
+ struct request *req)
|
||||
+{
|
||||
+ struct sstf_data *data = queue->elevator->elevator_data;
|
||||
+
|
||||
+ if(req->queuelist.next == &data->queue)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return list_entry(req->queuelist.next, struct request, queuelist);
|
||||
+}
|
||||
+
|
||||
+/* Name: sstf_init_queue
|
||||
+ * Description: Initializes the queue
|
||||
+ * Parameters: Request queue, Elevator
|
||||
+ */
|
||||
+static int sstf_init_queue(struct request_queue *queue,
|
||||
+ struct elevator_type *elev)
|
||||
+{
|
||||
+ struct sstf_data *data;
|
||||
+ struct elevator_queue *elevque;
|
||||
+
|
||||
+ elevque = elevator_alloc(queue, elev);
|
||||
+
|
||||
+ if(!elevque)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data = kmalloc_node(sizeof(*data), GFP_KERNEL, queue->node);
|
||||
+
|
||||
+ if(!data){
|
||||
+ kobject_put(&elevque->kobj);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ data->head = 0;
|
||||
+ elevque->elevator_data = data;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&data->queue);
|
||||
+
|
||||
+ spin_lock_irq(queue->queue_lock);
|
||||
+ queue->elevator = elevque;
|
||||
+ spin_unlock_irq(queue->queue_lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Name: sstf_exit_queue
|
||||
+ * Description: exits the queue
|
||||
+ * Parameters: elevator
|
||||
+ */
|
||||
+static void sstf_exit_queue(struct elevator_queue *elev)
|
||||
+{
|
||||
+ struct sstf_data *data = elev->elevator_data;
|
||||
+
|
||||
+ BUG_ON(!list_empty(&data->queue));
|
||||
+ kfree(data);
|
||||
+}
|
||||
+
|
||||
+static struct elevator_type elevator_sstf = {
|
||||
+ .ops = {
|
||||
+ .elevator_init_fn = sstf_init_queue,
|
||||
+ .elevator_add_req_fn = sstf_add_request,
|
||||
+ .elevator_former_req_fn = sstf_former_request,
|
||||
+ .elevator_latter_req_fn = sstf_latter_request,
|
||||
+ .elevator_merge_req_fn = sstf_merge_requests,
|
||||
+ .elevator_dispatch_fn = sstf_dispatch,
|
||||
+ .elevator_exit_fn = sstf_exit_queue,
|
||||
+ },
|
||||
+ .elevator_name = "sstf",
|
||||
+ .elevator_owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+/* Name: elev_init
|
||||
+ * Description: Initializes the elevator
|
||||
+ * Parameters: N/A
|
||||
+ */
|
||||
+static int __init elev_init(void)
|
||||
+{
|
||||
+ return elv_register(&elevator_sstf);
|
||||
+}
|
||||
+
|
||||
+/* Name: elev_exit
|
||||
+ * Description: exits out of the elevator
|
||||
+ * Parameters: N/A
|
||||
+ */
|
||||
+static void __exit elev_exit(void)
|
||||
+{
|
||||
+ elv_unregister(&elevator_sstf);
|
||||
+}
|
||||
+
|
||||
+module_init(elev_init);
|
||||
+module_exit(elev_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Corwin Perren, Corinna Brown");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DESCRIPTION("SSTF IO Scheduler");
|
||||
@@ -0,0 +1,105 @@
|
||||
\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran}
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{{./figures/}}
|
||||
|
||||
\usepackage{url}
|
||||
\usepackage{setspace}
|
||||
\usepackage{multicol}
|
||||
\usepackage{pdflscape}
|
||||
\usepackage{pdfpages}
|
||||
\usepackage[british]{babel}
|
||||
\usepackage{listings}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{listings}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{subfig}
|
||||
|
||||
\usepackage{geometry}
|
||||
\geometry{textheight=9.5in, textwidth=7in}
|
||||
|
||||
% \overfullrule=2in
|
||||
|
||||
|
||||
%Personal \newcommands
|
||||
|
||||
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
|
||||
\lstset{basicstyle=\ttfamily,
|
||||
backgroundcolor=\color{backcolor},
|
||||
showstringspaces=false,
|
||||
commentstyle=\color{red},
|
||||
keywordstyle=\color{blue},
|
||||
columns=fullflexible,
|
||||
breaklines=true,
|
||||
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
|
||||
}
|
||||
|
||||
\newcommand{\NameSigPair}[1]{
|
||||
\par
|
||||
\makebox[2.75in][r]{#1}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in]{\hrulefill}
|
||||
\hfill
|
||||
\makebox[.75in]{\hrulefill}
|
||||
}
|
||||
\par\vspace{-12pt}
|
||||
\textit{
|
||||
\tiny\noindent
|
||||
\makebox[2.75in]{}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in][r]{Signature}
|
||||
\hfill
|
||||
\makebox[.75in][r]{Date}
|
||||
}
|
||||
}
|
||||
}
|
||||
% 3. If the document is not to be signed, uncomment the command below
|
||||
\renewcommand{\NameSigPair}[1]{#1}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
\pagenumbering{gobble}
|
||||
\begin{singlespace}
|
||||
\par\vspace{2in}
|
||||
\centering
|
||||
\scshape{
|
||||
\huge Operating Systems II Homework 2 \par
|
||||
{\large\today}\par
|
||||
\vspace{.5in}
|
||||
\vfill
|
||||
\vspace{5pt}
|
||||
{\large Prepared by }\par
|
||||
Group 4 \par
|
||||
% 5. comment out the line below this one if you do not wish to name your team
|
||||
\vspace{5pt}
|
||||
{\Large
|
||||
\NameSigPair{Corinna Brown}\par
|
||||
\NameSigPair{Corwin Perren}\par
|
||||
}
|
||||
\vspace{20pt}
|
||||
\begin{abstract}
|
||||
The document is our groups submission for homework two covering the design of our solution, answers to explicit assignment questions, a version control log, and a work log.
|
||||
|
||||
|
||||
\end{abstract}
|
||||
}
|
||||
\end{singlespace}
|
||||
\end{titlepage}
|
||||
\newpage
|
||||
\pagenumbering{arabic}
|
||||
\tableofcontents
|
||||
\clearpage
|
||||
|
||||
\input{design}
|
||||
\input{questions}
|
||||
\input{versioncontrollog}
|
||||
\input{worklog}
|
||||
|
||||
\end{document}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import random
|
||||
import os, shutil
|
||||
|
||||
NUM_READ_WRITES = 10
|
||||
NUM_FILES = 100
|
||||
|
||||
RANDOM_PATH = "/dev/zero"
|
||||
dev_random = open(RANDOM_PATH, "r")
|
||||
|
||||
FILES_FOLDER = "files"
|
||||
|
||||
file_test_structure = {
|
||||
"file": None,
|
||||
"size": None
|
||||
}
|
||||
|
||||
ALL_FILES = []
|
||||
|
||||
if os.path.isdir(FILES_FOLDER):
|
||||
shutil.rmtree(FILES_FOLDER)
|
||||
|
||||
os.mkdir(FILES_FOLDER)
|
||||
|
||||
for i in range(NUM_FILES):
|
||||
temp = dict(file_test_structure)
|
||||
|
||||
temp["file"] = open(FILES_FOLDER + "/" + str(i)+ ".txt", "w+")
|
||||
temp["size"] = random.randint(1000000, 10000000)
|
||||
ALL_FILES.append(temp)
|
||||
|
||||
|
||||
for i in range(NUM_READ_WRITES):
|
||||
for j in range(NUM_FILES):
|
||||
current_file = ALL_FILES[j]
|
||||
current_file["file"].seek(0)
|
||||
current_file["file"].write(dev_random.read(current_file["size"]))
|
||||
|
||||
for j in range(NUM_FILES):
|
||||
current_file = ALL_FILES[j]
|
||||
current_file["file"].seek(0)
|
||||
current_file["file"].read(current_file["size"])
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
# This config is copied from overleaf so output there will match compiled output here
|
||||
|
||||
# support for the glossaries package:
|
||||
add_cus_dep('glo', 'gls', 0, 'makeglossaries');
|
||||
add_cus_dep('acn', 'acr', 0, 'makeglossaries');
|
||||
sub makeglossaries {
|
||||
system("makeglossaries \"$_[0]\"");
|
||||
}
|
||||
|
||||
# support for the nomencl package:
|
||||
add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
|
||||
sub makenlo2nls {
|
||||
system("makeindex -s nomencl.ist -o \"$_[0].nls\" \"$_[0].nlo\"");
|
||||
}
|
||||
|
||||
# from the documentation for V. 2.03 of asymptote:
|
||||
sub asy {return system("asy \"$_[0]\"");}
|
||||
add_cus_dep("asy","eps",0,"asy");
|
||||
add_cus_dep("asy","pdf",0,"asy");
|
||||
add_cus_dep("asy","tex",0,"asy");
|
||||
|
||||
# metapost rule from http://tex.stackexchange.com/questions/37134
|
||||
add_cus_dep('mp', '1', 0, 'mpost');
|
||||
sub mpost {
|
||||
my $file = $_[0];
|
||||
my ($name, $path) = fileparse($file);
|
||||
pushd($path);
|
||||
my $return = system "mpost $name";
|
||||
popd();
|
||||
return $return;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# Makefile created by Corwin Perren
|
||||
# Generic makefile for all LaTeX projects downloaded from overleaf
|
||||
#
|
||||
# All this makefile does is call perl against latexmkrc, which is
|
||||
# the latex equivalent of make
|
||||
|
||||
LATEXMK_COMPILE_FLAGS = -cd -pdf homework2.tex
|
||||
LATEXMK_CLEAN_FLAGS = -c
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
all: latexmk_output clean
|
||||
|
||||
latexmk_output:
|
||||
perl latexmk.pl $(LATEXMK_COMPILE_FLAGS)
|
||||
mv homework2.pdf CS444_project2_4.pdf
|
||||
|
||||
clean:
|
||||
perl latexmk.pl $(LATEXMK_CLEAN_FLAGS)
|
||||
@@ -0,0 +1,19 @@
|
||||
\section{Questions}
|
||||
\subsection{Point of Assignment}
|
||||
The point of this assignment was to explore the way that elevator algorithms are implemented as well as getting acquainted with going through all the steps needed to make and apply changes to Linux kernel modules. This required looking through the kernel elevator source files and performing research to determine how to adapt our elevator algorithm. Additionally, this assignment was an initial experience creating a patch for the Linux kernel.
|
||||
|
||||
\subsection{Problem Approach}
|
||||
We approached this problem by first reading through the Homework 2 page on Canvas and reading through the information on the noop and LOOK/CLOOK algorithms on the "I/O and provided functionality" page on Canvas. Next the "noop-iosched.c" file was copied to "sstf-iosched.c" and all references to noop were changed to sstf. Research was then performed to figure out how to get the kernel to compile, recognize, and use this scheduler. The "noop-iosched.c" file and the files it is dependent on were also explored to learn how this scheduling algorithm was implemented.
|
||||
|
||||
After this initial set-up and research, it was decided to implement the LOOK algorithm because it is the more efficient algorithm that seemed like a better choice, especially in real world use cases. In order to ensure that the queue is sorted, insertion sort is used for each of the new items added. Printk statements were placed in the queue add function to ensure that printed results of the queue's state matched what was expected from the LOOK algorithm.
|
||||
|
||||
\subsection{Correctness}
|
||||
We know that the end result was correct by using the output of the printk function calls mentioned above to log the blocks for each request as they were added and dispatched. We also added printouts of the whole queue each time an entry was added, to ensure that the entry was placed in the expected location. With these statements on the screen, verifying correctness was as simple as making sure block numbers in the queue were being added in such that if the head were on its way "up" or "down", that the data in the queue matched the current direction.
|
||||
|
||||
To ensure that the implementation worked for all reasonable accesses of the drive, a python script was written to generate many randomly sized files, as well as to randomly read this data back. By changing the number of times that the randomly generated files were read/written we were able to test the scheduler until varying scenarios of use.
|
||||
|
||||
\subsection{What Was Learned}
|
||||
We learned that documentation is extremely important to code development as it allows readers to more easily use code that has already been written. There are not many comments in the "noop-iosched.c" or the "elevator.c" file to describe how the various functions work, and this made it difficult to understand exactly how the previously written code functioned. We also learned that it can be challenging to debug while working with the kernel because sometimes the only error that you see is that the kernel does not boot, at which point using the GDB debugger is needed.
|
||||
|
||||
\subsection{How to Evaluate}
|
||||
After applying the patch file, building the kernel, and booting the VM, you should be able to see prints to the screen once the scheduler is loaded and applied to the main boot device /dev/hda. At this point, there were be a few different kinds of statements to look out for. The first will start with "[SSTF\_GROUP4] Adding ...." that will tell you when a new item is being added to the queue, what block number the access is for, and whether this is a read or write. After these add prints there will be a printout of the whole elevator queue that will immediately allow you to see where the new entry was placed in the queue. Once the system is ready for a dispatch, the kernel will also print a statement starting with "[SSTF\_GROUP4] Dispatching:..." telling you what block is being dispatched, and whether it's a read or write. By watching changes to these statements as the kernel is booting, or by using a program to generate IO, correctness of the implementation can easily be verified. We have included the python file io\_test.py in our tarball if you want to use it to generate the IO that we did for testing.
|
||||
@@ -0,0 +1,15 @@
|
||||
\section{Version Control Log}
|
||||
\begin{center}
|
||||
\begin{tabular}{l l l l} \textbf{Detail} & \textbf{Author} & \textbf{Date} &\textbf{Description}\\\hline
|
||||
|
||||
\href{.//commit/9aba09af70810709d27af320d740e677c498b79f}{9aba09a} & Corwin Perren & 2018-05-04 17:33:16 -0700 &Refactored for easier development. Added initial sstf file. Tested kernel change name. Started virtual machine as ide drive.\\\hline
|
||||
\href{.//commit/07b427a502f82dd300e79f2bce18a2f56a65fc55}{07b427a} & Corwin Perren & 2018-05-04 18:14:07 -0700 &Compiled sstf. Added untouched directory to gitignore so it doesn't have to check it each time\\\hline
|
||||
\href{.//commit/690e1a6793997bea1e327810eca7dd2838b131a3}{690e1a6} & Corwin Perren & 2018-05-04 20:31:36 -0700 &Works, but is confusing\\\hline
|
||||
\href{.//commit/9b48e6ccf10fa5b356e2ce6f1ef185c8af0c3e8b}{9b48e6c} & Corwin Perren & 2018-05-05 14:57:26 -0700 &Added new version of sstf. Removed unneeded files.\\\hline
|
||||
\href{.//commit/ce39f4775a5172d033dcd86a0ac0613af748830b}{ce39f47} & Corwin Perren & 2018-05-05 16:38:26 -0700 &Final version of homework 2\\\hline
|
||||
\href{.//commit/58376ddc3bb9791d8c277ef5612118bbe6522f55}{58376dd} & Corwin Perren & 2018-05-05 17:39:40 -0700 &Added patch file for homework2\\\hline
|
||||
|
||||
|
||||
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
@@ -0,0 +1,17 @@
|
||||
\section{Work Log}
|
||||
\begin{itemize}
|
||||
\item 2018-05-04
|
||||
\begin{itemize}
|
||||
\item Group met in Valley Library
|
||||
\item Started Latex document for Homework 2
|
||||
\item Copied noop elevator
|
||||
\item Figured out how to get the kernel to use the new elevator
|
||||
\item Started implementing the LOOK algorithm
|
||||
\end{itemize}
|
||||
\item 2018-05-05
|
||||
\begin{itemize}
|
||||
\item Group met in Valley Library
|
||||
\item Finished implementing the LOOK algorithm
|
||||
\item Created patch file
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
\section{Design}
|
||||
The framework for the device driver was taken from the "simple block device" from the website: http://blog.superpat.com/2010/05/04/a-simple-block-driver-for-linux-kernel-2-6-31/. The following changes were then needed to add crypto functionality:
|
||||
\begin{itemize}
|
||||
\item Addition of cipher
|
||||
\item Addition of cipher key
|
||||
\item Addition of module parameter for the key
|
||||
\item Change the read and write functionality so that the encryption and decryption occurs as the reads and writes happen
|
||||
\end{itemize}
|
||||
|
||||
The following psuedocode describes how the read and write functionality with encryption and decryption was implemented:
|
||||
\begin{lstlisting}[lineskip=3pt,keywords={if,else,while}]
|
||||
if (write) {
|
||||
for(iterate through desired length) {
|
||||
encrypt using crypto_cipher_encrypt_one()
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(iterate through desired length) {
|
||||
decrypt using crypto_cipher_decrypt_one()
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
@@ -0,0 +1,254 @@
|
||||
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/drivers/block/encrypted_block_device.c linux-yocto-3.19.2/drivers/block/encrypted_block_device.c
|
||||
--- linux-yocto-3.19.2_untouched/drivers/block/encrypted_block_device.c 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ linux-yocto-3.19.2/drivers/block/encrypted_block_device.c 2018-05-16 21:34:04.762216256 -0700
|
||||
@@ -0,0 +1,226 @@
|
||||
+/*
|
||||
+ * Encrypted block driver by Corinna Brown and Corwin Perren
|
||||
+ *
|
||||
+ * Core code pulled from the following link
|
||||
+ * http://blog.superpat.com/2010/05/04/a-simple-block-driver-for-linux-kernel-2-6-31/
|
||||
+ *
|
||||
+ * A sample, extra-simple block driver. Updated for kernel 2.6.31.
|
||||
+ *
|
||||
+ * (C) 2003 Eklektix, Inc.
|
||||
+ * (C) 2010 Pat Patterson <pat at superpat dot com>
|
||||
+ * Redistributable under the terms of the GNU GPL.
|
||||
+ */
|
||||
+
|
||||
+ #include <linux/module.h>
|
||||
+ #include <linux/moduleparam.h>
|
||||
+ #include <linux/init.h>
|
||||
+
|
||||
+ #include <linux/kernel.h> /* printk() */
|
||||
+ #include <linux/fs.h> /* everything... */
|
||||
+ #include <linux/errno.h> /* error codes */
|
||||
+ #include <linux/types.h> /* size_t */
|
||||
+ #include <linux/vmalloc.h>
|
||||
+ #include <linux/genhd.h>
|
||||
+ #include <linux/blkdev.h>
|
||||
+ #include <linux/hdreg.h>
|
||||
+ #include <linux/crypto.h>
|
||||
+
|
||||
+MODULE_LICENSE("Dual BSD/GPL");
|
||||
+static char *Version = "1.4";
|
||||
+
|
||||
+static int major_num = 0;
|
||||
+module_param(major_num, int, 0);
|
||||
+static int logical_block_size = 512;
|
||||
+module_param(logical_block_size, int, 0);
|
||||
+static int nsectors = 1024; /* How big the drive is */
|
||||
+module_param(nsectors, int, 0);
|
||||
+
|
||||
+/* Cryptography Assignment Variables */
|
||||
+
|
||||
+struct crypto_cipher *custom_cipher;
|
||||
+
|
||||
+static char *custom_cipher_key = "3a84e1ac6b54ca";
|
||||
+module_param(custom_cipher_key, charp, 0644);
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * We can tweak our hardware sector size, but the kernel talks to us
|
||||
+ * in terms of small sectors, always.
|
||||
+ */
|
||||
+#define KERNEL_SECTOR_SIZE 512
|
||||
+
|
||||
+/*
|
||||
+ * Our request queue.
|
||||
+ */
|
||||
+static struct request_queue *Queue;
|
||||
+
|
||||
+/*
|
||||
+ * The internal representation of our device.
|
||||
+ */
|
||||
+static struct sbd_device {
|
||||
+ unsigned long size;
|
||||
+ spinlock_t lock;
|
||||
+ u8 *data;
|
||||
+ struct gendisk *gd;
|
||||
+} Device;
|
||||
+
|
||||
+/*
|
||||
+ * Handle an I/O request.
|
||||
+ */
|
||||
+static void sbd_transfer(struct sbd_device *dev, sector_t sector,
|
||||
+ unsigned long nsect, char *buffer, int write) {
|
||||
+ unsigned long offset = sector * logical_block_size;
|
||||
+ unsigned long nbytes = nsect * logical_block_size;
|
||||
+
|
||||
+ unsigned char *device_buffer = dev->data + offset;
|
||||
+ unsigned char *request_buffer = buffer;
|
||||
+ int i;
|
||||
+
|
||||
+ int custom_cipher_length = sizeof(custom_cipher_key) /
|
||||
+ sizeof(custom_cipher_key[0]);
|
||||
+
|
||||
+ printk("##[GROUP4]## Custom cipher key is %s\n", custom_cipher_key);
|
||||
+ crypto_cipher_setkey(custom_cipher, custom_cipher_key, custom_cipher_length);
|
||||
+
|
||||
+ if ((offset + nbytes) > dev->size) {
|
||||
+ printk (KERN_NOTICE "sbd: Beyond-end write (%ld %ld)\n", offset, nbytes);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ printk("##[GROUP4]## Module is: %s\n", write ? "WRITING" : "READING");
|
||||
+ if (write)
|
||||
+ {
|
||||
+ for (i = 0; i < nbytes; i+= crypto_cipher_blocksize(custom_cipher)) {
|
||||
+ crypto_cipher_encrypt_one(custom_cipher, device_buffer + i,
|
||||
+ request_buffer + i);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ for (i = 0; i < nbytes; i+= crypto_cipher_blocksize(custom_cipher)) {
|
||||
+ crypto_cipher_decrypt_one(custom_cipher, request_buffer + i,
|
||||
+ device_buffer + i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ printk("##[GROUP4]## Encrypted Bytes ##\n");
|
||||
+ for (i = 0; i < nbytes; i++) {
|
||||
+ printk("%u", (unsigned) *device_buffer++);
|
||||
+ }
|
||||
+ printk("\n");
|
||||
+
|
||||
+ printk("##[GROUP4]## Unencrypted Bytes ##\n");
|
||||
+ for (i = 0; i < nbytes; i++) {
|
||||
+ printk("%u", (unsigned) *request_buffer++);
|
||||
+ }
|
||||
+ printk("\n\n");
|
||||
+}
|
||||
+
|
||||
+static void sbd_request(struct request_queue *q) {
|
||||
+ struct request *req;
|
||||
+
|
||||
+ req = blk_fetch_request(q);
|
||||
+ while (req != NULL) {
|
||||
+ // blk_fs_request() was removed in 2.6.36 - many thanks to
|
||||
+ // Christian Paro for the heads up and fix...
|
||||
+ //if (!blk_fs_request(req)) {
|
||||
+ if (req == NULL || (req->cmd_type != REQ_TYPE_FS)) {
|
||||
+ printk (KERN_NOTICE "Skip non-CMD request\n");
|
||||
+ __blk_end_request_all(req, -EIO);
|
||||
+ continue;
|
||||
+ }
|
||||
+ sbd_transfer(&Device, blk_rq_pos(req), blk_rq_cur_sectors(req),
|
||||
+ bio_data(req->bio), rq_data_dir(req));
|
||||
+ if ( ! __blk_end_request_cur(req, 0) ) {
|
||||
+ req = blk_fetch_request(q);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * The HDIO_GETGEO ioctl is handled in blkdev_ioctl(), which
|
||||
+ * calls this. We need to implement getgeo, since we can't
|
||||
+ * use tools such as fdisk to partition the drive otherwise.
|
||||
+ */
|
||||
+int sbd_getgeo(struct block_device * block_device, struct hd_geometry * geo) {
|
||||
+ long size;
|
||||
+
|
||||
+ /* We have no real geometry, of course, so make something up. */
|
||||
+ size = Device.size * (logical_block_size / KERNEL_SECTOR_SIZE);
|
||||
+ geo->cylinders = (size & ~0x3f) >> 6;
|
||||
+ geo->heads = 4;
|
||||
+ geo->sectors = 16;
|
||||
+ geo->start = 0;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * The device operations structure.
|
||||
+ */
|
||||
+static struct block_device_operations sbd_ops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .getgeo = sbd_getgeo
|
||||
+};
|
||||
+
|
||||
+static int __init sbd_init(void) {
|
||||
+ /* Initialize our cipher_key */
|
||||
+ custom_cipher = crypto_alloc_cipher("aes", 0, 0);
|
||||
+
|
||||
+ /*
|
||||
+ * Set up our internal device.
|
||||
+ */
|
||||
+ Device.size = nsectors * logical_block_size;
|
||||
+ spin_lock_init(&Device.lock);
|
||||
+ Device.data = vmalloc(Device.size);
|
||||
+ if (Device.data == NULL)
|
||||
+ return -ENOMEM;
|
||||
+ /*
|
||||
+ * Get a request queue.
|
||||
+ */
|
||||
+ Queue = blk_init_queue(sbd_request, &Device.lock);
|
||||
+ if (Queue == NULL)
|
||||
+ goto out;
|
||||
+ blk_queue_logical_block_size(Queue, logical_block_size);
|
||||
+ /*
|
||||
+ * Get registered.
|
||||
+ */
|
||||
+ major_num = register_blkdev(major_num, "sbd");
|
||||
+ if (major_num < 0) {
|
||||
+ printk(KERN_WARNING "sbd: unable to get major number\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /*
|
||||
+ * And the gendisk structure.
|
||||
+ */
|
||||
+ Device.gd = alloc_disk(16);
|
||||
+ if (!Device.gd)
|
||||
+ goto out_unregister;
|
||||
+ Device.gd->major = major_num;
|
||||
+ Device.gd->first_minor = 0;
|
||||
+ Device.gd->fops = &sbd_ops;
|
||||
+ Device.gd->private_data = &Device;
|
||||
+ strcpy(Device.gd->disk_name, "sbd0");
|
||||
+ set_capacity(Device.gd, nsectors);
|
||||
+ Device.gd->queue = Queue;
|
||||
+ add_disk(Device.gd);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_unregister:
|
||||
+ unregister_blkdev(major_num, "sbd");
|
||||
+out:
|
||||
+ vfree(Device.data);
|
||||
+ return -ENOMEM;
|
||||
+}
|
||||
+
|
||||
+static void __exit sbd_exit(void)
|
||||
+{
|
||||
+ del_gendisk(Device.gd);
|
||||
+ put_disk(Device.gd);
|
||||
+ unregister_blkdev(major_num, "sbd");
|
||||
+ blk_cleanup_queue(Queue);
|
||||
+ vfree(Device.data);
|
||||
+}
|
||||
+
|
||||
+module_init(sbd_init);
|
||||
+module_exit(sbd_exit);
|
||||
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/drivers/block/Kconfig linux-yocto-3.19.2/drivers/block/Kconfig
|
||||
--- linux-yocto-3.19.2_untouched/drivers/block/Kconfig 2018-05-04 15:14:54.159243368 -0700
|
||||
+++ linux-yocto-3.19.2/drivers/block/Kconfig 2018-05-16 19:58:45.301219285 -0700
|
||||
@@ -15,6 +15,9 @@
|
||||
|
||||
if BLK_DEV
|
||||
|
||||
+config BLK_DEV_EBD
|
||||
+ tristate "Homework group4 encrypted block device driver."
|
||||
+
|
||||
config BLK_DEV_NULL_BLK
|
||||
tristate "Null test block driver"
|
||||
|
||||
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/drivers/block/Makefile linux-yocto-3.19.2/drivers/block/Makefile
|
||||
--- linux-yocto-3.19.2_untouched/drivers/block/Makefile 2018-05-04 15:14:54.159243368 -0700
|
||||
+++ linux-yocto-3.19.2/drivers/block/Makefile 2018-05-16 19:59:05.919571039 -0700
|
||||
@@ -30,6 +30,7 @@
|
||||
obj-$(CONFIG_BLK_DEV_NBD) += nbd.o
|
||||
obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
|
||||
obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
|
||||
+obj-$(CONFIG_BLK_DEV_EBD) += encrypted_block_device.o
|
||||
|
||||
obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
|
||||
obj-$(CONFIG_BLK_DEV_HD) += hd.o
|
||||
@@ -0,0 +1,98 @@
|
||||
\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran}
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{{./figures/}}
|
||||
|
||||
\usepackage{url}
|
||||
\usepackage{setspace}
|
||||
\usepackage{multicol}
|
||||
\usepackage{pdflscape}
|
||||
\usepackage{pdfpages}
|
||||
\usepackage[british]{babel}
|
||||
\usepackage{listings}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{listings}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{subfig}
|
||||
|
||||
\usepackage{geometry}
|
||||
\geometry{textheight=9.5in, textwidth=7in}
|
||||
|
||||
% \overfullrule=2in
|
||||
|
||||
|
||||
%Personal \newcommands
|
||||
|
||||
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
|
||||
\lstset{basicstyle=\ttfamily,
|
||||
backgroundcolor=\color{backcolor},
|
||||
showstringspaces=false,
|
||||
commentstyle=\color{red},
|
||||
keywordstyle=\color{blue},
|
||||
columns=fullflexible,
|
||||
breaklines=true,
|
||||
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
|
||||
}
|
||||
|
||||
\newcommand{\NameSigPair}[1]{
|
||||
\par
|
||||
\makebox[2.75in][r]{#1}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in]{\hrulefill}
|
||||
\hfill
|
||||
\makebox[.75in]{\hrulefill}
|
||||
}
|
||||
\par\vspace{-12pt}
|
||||
\textit{
|
||||
\tiny\noindent
|
||||
\makebox[2.75in]{}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in][r]{Signature}
|
||||
\hfill
|
||||
\makebox[.75in][r]{Date}
|
||||
}
|
||||
}
|
||||
}
|
||||
% 3. If the document is not to be signed, uncomment the command below
|
||||
\renewcommand{\NameSigPair}[1]{#1}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
\pagenumbering{gobble}
|
||||
\begin{singlespace}
|
||||
\par\vspace{2in}
|
||||
\centering
|
||||
\scshape{
|
||||
\huge Operating Systems II Homework 3 \par
|
||||
{\large\today}\par
|
||||
\vspace{.5in}
|
||||
\vfill
|
||||
\vspace{5pt}
|
||||
{\large Prepared by }\par
|
||||
Group 4 \par
|
||||
% 5. comment out the line below this one if you do not wish to name your team
|
||||
\vspace{5pt}
|
||||
{\Large
|
||||
\NameSigPair{Corinna Brown}\par
|
||||
\NameSigPair{Corwin Perren}\par
|
||||
}
|
||||
\vspace{20pt}
|
||||
\begin{abstract}
|
||||
The document is our group's submission for homework three covering the design of our solution, answers to explicit assignment questions, a version control log, and a work log.
|
||||
\end{abstract}
|
||||
}
|
||||
\end{singlespace}
|
||||
\end{titlepage}
|
||||
\newpage
|
||||
\pagenumbering{arabic}
|
||||
\tableofcontents
|
||||
\clearpage
|
||||
|
||||
\input{design}
|
||||
\input{questions}
|
||||
\input{versioncontrollog}
|
||||
\input{worklog}
|
||||
|
||||
\end{document}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
# This config is copied from overleaf so output there will match compiled output here
|
||||
|
||||
# support for the glossaries package:
|
||||
add_cus_dep('glo', 'gls', 0, 'makeglossaries');
|
||||
add_cus_dep('acn', 'acr', 0, 'makeglossaries');
|
||||
sub makeglossaries {
|
||||
system("makeglossaries \"$_[0]\"");
|
||||
}
|
||||
|
||||
# support for the nomencl package:
|
||||
add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
|
||||
sub makenlo2nls {
|
||||
system("makeindex -s nomencl.ist -o \"$_[0].nls\" \"$_[0].nlo\"");
|
||||
}
|
||||
|
||||
# from the documentation for V. 2.03 of asymptote:
|
||||
sub asy {return system("asy \"$_[0]\"");}
|
||||
add_cus_dep("asy","eps",0,"asy");
|
||||
add_cus_dep("asy","pdf",0,"asy");
|
||||
add_cus_dep("asy","tex",0,"asy");
|
||||
|
||||
# metapost rule from http://tex.stackexchange.com/questions/37134
|
||||
add_cus_dep('mp', '1', 0, 'mpost');
|
||||
sub mpost {
|
||||
my $file = $_[0];
|
||||
my ($name, $path) = fileparse($file);
|
||||
pushd($path);
|
||||
my $return = system "mpost $name";
|
||||
popd();
|
||||
return $return;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# Makefile created by Corwin Perren
|
||||
# Generic makefile for all LaTeX projects downloaded from overleaf
|
||||
#
|
||||
# All this makefile does is call perl against latexmkrc, which is
|
||||
# the latex equivalent of make
|
||||
|
||||
LATEXMK_COMPILE_FLAGS = -cd -pdf homework3.tex
|
||||
LATEXMK_CLEAN_FLAGS = -c
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
all: latexmk_output clean
|
||||
|
||||
latexmk_output:
|
||||
perl latexmk.pl $(LATEXMK_COMPILE_FLAGS)
|
||||
mv homework3.pdf CS444_project3_4.pdf
|
||||
|
||||
clean:
|
||||
perl latexmk.pl $(LATEXMK_CLEAN_FLAGS)
|
||||
@@ -0,0 +1,17 @@
|
||||
\section{Questions}
|
||||
\subsection{Point of Assignment}
|
||||
The main point of this assignment was to gain experience working with device drivers and the Linux kernel crypto API. To accomplish this, a lot of research was necessary. Learning how to perform research and finding good sources for the future are also benefits of this assignment. Finally, the assignment provided experience working with module parameters.
|
||||
|
||||
\subsection{Problem Approach}
|
||||
We approached this problem by first reading through the Homework 3 page on Canvas. Then we separated the assignment into three main concepts, the device driver, crypto, and the module.
|
||||
|
||||
First we decided to implement the device driver. As suggested on the Canvas page, "SBD" was researched and an example of a sample block device was found at http://blog.superpat.com/2010/05/04/a-simple-block-driver-for-linux-kernel-2-6-31/. After some adjustments to ensure it was compatible with the version of the kernel we are using, the device driver was tested. After ensuring correct functionality of the device driver, the Linux kernel crypto API was researched. This mainly involved looking through the crypto.h file to find the functions that are available. After finding the functions we wished to use, the device driver was adapted to encrypt and decrypt data at the time that it is read or written. Finally, we added the cipher key as a module parameter. While performing the crypto development,the module was loaded as a built-in module at boot time. Once kernel parameters were added, the driver was compiled as an add-in module, scp'd to the virtual machine, installed into the kernel directories, and loaded with varying parameters as needed for testing.
|
||||
|
||||
\subsection{Correctness}
|
||||
We know that the end result was correct by first using the output of printk function calls to look at the cipher key, the current state (reading or writing), the encrypted bytes, and the unencrypted bytes. This allowed us to see what the encrypted data looked like and ensure that the encryption and decryption was being done correctly. Then we moved our block device to a module to test the module parameter. To test this, we used different cipher keys with the same input data to show that the output data changes with the different cipher keys. Lastly, we were able to verify that the driver was working correctly by directly reading data from the /dev/sdb0 device. Reading from the device directly always returned garbage encrypted data unlike when reading from the mounted directory using our driver.
|
||||
|
||||
\subsection{What Was Learned}
|
||||
We again learned that documentation is extremely important to code development as it allows readers to more easily use code that has already been written. We also learned the basics of how to use the Linux kernel crypto API as well as the basics of writing device drivers.
|
||||
|
||||
\subsection{How to Evaluate}
|
||||
After applying the patch file using patch -p1 $<$ homework3.patch from the root of the kernel directory, building the kernel, and launching the vm, you should immediately see printk statements showing the output of the driver. Once booted, a filesystem can be made per the assignment instructions and mounted to a folder using the mount command. By reading and writing data to the mounted drive and watching printk output, you will easily be able to see that the encrypted data is different than the unencrypted data. For more in depth evaluation, a boot time kernel parameter can be set with the command "encrypted\_boot\_device.custom\_cipher\_key=yourkey" to change the module parameter. Then, by following the process above with identical data input as before, you can see the printk statements for encrypted data output differing data than with the default key.
|
||||
@@ -0,0 +1,8 @@
|
||||
\section{Version Control Log}
|
||||
\begin{center}
|
||||
\begin{tabular}{l l l l} \textbf{Detail} & \textbf{Author} & \textbf{Date} &\textbf{Description}\\\hline
|
||||
|
||||
\href{.//commit/34ba569ad1c705e8d6054e20f0a129a21d2bc0c1}{34ba569} & Corwin Perren & 2018-05-16 21:45:55 -0700 &Finished homework 3\\\hline
|
||||
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
@@ -0,0 +1,14 @@
|
||||
\section{Work Log}
|
||||
\begin{itemize}
|
||||
\item 2018-05-16
|
||||
\begin{itemize}
|
||||
\item Group met in Valley Library
|
||||
\item Started Latex document for Homework 3
|
||||
\item Found an example of a sbd
|
||||
\item Updated sbd to work with correct kernel version
|
||||
\item Researched Linux kernel API and searched through crypto.h
|
||||
\item Added crypto functionality to the device driver
|
||||
\item Added module parameter
|
||||
\item Tested module
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
\section{Design}
|
||||
In order to implement a best-fit version of the slob, we're going to need to modify the functions slob\_alloc and slob\_page\_alloc in "slob.c". From a high level, the biggest change that needs to be made is for slob\_alloc to have an understanding of which of its pages have a block that is best sized for the allocation that is requested. This will involve not only finding a page with free blocks available, but going through all pages with free blocks available, and then choosing the page and block that is larger than, but closest to the size of the requested allocation. If along the way, we encounter a page with a block that is exactly the size we need, we can immediately choose that as the allocation point as you can't get better than perfectly sized. In the event that there are no pages with blocks available to store the requested size of allocation, the default creation of a new page will occur, providing an empty chunk of memory that will have enough space.
|
||||
|
||||
Changes to slob\_alloc:
|
||||
\begin{lstlisting}[lineskip=3pt,keywords={if,else,while,for}]
|
||||
for each page
|
||||
//section "Enough room on this page?"
|
||||
check size of all blocks on current page
|
||||
|
||||
if (no space large enough on this page) {
|
||||
continue
|
||||
}
|
||||
if (any block has a perfect fit) {
|
||||
store page
|
||||
break
|
||||
}
|
||||
else if (any block has a fit better than current best fit) {
|
||||
store page
|
||||
}
|
||||
|
||||
if (found page with block with space) {
|
||||
allocate the space
|
||||
} else {
|
||||
create a new page
|
||||
}
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Changes to slob\_page\_alloc:
|
||||
\begin{itemize}
|
||||
\item Separate the original function so that it finds the best block (using same logic as find\_closest\_block\_size\_in\_page) and then allocates that block
|
||||
\item Take out "room enough" section because we already know there is room
|
||||
\end{itemize}
|
||||
|
||||
find\_closest\_block\_size\_in\_page:
|
||||
\begin{itemize}
|
||||
\item Uses same logic as original slob\_page\_alloc to go through each block, but searches for the best instead of the first
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#define __sys_slob_free 400
|
||||
#define __sys_slob_used 401
|
||||
|
||||
int main (void){
|
||||
float fragmentation_percent;
|
||||
long used = syscall(__sys_slob_used);
|
||||
long free = syscall(__sys_slob_free);
|
||||
|
||||
fragmentation_percent = (float) free / (float) used;
|
||||
printf("Amount free: %ld.\n", free);
|
||||
printf("Amount used: %ld.\n", used);
|
||||
printf("Amount frag: %.2f%%.\n", fragmentation_percent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/mm/slob.c linux-yocto-3.19.2/mm/slob.c
|
||||
--- linux-yocto-3.19.2_untouched/mm/slob.c 2018-05-04 15:15:00.445347537 -0700
|
||||
+++ linux-yocto-3.19.2/mm/slob.c 2018-06-06 17:07:53.244403545 -0700
|
||||
@@ -68,6 +68,9 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/kmemleak.h>
|
||||
|
||||
+#include <linux/linkage.h>
|
||||
+#include <linux/syscalls.h>
|
||||
+
|
||||
#include <trace/events/kmem.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
@@ -101,6 +104,8 @@
|
||||
static LIST_HEAD(free_slob_medium);
|
||||
static LIST_HEAD(free_slob_large);
|
||||
|
||||
+size_t num_pages = 0;
|
||||
+
|
||||
/*
|
||||
* slob_page_free: true for pages on free_slob_pages list.
|
||||
*/
|
||||
@@ -211,55 +216,117 @@
|
||||
free_pages((unsigned long)b, order);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Allocate a slob block within a given slob_page sp.
|
||||
- */
|
||||
static void *slob_page_alloc(struct page *sp, size_t size, int align)
|
||||
{
|
||||
- slob_t *prev, *cur, *aligned = NULL;
|
||||
- int delta = 0, units = SLOB_UNITS(size);
|
||||
+ slob_t *prev, *cur, *aligned = NULL, *best = NULL, *best_prev = NULL;
|
||||
+ int delta = 0;
|
||||
+ int units = SLOB_UNITS(size);
|
||||
+ slobidx_t avail;
|
||||
|
||||
+ /* Find best fit block on page that can fit what needs to be allocated */
|
||||
for (prev = NULL, cur = sp->freelist; ; prev = cur, cur = slob_next(cur)) {
|
||||
- slobidx_t avail = slob_units(cur);
|
||||
+ avail = slob_units(cur);
|
||||
|
||||
+ /* Use aligned blocks if requested */
|
||||
if (align) {
|
||||
aligned = (slob_t *)ALIGN((unsigned long)cur, align);
|
||||
delta = aligned - cur;
|
||||
}
|
||||
- if (avail >= units + delta) { /* room enough? */
|
||||
- slob_t *next;
|
||||
+
|
||||
+ /* If the current block is the best option seen yet, store it */
|
||||
+ if(avail >= units + delta && (!best || avail < slob_units(best))) {
|
||||
+ best = cur;
|
||||
+ best_prev = prev;
|
||||
+ }
|
||||
+
|
||||
+ /* If this is the last block, exit loop */
|
||||
+ if (slob_last(cur)) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ /* Allocate the best block found above, if found */
|
||||
+ if (best != NULL){
|
||||
+ slob_t *next;
|
||||
|
||||
- if (delta) { /* need to fragment head to align? */
|
||||
- next = slob_next(cur);
|
||||
- set_slob(aligned, avail - delta, next);
|
||||
- set_slob(cur, delta, aligned);
|
||||
- prev = cur;
|
||||
- cur = aligned;
|
||||
- avail = slob_units(cur);
|
||||
- }
|
||||
+ /* Align if necessary */
|
||||
+ if (align) {
|
||||
+ aligned = (slob_t *)ALIGN((unsigned long)best, align);
|
||||
+ delta = aligned - best;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the amount of space available */
|
||||
+ avail = slob_units(best);
|
||||
|
||||
- next = slob_next(cur);
|
||||
- if (avail == units) { /* exact fit? unlink. */
|
||||
- if (prev)
|
||||
- set_slob(prev, slob_units(prev), next);
|
||||
- else
|
||||
- sp->freelist = next;
|
||||
- } else { /* fragment */
|
||||
- if (prev)
|
||||
- set_slob(prev, slob_units(prev), cur + units);
|
||||
- else
|
||||
- sp->freelist = cur + units;
|
||||
- set_slob(cur + units, avail - units, next);
|
||||
+
|
||||
+ if (delta) { /* need to fragment head to align? */
|
||||
+ next = slob_next(best);
|
||||
+ set_slob(aligned, (avail - delta), next);
|
||||
+ set_slob(best, delta, aligned);
|
||||
+ best_prev = best;
|
||||
+ best = aligned;
|
||||
+ avail = slob_units(best);
|
||||
+ }
|
||||
+
|
||||
+ next = slob_next(best);
|
||||
+
|
||||
+ /* exact fit? unlink. */
|
||||
+ if (avail == units) {
|
||||
+ if (best_prev)
|
||||
+ set_slob(best_prev, slob_units(best_prev), next);
|
||||
+ else
|
||||
+ sp->freelist = next;
|
||||
+ } else { /* fragment */
|
||||
+ if (best_prev){
|
||||
+ set_slob(best_prev, slob_units(best_prev), best + units);
|
||||
}
|
||||
+ else{
|
||||
+ sp->freelist = best + units;
|
||||
+ }
|
||||
+ set_slob(best + units, avail - units, next);
|
||||
+ }
|
||||
+
|
||||
+ sp->units -= units;
|
||||
+ if (!sp->units)
|
||||
+ clear_slob_page_free(sp);
|
||||
+ return best;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int find_closest_block_size_in_page(struct page *sp, size_t size, int align)
|
||||
+{
|
||||
+ slob_t *prev, *cur, *aligned = NULL, *best = NULL;
|
||||
+ int delta = 0, units = SLOB_UNITS(size);
|
||||
|
||||
- sp->units -= units;
|
||||
- if (!sp->units)
|
||||
- clear_slob_page_free(sp);
|
||||
- return cur;
|
||||
+ for (prev = NULL, cur = sp->freelist; ; prev = cur, cur = slob_next(cur)) {
|
||||
+ slobidx_t avail = slob_units(cur);
|
||||
+
|
||||
+ /* Align if necessary */
|
||||
+ if (align) {
|
||||
+ aligned = (slob_t *)ALIGN((unsigned long)cur, align);
|
||||
+ delta = aligned - cur;
|
||||
}
|
||||
- if (slob_last(cur))
|
||||
- return NULL;
|
||||
+
|
||||
+ /* Keep track of the better block if we've found one */
|
||||
+ if(avail >= units + delta && (!best || avail < slob_units(best))){
|
||||
+ best = cur;
|
||||
+ }
|
||||
+
|
||||
+ /* If we're at the end, return the best block, or -1 if not found*/
|
||||
+ if (slob_last(cur)) {
|
||||
+ if(best){
|
||||
+ return slob_units(best);
|
||||
+ }else{
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
}
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -267,11 +334,12 @@
|
||||
*/
|
||||
static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
|
||||
{
|
||||
- struct page *sp;
|
||||
- struct list_head *prev;
|
||||
- struct list_head *slob_list;
|
||||
+ struct page *sp = NULL, *best_pg = NULL;
|
||||
+ struct list_head *slob_list = NULL;
|
||||
slob_t *b = NULL;
|
||||
unsigned long flags;
|
||||
+ slobidx_t best_fit = 0;
|
||||
+ slobidx_t cur_fit;
|
||||
|
||||
if (size < SLOB_BREAK1)
|
||||
slob_list = &free_slob_small;
|
||||
@@ -281,53 +349,67 @@
|
||||
slob_list = &free_slob_large;
|
||||
|
||||
spin_lock_irqsave(&slob_lock, flags);
|
||||
- /* Iterate through each partially free page, try to find room */
|
||||
+
|
||||
+ /* Iterate through each page for find a spot if possible */
|
||||
list_for_each_entry(sp, slob_list, lru) {
|
||||
#ifdef CONFIG_NUMA
|
||||
- /*
|
||||
- * If there's a node specification, search for a partial
|
||||
- * page with a matching node id in the freelist.
|
||||
- */
|
||||
- if (node != NUMA_NO_NODE && page_to_nid(sp) != node)
|
||||
- continue;
|
||||
+ /*
|
||||
+ * If there's a node specification, search for a partial
|
||||
+ * page with a matching node id in the freelist.
|
||||
+ */
|
||||
+ if (node != NUMA_NO_NODE && page_to_nid(sp) != node)
|
||||
+ continue;
|
||||
#endif
|
||||
- /* Enough room on this page? */
|
||||
- if (sp->units < SLOB_UNITS(size))
|
||||
- continue;
|
||||
-
|
||||
- /* Attempt to alloc */
|
||||
- prev = sp->lru.prev;
|
||||
- b = slob_page_alloc(sp, size, align);
|
||||
- if (!b)
|
||||
- continue;
|
||||
-
|
||||
- /* Improve fragment distribution and reduce our average
|
||||
- * search time by starting our next search here. (see
|
||||
- * Knuth vol 1, sec 2.5, pg 449) */
|
||||
- if (prev != slob_list->prev &&
|
||||
- slob_list->next != prev->next)
|
||||
- list_move_tail(slob_list, prev->next);
|
||||
- break;
|
||||
+ /* Enough room on this page? */
|
||||
+ if (sp->units < SLOB_UNITS(size))
|
||||
+ continue;
|
||||
+
|
||||
+ /* Find out if there's space for this in the current page */
|
||||
+ cur_fit = find_closest_block_size_in_page(sp, size, align);
|
||||
+
|
||||
+ /* If not, continue*/
|
||||
+ if(cur_fit == -1){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* Stop if we've found something that perfectly matches */
|
||||
+ if (cur_fit == SLOB_UNITS(size)) {
|
||||
+ best_pg = sp;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Store the current best fit block, if it's better than previous */
|
||||
+ if (best_fit > cur_fit || best_pg == NULL) {
|
||||
+ best_pg = sp;
|
||||
+ best_fit = cur_fit;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Attempt to allocate */
|
||||
+ if(best_pg != NULL){
|
||||
+ b = slob_page_alloc(best_pg, size, align);
|
||||
}
|
||||
+
|
||||
spin_unlock_irqrestore(&slob_lock, flags);
|
||||
|
||||
- /* Not enough space: must allocate a new page */
|
||||
+ /* Make a new page if we never found a spot */
|
||||
if (!b) {
|
||||
- b = slob_new_pages(gfp & ~__GFP_ZERO, 0, node);
|
||||
- if (!b)
|
||||
- return NULL;
|
||||
- sp = virt_to_page(b);
|
||||
- __SetPageSlab(sp);
|
||||
-
|
||||
- spin_lock_irqsave(&slob_lock, flags);
|
||||
- sp->units = SLOB_UNITS(PAGE_SIZE);
|
||||
- sp->freelist = b;
|
||||
- INIT_LIST_HEAD(&sp->lru);
|
||||
- set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
|
||||
- set_slob_page_free(sp, slob_list);
|
||||
- b = slob_page_alloc(sp, size, align);
|
||||
- BUG_ON(!b);
|
||||
- spin_unlock_irqrestore(&slob_lock, flags);
|
||||
+ b = slob_new_pages(gfp & ~__GFP_ZERO, 0, node);
|
||||
+ if (!b)
|
||||
+ return NULL;
|
||||
+ sp = virt_to_page(b);
|
||||
+ __SetPageSlab(sp);
|
||||
+
|
||||
+ spin_lock_irqsave(&slob_lock, flags);
|
||||
+ sp->units = SLOB_UNITS(PAGE_SIZE);
|
||||
+ sp->freelist = b;
|
||||
+ INIT_LIST_HEAD(&sp->lru);
|
||||
+ set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
|
||||
+ set_slob_page_free(sp, slob_list);
|
||||
+ b = slob_page_alloc(sp, size, align);
|
||||
+ BUG_ON(!b);
|
||||
+ spin_unlock_irqrestore(&slob_lock, flags);
|
||||
+ num_pages++;
|
||||
}
|
||||
if (unlikely((gfp & __GFP_ZERO) && b))
|
||||
memset(b, 0, size);
|
||||
@@ -362,6 +444,7 @@
|
||||
__ClearPageSlab(sp);
|
||||
page_mapcount_reset(sp);
|
||||
slob_free_pages(b, 0);
|
||||
+ num_pages--;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -640,3 +723,31 @@
|
||||
{
|
||||
slab_state = FULL;
|
||||
}
|
||||
+
|
||||
+asmlinkage long sys_slob_free(void) {
|
||||
+ struct list_head *temp;
|
||||
+ struct page *sp;
|
||||
+ unsigned long free_units = 0;
|
||||
+
|
||||
+ temp = &free_slob_small;
|
||||
+ list_for_each_entry(sp, temp, lru) {
|
||||
+ free_units += sp->units;
|
||||
+ }
|
||||
+ temp = &free_slob_medium;
|
||||
+ list_for_each_entry(sp, temp, lru) {
|
||||
+ free_units += sp->units;
|
||||
+ }
|
||||
+ temp = &free_slob_large;
|
||||
+ list_for_each_entry(sp, temp, lru) {
|
||||
+ free_units += sp->units;
|
||||
+ }
|
||||
+
|
||||
+ return free_units;
|
||||
+}
|
||||
+
|
||||
+asmlinkage long sys_slob_used(void) {
|
||||
+ long slob_total_used;
|
||||
+
|
||||
+ slob_total_used = SLOB_UNITS(PAGE_SIZE) * num_pages;
|
||||
+ return slob_total_used;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/include/linux/syscalls.h linux-yocto-3.19.2/include/linux/syscalls.h
|
||||
--- linux-yocto-3.19.2_untouched/include/linux/syscalls.h 2018-05-04 15:14:59.075324834 -0700
|
||||
+++ linux-yocto-3.19.2/include/linux/syscalls.h 2018-06-06 16:32:02.518020727 -0700
|
||||
@@ -882,4 +882,6 @@
|
||||
const char __user *const __user *argv,
|
||||
const char __user *const __user *envp, int flags);
|
||||
|
||||
+asmlinkage long sys_slob_free(void);
|
||||
+asmlinkage long sys_slob_used(void);
|
||||
#endif
|
||||
diff -Naur -x '*.o' -x '*.ko' -x '*.order' -x '*.builtin' -x '*.cmd' -x '*.mod.c' linux-yocto-3.19.2_untouched/arch/x86/syscalls/syscall_32.tbl linux-yocto-3.19.2/arch/x86/syscalls/syscall_32.tbl
|
||||
--- linux-yocto-3.19.2_untouched/arch/x86/syscalls/syscall_32.tbl 2018-05-04 15:14:40.077010007 -0700
|
||||
+++ linux-yocto-3.19.2/arch/x86/syscalls/syscall_32.tbl 2018-06-06 16:31:26.578421117 -0700
|
||||
@@ -365,3 +365,6 @@
|
||||
356 i386 memfd_create sys_memfd_create
|
||||
357 i386 bpf sys_bpf
|
||||
358 i386 execveat sys_execveat stub32_execveat
|
||||
+
|
||||
+400 i386 slob_free sys_slob_free
|
||||
+401 i386 slob_used sys_slob_used
|
||||
\ No newline at end of file
|
||||
--- linux-yocto-3.19.2_untouched/.config 2018-05-04 15:15:03.830403632 -0700
|
||||
+++ linux-yocto-3.19.2/.config 2018-06-05 17:11:02.799939154 -0700
|
||||
@@ -146,7 +146,6 @@
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_MEMCG_SWAP_ENABLED=y
|
||||
-CONFIG_MEMCG_KMEM=y
|
||||
# CONFIG_CGROUP_PERF is not set
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_FAIR_GROUP_SCHED=y
|
||||
@@ -211,12 +210,10 @@
|
||||
CONFIG_PERF_EVENTS=y
|
||||
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
-CONFIG_SLUB_DEBUG=y
|
||||
CONFIG_COMPAT_BRK=y
|
||||
# CONFIG_SLAB is not set
|
||||
-CONFIG_SLUB=y
|
||||
-# CONFIG_SLOB is not set
|
||||
-CONFIG_SLUB_CPU_PARTIAL=y
|
||||
+# CONFIG_SLUB is not set
|
||||
+CONFIG_SLOB=y
|
||||
# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_TRACEPOINTS=y
|
||||
@@ -251,7 +248,6 @@
|
||||
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
|
||||
-CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
|
||||
CONFIG_HAVE_CMPXCHG_LOCAL=y
|
||||
CONFIG_HAVE_CMPXCHG_DOUBLE=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
@@ -275,7 +271,6 @@
|
||||
# CONFIG_GCOV_KERNEL is not set
|
||||
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
-CONFIG_SLABINFO=y
|
||||
CONFIG_RT_MUTEXES=y
|
||||
CONFIG_BASE_SMALL=0
|
||||
CONFIG_MODULES=y
|
||||
@@ -3787,8 +3782,6 @@
|
||||
# CONFIG_PAGE_EXTENSION is not set
|
||||
# CONFIG_DEBUG_PAGEALLOC is not set
|
||||
# CONFIG_DEBUG_OBJECTS is not set
|
||||
-# CONFIG_SLUB_DEBUG_ON is not set
|
||||
-# CONFIG_SLUB_STATS is not set
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
# CONFIG_DEBUG_KMEMLEAK is not set
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
@@ -0,0 +1,99 @@
|
||||
\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran}
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{{./figures/}}
|
||||
|
||||
\usepackage{url}
|
||||
\usepackage{setspace}
|
||||
\usepackage{multicol}
|
||||
\usepackage{pdflscape}
|
||||
\usepackage{pdfpages}
|
||||
\usepackage[british]{babel}
|
||||
\usepackage{listings}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{listings}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{subfig}
|
||||
\usepackage{textcomp}
|
||||
|
||||
\usepackage{geometry}
|
||||
\geometry{textheight=9.5in, textwidth=7in}
|
||||
|
||||
% \overfullrule=2in
|
||||
|
||||
|
||||
%Personal \newcommands
|
||||
|
||||
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
|
||||
\lstset{basicstyle=\ttfamily,
|
||||
backgroundcolor=\color{backcolor},
|
||||
showstringspaces=false,
|
||||
commentstyle=\color{red},
|
||||
keywordstyle=\color{blue},
|
||||
columns=fullflexible,
|
||||
breaklines=true,
|
||||
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
|
||||
}
|
||||
|
||||
\newcommand{\NameSigPair}[1]{
|
||||
\par
|
||||
\makebox[2.75in][r]{#1}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in]{\hrulefill}
|
||||
\hfill
|
||||
\makebox[.75in]{\hrulefill}
|
||||
}
|
||||
\par\vspace{-12pt}
|
||||
\textit{
|
||||
\tiny\noindent
|
||||
\makebox[2.75in]{}
|
||||
\hfill
|
||||
\makebox[3.25in]{
|
||||
\makebox[2.25in][r]{Signature}
|
||||
\hfill
|
||||
\makebox[.75in][r]{Date}
|
||||
}
|
||||
}
|
||||
}
|
||||
% 3. If the document is not to be signed, uncomment the command below
|
||||
\renewcommand{\NameSigPair}[1]{#1}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
\pagenumbering{gobble}
|
||||
\begin{singlespace}
|
||||
\par\vspace{2in}
|
||||
\centering
|
||||
\scshape{
|
||||
\huge Operating Systems II Homework 4 \par
|
||||
{\large\today}\par
|
||||
\vspace{.5in}
|
||||
\vfill
|
||||
\vspace{5pt}
|
||||
{\large Prepared by }\par
|
||||
Group 4 \par
|
||||
% 5. comment out the line below this one if you do not wish to name your team
|
||||
\vspace{5pt}
|
||||
{\Large
|
||||
\NameSigPair{Corinna Brown}\par
|
||||
\NameSigPair{Corwin Perren}\par
|
||||
}
|
||||
\vspace{20pt}
|
||||
\begin{abstract}
|
||||
The document is our group's submission for homework four covering the design of our solution, answers to explicit assignment questions, a version control log, and a work log.
|
||||
\end{abstract}
|
||||
}
|
||||
\end{singlespace}
|
||||
\end{titlepage}
|
||||
\newpage
|
||||
\pagenumbering{arabic}
|
||||
\tableofcontents
|
||||
\clearpage
|
||||
|
||||
\input{design}
|
||||
\input{questions}
|
||||
\input{versioncontrollog}
|
||||
\input{worklog}
|
||||
|
||||
\end{document}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
# This config is copied from overleaf so output there will match compiled output here
|
||||
|
||||
# support for the glossaries package:
|
||||
add_cus_dep('glo', 'gls', 0, 'makeglossaries');
|
||||
add_cus_dep('acn', 'acr', 0, 'makeglossaries');
|
||||
sub makeglossaries {
|
||||
system("makeglossaries \"$_[0]\"");
|
||||
}
|
||||
|
||||
# support for the nomencl package:
|
||||
add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
|
||||
sub makenlo2nls {
|
||||
system("makeindex -s nomencl.ist -o \"$_[0].nls\" \"$_[0].nlo\"");
|
||||
}
|
||||
|
||||
# from the documentation for V. 2.03 of asymptote:
|
||||
sub asy {return system("asy \"$_[0]\"");}
|
||||
add_cus_dep("asy","eps",0,"asy");
|
||||
add_cus_dep("asy","pdf",0,"asy");
|
||||
add_cus_dep("asy","tex",0,"asy");
|
||||
|
||||
# metapost rule from http://tex.stackexchange.com/questions/37134
|
||||
add_cus_dep('mp', '1', 0, 'mpost');
|
||||
sub mpost {
|
||||
my $file = $_[0];
|
||||
my ($name, $path) = fileparse($file);
|
||||
pushd($path);
|
||||
my $return = system "mpost $name";
|
||||
popd();
|
||||
return $return;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# Makefile created by Corwin Perren
|
||||
# Generic makefile for all LaTeX projects downloaded from overleaf
|
||||
#
|
||||
# All this makefile does is call perl against latexmkrc, which is
|
||||
# the latex equivalent of make
|
||||
|
||||
LATEXMK_COMPILE_FLAGS = -cd -pdf homework4.tex
|
||||
LATEXMK_CLEAN_FLAGS = -c
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
all: latexmk_output clean
|
||||
|
||||
latexmk_output:
|
||||
perl latexmk.pl $(LATEXMK_COMPILE_FLAGS)
|
||||
mv homework4.pdf CS444_project4_4.pdf
|
||||
|
||||
clean:
|
||||
perl latexmk.pl $(LATEXMK_CLEAN_FLAGS)
|
||||
@@ -0,0 +1,44 @@
|
||||
\section{Questions}
|
||||
\subsection{Point of Assignment}
|
||||
One of the main points of this assignment was to gain experience working with the memory management system in Linux. Working with slob.c requires knowledge of how memory is organized and how to access this memory. Doing this also provides more experience modifying existing kernel code. Finally this assignment also provided an opportunity to create and use a custom system call.
|
||||
|
||||
\subsection{Problem Approach}
|
||||
We approached this problem by first reading the HW4 page on Canvas and reading through the slob.c file in the "mm" folder. After reaching an understanding of how the "slob.c" file works, we set up our kernel to use SLOB instead of SLAB.
|
||||
|
||||
Next we started to create a design for how we would implement the best-fit algorithm. This involved determining which functions were being used to implement first-fit. These functions were found to be "slob\_alloc" and "slob\_page\_alloc". To implement best-fit we modified these and added a helper function "find\_closest\_block\_size\_in\_page". After this was tested and correctly functioning, we added two system call functions that find the amount of free memory and the amount of used memory by finding the number of pages being used and the amount of space on each page that is free. These system calls were also added to a unmodified version of the kernel's slob.c to test the fragmentation of the first-fit algorithm in comparison to the best-fit algorithm. These system calls were added to the system call table, and a program was written to call these system calls in order to test both algorithms. Each algorithm was then tested five times. The results of these tests are in the "Correctness" section below.
|
||||
|
||||
\subsection{Correctness}
|
||||
The test results are shown in Table 1 below. The test was run five different times on each of the two kernels with the different algorithms. To calculate the fragmentation, the following equation was used:
|
||||
\[ \frac{free blocks}{total blocks}*100 = fragmentation \]
|
||||
The average fragmentation over these five tests was then calculated. The average fragmentation was found to be 5.80\% for first-fit and 4.20\% for best-fit.
|
||||
|
||||
\begin{table}[ht]
|
||||
\caption{Fragmentation of First-Fit vs. Best-Fit Algorithms} % title of Table
|
||||
\centering % used for centering table
|
||||
\begin{tabular}{ c | c c c | c c c } % centered columns (7 columns)
|
||||
\hline\hline %inserts double horizontal lines
|
||||
& \multicolumn{3}{| c |}{First-Fit} & \multicolumn{3}{ c }{Best-Fit}\\
|
||||
\hline
|
||||
Trial & Free Blocks & Total Blocks & Fragmentation & Free Blocks & Total Blocks & Fragmentation \\ [0.5ex] % inserts table
|
||||
%heading
|
||||
\hline % inserts single horizontal line
|
||||
1 & 303776 & 5220352 & 5.82\% & 217544 & 5132288 & 4.24\% \\ % inserting body of the table
|
||||
2 & 303032 & 5220352 & 5.80\% & 214686 & 5130240 & 4.18\% \\
|
||||
3 & 304898 & 5220400 & 5.84\% & 215515 & 5130240 & 4.20\% \\
|
||||
4 & 303096 & 5220352 & 5.81\% & 213248 & 5128192 & 4.16\% \\
|
||||
5 & 298986 & 5216256 & 5.73\% & 215862 & 5130240 & 4.21\% \\
|
||||
\hline
|
||||
Average & & & 5.80\% & & & 4.20\% \\
|
||||
\hline %inserts single line
|
||||
\end{tabular}
|
||||
\label{table:nonlin} % is used to refer this table in the text
|
||||
\end{table}
|
||||
|
||||
As can be seen from the table, the fragmentation values fo r the best-fit algorithm are lower than those for the default first-fit one that ships with the kernel. This proves out implementation is correct as the best-fit model, while slower, does use the allocated pages in memory more efficiently than first-fit.
|
||||
|
||||
|
||||
\subsection{What Was Learned}
|
||||
We learned in this lab that the memory management system in linux is large and complex. We also learned that best-fit has less fragmentation than first-fit. However, there is a trade-off as best-fit also causes the kernel to boot significantly slower than with first-fit. Finally we learned how to create a custom system call, how to add it to the system call table, and how to use it.
|
||||
|
||||
\subsection{How to Evaluate}
|
||||
To evaluate this, get a clean version of the linux yocto kernel and copy the patch file into the root of the directory. Run "patch -p1 -t $<$ homework4.patch" to apply the changes to the necessary files. Make the kernel using "make -j4". Boot the kernel and scp the "find\_fragmentation.c" file into the running vm. Run "gcc find\_fragmentation.c -o frag\_check" on the vm's command line to build the fragmentation source into a binary. Run the binary with "./frag\_check". If the program outputs reasonable values for free, used, and fragmentation the kernel was built and is running correctly using the modified slob algorithm. The values on a cleanly booted system should closely match the best-fit table values from above.
|
||||
@@ -0,0 +1,11 @@
|
||||
\section{Version Control Log}
|
||||
\begin{center}
|
||||
\begin{tabular}{l l l l} \textbf{Detail} & \textbf{Author} & \textbf{Date} &\textbf{Description}\\\hline
|
||||
|
||||
\href{.//commit/3b486d3c5ba08b193bc64b47e5cab98ac4cbbafe}{3b486d3} & Corwin Perren & 2018-06-05 18:16:42 -0700 &Clean kernels for homework 4. *Design commited here*\\\hline
|
||||
\href{.//commit/5b7861a5682daf082272f8e0dd24a0174ef70f4b}{5b7861a} & Corwin Perren & 2018-06-05 18:26:26 -0700 &Missed adding updated files from previous commit.\\\hline
|
||||
\href{.//commit/608c1fc75c1be5e2a87a81185c3a09712ca5232f}{608c1fc} & Corwin Perren & 2018-06-06 18:00:36 -0700 &Finished hw4. Patch made. Tested.\\\hline
|
||||
|
||||
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
@@ -0,0 +1,20 @@
|
||||
\section{Work Log}
|
||||
\begin{itemize}
|
||||
\item 06-05-2019
|
||||
\begin{itemize}
|
||||
\item Group met in Valley Library
|
||||
\item Started Latex document for Homework 4
|
||||
\item Read through slob.c
|
||||
\item Created initial design for best-fit algorithm
|
||||
\item Began work modifying slob.c
|
||||
\end{itemize}
|
||||
\item 06-06-2019
|
||||
\begin{itemize}
|
||||
\item Group met in Valley Library
|
||||
\item Made working version of best-fit slob.c
|
||||
\item Ran performance tests between algorithms
|
||||
\item Created patch file
|
||||
\item Finished latex document
|
||||
\item Turned in assignment
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
Reference in New Issue
Block a user