Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 342 lines (271 sloc) 11.1 KB
\newmnemonic{NOP}{no operation}
\newmnemonic{RETF}{far return}
\newmnemonic{RET}{near return}%or just Return...
\newmnemonic{LGDT}{load global descriptor table}
\newmnemonic{SGDT}{store global descriptor table}
\newmnemonic{SFENCE}{store fence}
\node[rectangle,minimum width=0.9\textwidth] (m)
\bgroup\begin{minipage}{0.85\textwidth}$\!\!\!$\textbf{TechNote:} \ignorespaces%
\draw[dashed] (m.south west) rectangle (m.north east);
\node[rectangle,minimum width=0.9\textwidth] (m)
\bgroup\begin{minipage}{0.85\textwidth}$\!\!\!$\textbf{TestIdea:} \ignorespaces%
\draw (m.south west) rectangle (m.north east);
%\newcommand\technote[1]{\emph{\tiny{Technical~note: #1}}}
\title{Art of Operating System Development}
\part{First things}
{\small\textit{Note that this book will be seperated into multiple parts. The
first few chapters will cover a general overview of the subject and
various aspects of the boot sequence.}}
We intend to explain how to develop an operating system on the \gls{x86}
{architecture}\footnote{This includes the \gls{x86-64} variants. Later in
the far far future discussion on other machine types may be included.}.
\section{Data sizes}
Explain \gls{bit}, \gls{nibble}, \gls{byte}, \gls{word},
\gls{double word}, and \gls{quad word}.
\bitheader[b]{0-7} \\
A machine \gls{double word} is 32 bits.\cn So we are clear, that is 4
\caption{\protect\Gls{double word}\relax}
\bitheader[b]{0,7,8,15,16,23,24,31} \\
\bitbox{8}{} \bitbox{8}{} \bitbox{8}{} \bitbox{8}{}
There are various other terms including \gls{nibble}, \gls{word} and \gls{quad word}. We
will discuss these when they come up. \todo{where?}
\section{Which Endian?}
% further explain what endian is and how we will handle data sizes
As the \gls{x86} architecture is \gls{little endian}, all of our figures
and notation will also be little~endian. So when talking about where
a~\gls{bit} is~in a~\gls{byte} we will start counting from the~right
to~left.\cite{wikipedia_endianness_2011,cohen_holy_war_1980} Looking at
figure \ref{fig:byte}, we notice that the 0\ap{th} bit is located to the far right
and the 7\ap{th} bit is located to the far left.
The attentive reader should note that we have started counting at
\emph{zero} instead of \emph{one}. This is the traditional way for computer
scientists to count.\cn\todo{I'd really like to rewrite this with a better
word flow\ldots.}
\chapter{Boot Loader}
On x86 systems the \gls*{bios} starts execution at physical address
\verb|0x7c00|. The \gls*{cpu} will get control operating in \gls{real
mode}. Real mode is~very limited, only~1MB of~memory may be
accessed.\cn\todo{Check that real mode memory limits are correct}
The contents of the \register{DL}~register indicate which drive contains
the~loaded boot-sector. Store this number for~later reference if
the~kernel is~to~handle being booted from a~machine with more than
Either the \gls{boot loader} or the \keyword{kernel} has to~bring
the~CPU into protected mode.
\Gls{byte addressing} means memory access is~accessed as~a~sequence
An \gls{address space} is the set of addressable bytes that can be
selected at a given time.\cite{intel-v3A}
Since the~whole memory space cannot be~accessed at~one~time on a~32bit
system the concept of~\keyword{segments} was invented. A~segment is~just
a~named address-space. There are six segment registers on a 32bit
system.\cite[3-4]{intel-v1}\todo{Write something about how many of these
exist on 64 bit systems.} A dedicated segment can be assigned to the
\keyword{stack} as well as to the currently executing code. \todo{Discuss
assembly level segment syntax, both intel and gas versions.}
The \gls*{gdtr} is a machine register that serves as a pointer to the linear
address location of the \gls*{gdt}.
Is not considered a segment. Only the LDT and TSS are
LGDT is the assembly mnemonic for loading a value to the \gls*{gdtr}
register\todo{Expand this explaining how to use the LGDT assembler
instruction. Might need moved to a later part of this book.}.
\gls*{gdtr} is an oddly shaped machine register that acts as a pointer
containing either 48 bits or 80 bits depending on if a 32 bit mode or 64
bit mode is in use. Figure \ref{fig:GDTR} shows the layout of this machine
register\todo{We have this repeated twice in different ways, see first
There are four system descriptor registers: \register{GDTR},
\register{IDTR}, \register{LDTR}, and
On segmentation, there is no way to disable segmentation on
32~bit\cite[3.2.4]{intel-v3A} x86~processors.\cite[3.1]{intel-v3A} For
the 64bit architectures segmentation is largely unused. Intel specification
states that a processor in 64~bit mode will not do runtime segment limit
Paging is optional.\cn
Verify memory size reading is correct.\par
After GDT is setup, attempt to set the last byte of reachable memory to
$0xE$ and attempt to read it back.
\section{Basic Flat Memory Model}
Simplest way to setup segmentation on x86 architectures. Assumes that the
physical disk is a fixed size regardless of the actual physical
disk\todo{Duck was having a hard time understanding what was meant by
this, rewrite/improve.}. No general protection faults will be generated.\cn
Two segment descriptors that indicate the whole address space\footnote{On
32 bit systems this is 4GB.} is usable must be created. The initial state
of the \register{DS}~data segment after initializing this setup will be 0.
\draw (0,0) rectangle
node[pos=0.5]{Base Address} (6,2em) rectangle
node[pos=0.5]{Length} (9,0);
\node[above right] at (0,2em) {\tiny{47}};
\node[above left] at (6,2em) {\tiny{16}};SR \node[above right] at (6,2em) {\tiny{15}};
\node[above left] at (9,2em) {\tiny{0}};
\node [below right,color=gray] at (0,2em) {\tiny{(32)}};
\node [below right,color=gray] at (6,2em) {\tiny{(16)}};
% \node [rectangle,draw] {GDTR};
% \node [above right] at (0,1em) {\tiny{47}};
% Maybe useful... we shall see. #1=lowbit, #2=highbit, #3=width, #4=text.
% if we want to use it, don't forget the greyed out number in the upper
% left corner.
% \def\mywidth{#3}
% \node[rectangle,draw,align=center,minimum height=2em,minimum width=\mywidth] {#4}
% node[above left=1em and \mywidth/2-0.5cm]{\tiny{#2}}
% node[above right=1em and \mywidth/2-0.5cm]{\tiny{#1}}}
A machine independent method of configuring various input and output
devices.\cn Detecting if a computer has \gls*{acpi} support involves
looking in specific memory regions for the string \verb|"RSP PTR "|.\cn
Finding this on a 16 byte boundary marks the start of the RSPT which is
used for finding other ACPI tables.\cn
Checksum fields in all the tables are a single byte that when added to all
the other bytes in the table, the whole table will sum to
\chapter{Keyboard driver}
\section{Interrupt based}
\section{Poll based}
\chapter{Memory Management}
Want to cover how to write a workable TCP/IP stack.
\chapter{Context Switching}
\chapter{multi tasking}
\chapter{Linker files}
\chapter{64 bit x86}
\chapter{Multiboot spec}
\chapter{FAQ} {\small\textit{This chapter will not exist in this form in
the 1.0 version of this book. The intent here is simply to indicate
questions that ought to have answers. The porported
answers to the questions in this chapter should be treated with care
unless proper citations are given. Again in due time various questions
and answers will wind up in the book text proper.}}
\section{What is a reliable way to cause a reboot in x86 assembler?}
Just load a 0-sized IDT and interrupt.\footnote{Does not work in virtual
box and on some hardware.}\cn Also possibly look at
\section{How do I cause a triple fault?}
You can't without interrupts setup. \todo{add more!} \marginnote{foobar}[1em]
\section{Why can't I disable interrupts?}
\section{Does anything call sti?}
\section{Is cli run in ring0?}
\section{How much memory can a x86 processor address in real mode?}
\section{Why can't I pop the \register{CS} register?}
Changing running code would be a JMP\ldots so yea I imagine setting the
program counter/whatever segment register you use for code\ldots (I think
cs is mandatory\ldots not sure)\ldots is a simple matter of doing a far
\section{How do I read from a FAT16 file format?}
\section{Why is a higher half kernel recommended?}
At least recommended by osdev wiki\ldots from what the author understands\ldots.
\section{What is the System V ABI?}
\section{How does canonical naming work?}
\section{What is an ABI for?}
\section{What is Long mode on x86\_64?}
\section{How do I change video modes on x86 hardware?}
Only reasonable way to do this on most hardware is to go through
\emph{vm86} and real mode \emph{VBE interrupts}\cn.
\section{What are the debug registers \register{d0}\ldots\register{d7} for?}
Leave BDA and IVT alone.
Always best to load your kernel at 1MB.
on 32bit x86 machines EAX always contains the return value.
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End: