Written by Luka Kerr on June 20, 2018

Bit Manipulation

Bitwise Operators



Physical Memory

Data Representation

Instruction Set Architectures

Fetch Execute Cycle

All CPUs have program execution logic like:

while (1) {
  instruction = memory[PC]
  PC++  // Program Counter move to next instruction
  if (instruction == HALT)


Memory Addressing

vec: .space   16      # int vec[4];
    .text             # 16 bytes of storage
    .globl  main
    la  $t0, vec      # reg[t0] = &vec
    li  $t1, 5        # reg[t1] = 5
    sw  $t1, ($t0)    # vec[0] = reg[t1]
    li  $t1, 13       # reg[t1] = 13
    sw  $t1, 4($t0)   # vec[1] = reg[t1]
    li  $t1, -7       # reg[t1] = -7
    sw  $t1, 8($t0)   # vec[2] = reg[t1]
    li  $t2, 12       # reg[t2] = 12
    li  $t1, 42       # reg[t1] = 42
    sw  $t1, vec($t2) # vec[3] = reg[t1]



2D Arrays


Computer System Architecture

Operating Systems

System Calls

File Systems

Memory Management

Address Mapping

To map from process address (virtual address) to physical address:

typedef struct {char status, uint frameNo, ...} PageData;

PageData *AllPageTables[maxProc]; // one entry for each process

Address processToPhysical(pid, Vaddr) {
  PageData *PageTable = AllPageTables[pid];
  uint pageno = PageNumberFrom(Vaddr);
  uint offset = OffsetFrom(Vaddr);
  if (PageTable[pageno].status != Loaded) {
    // load page into free frame
    // set PageTable[pageno]
  uint frame = PageTable[pageno].frameNo;
  return frame * P + offset;

Virtual Memory

Cache Memory

Memory Management Hardware

Process Management


// define how to handle a particular signal
// SigID is one of the OS-defined signals
// Handler could be SIG_IGN, or SIG_DFL or user defined
SigHnd signal(int SigID, SigHnd Handler);

// sigID is one of the OS-defined signals
// newAct defines how signal should be handled
// oldAct saves a copy of how signal was handled
int sigaction(int sigID, struct sigaction *newAct, struct sigaction *oldAct);



Multi Tasking


Device Management

I/O Devices

Device Drivers

Memory Mapped I/O

Devices On Unix

Buffered I/O


Network Architecture In Depth


// creates a new thread with specified Attributes
// thread info stored in *Thread
// thread starts by executing Func() with Arg
int pthread_create(pthread_t *Thread, pthread_attr_t *Attr, void *(*Func)(void *), void *Arg);

// returns a pthread_t for current thread
pthread_t pthread_self(void);

// compares two thread IDs and returns 0 if the same, otherwise non-zero
int pthread_equal(pthread_t t1, pthread_t t2);

// suspend execution until thread T terminates
// pthread_exit() value is placed in *value_ptr
// if T has already exited, does not wait
int pthread_join(pthread_t T, void **value_ptr);

// terminate execution of thread, and do some cleaning up
// stores a return value in *value_ptr
void pthread_exit(void *value_ptr);

// create a semaphore object, and set initial value
int sem_init(sem_t *Sem, int Shared, uint Value);

// try to decrement
// blocks if Sem == 0
int sem_wait(sem_t *Sem);

// increment the value of semaphore Sem
int sem_post(sem_t *Sem);

// free all memory associated with semaphore Sem
int sem_destroy(sem_t *Sem);

// controls access to shared files
int flock(int FileDesc, int Operation);

// open two file descriptors
// fd[0] is opened for reading, fd[1] is opened for writing
int pipe(int fd[2]);

// opens a process by creating a bidirectional pipe, forking, and invoking the shell Cmd
FILE *popen(char *Cmd, char *Mode);

// create a new message queue, or open existing one
mqd_t mq_open(char *Name, int Flags);

// finish accessing message queue MQ
int mq_close(mqd_t *MQ);

// adds message Msg to message queue MQ with a given priority Prio
int mq_send(mqd_t MQ, char *Msg, int Size, uint Prio);

// removes highest priority message from queue MQ
int mq_receive(mqd_t MQ, char *Msg, int Size, uint *Prio);

// creates a socket with a Domain, Type and Protocol
int socket(int Domain, int Type, int Protocol);

// associates an open socket with an address
int bind(int Sockfd, SockAddr *Addr, socklen_t AddrLen);

// wait for connections on socket Sockfd
// allow at most Backlog connections to be queued up
int listen(int Sockfd, int Backlog);

// Sockfd has been created, bound and is listening
int accept(int Sockfd, SockAddr *Addr, socklen_t *AddrLen);

// connects the socket Sockfd to address Addr
int connect(int Sockfd, SockAddr *Addr, socklen_t AddrLen);

Exam Tips

Use man for looking up system calls, unix variables etc

Section Description
1 User commands
2 System calls
3 C Library Functions
4 Devices and Special Files
5 File Formats and Conventions
6 Games and Screensavers
7 Misc
8 System Administration tools and Daemons

Use apropos <search_term> to search for man pages

Use man -K <search_term> to brute force search man pages for a specific keyword

Use bc (1) To Convert Between Bases

# ibase is the input base, obase is the output base, <string> is the input string
echo 'obase=2; ibase=16; <string>' | bc

# converting hex to binary
echo 'obase=2; ibase=16; ABC123' | bc

# converting octal to binary
echo 'obase=2; ibase=8; 12345' |  bc

# converting hex to decimal - leave out the obase
echo 'ibase=16; ABC123' | bc