Written by Luka Kerr on June 20, 2018

Bit Manipulation

Bitwise Operators

Memory

Regions

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)
    break
  else
    execute(instruction)
}

MIPS

Memory Addressing

    .data
vec: .space   16      # int vec[4];
    .text             # 16 bytes of storage
    .globl  main
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]

SPIM

Functions

2D Arrays

Structs

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

Signals

// 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);

Interrupts

Exceptions

Multi Tasking

Scheduling

Device Management

I/O Devices

Device Drivers

Memory Mapped I/O

Devices On Unix

Buffered I/O

Networks

Network Architecture In Depth

Concurrency

// 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