ECE391
ECE 391 (Computer Systems Engineering) is a 4-credit-hour course that is required for CE students. It is offered in both Fall and Spring and is a technical elective for EE students.
Content Covered
- x86 assembly: review of basic constructs and structures, interfacing C to assembly, macros, stack frame and calling convention
- Synchronization: primitives, memory semantics, mutual exclusion, semaphores, scheduling, and race conditions
- Interrupts: controlling generation and handling, chaining, cleanup code, interactions with device functionality
- Resource management: virtualization and protection, virtual memory and hardware support
- Exceptions and signals: exceptions due to instructions, memory accesses, and floating-point operations; signal semantics and delivery
- Device programming: basic abstractions, character and block devices
- File system abstractions: disk layout, access control lists and capabilities, log-structured and traditional filesystems as design problem
- I/O interface: file descriptors, buffering, control operations, memory mapping
- Application programming: Basic application design (iMail)
This course goes over systems software and the level of software involved in fine control of the hardware. Systems software is very important in fields like computer security, embedded systems, networking, and application programming. You will learn about how to keep processes safe through synchronization, how to manage resources like memory, and security concepts like memory virtualization and protection levels. You will also learn to interact with external devices through interrupts and port-mapped I/O. Famously, you will learn about Operating Systems, with a case study on the Linux kernel. Practically, this course will teach you assembly programming as well as multiple forms of system program through MPs.
Content Covered (Fall 2024)
- RISC-V assembly: review of basic constructs and structures, interfacing C to assembly, macros, stack frame and calling convention
- System software basics: resource management, virtualization, protection, system call interface, asynchronous and synchronous interactions
- Basic data structures: queues, heaps, stacks, lists
- Interrupts and exceptions: controlling generation and handling, chaining, cleanup code, interactions with device functionality, interrupt controllers
- Synchronization: primitives, memory semantics, mutual exclusion, semaphores, scheduling, race conditions
- Virtualization of the CPU: processes and scheduling
- I/O interface: file descriptors, buffering, control operations
- Device programming: basic abstractions, character and block devices, device driver development process
- User-level programming interfaces for file and network I/O, relationship to kernel I/O abstractions
- Virtualization of memory: hardware support and software abstractions
- Signals: semantics, generation, and delivery
- File system abstractions and disk layout
This course goes over the concepts and abstractions central to the development of modern computing systems, with an emphasis on the systems software that controls the interaction between devices and other hardware and application programs. The course covers input-output semantics, synchronization, interrupts, multitasking, virtualization of resources, protection, and resource management concepts. You will also be introduced to network and storage device abstractions. In terms of practical skills, you will be exposed to software development tools for source control, debugging, dependency management, and compilation, and will work in the context of a real operating system executing in a virtual machine. You will also develop software analysis skills as well as team-based development and testing skills.
Prerequisites
The concepts of C to LC3 and LC3 Assembly will come in handy in this class, particularly knowledge of how calling conventions and stacks work. Much of this class' programming is in C. Proficiency in C is highly useful for this class.
When to Take It
This course is a required prerequisite for ECE 411 (Computer Organization and Design) as well, therefore you will want to take this class ASAP so you can get into ECE 411. ECE 411 is helpful for the hardware design industry. Many other courses have this as a prerequisite, including ECE 422 (Computer Security I), ECE 428 (Distributed Systems) and ECE 438 (Communication Networks). All of these are systems-software-heavy courses.
Course Structure
The coursework is entirely MP and homework-based. There are 4 MPs, and MP1 and MP2 have an associated Problem set, each worth 10% of the full MP grade. The problem sets consist of questions relevant to your MPs to help prime you for those assignments.
There are 2 midterms and a final exam for the course, all weighted equally.
The class begins with MP0, which just helps you set up your ECE391 environment and introduces you to useful concepts in git.
In MP1, you will write x86 Assembly code to perform functions for a simple program. This involves writing a tasklet and i/o control functions, which mainly involve manipulating a data structure with assembly code. You will also write code to display on the screen in particular ways.
In MP2, you will implement much of the software for a game with visual graphics. This involves using the ModeX VGA controller to display values on a screen and learning the ModeX protocol to color certain pixels. You will implement parts of the logic for the game itself, as well as specific ways to draw things on screen. A big part of this MP is writing the Tux controller, a driver for an external device with buttons and LEDs to receive inputs and drive outputs.
In MP3, you will work in a group of 4 to create an operating system from scratch. This operating system will use paging, a virtual memory system. It will also implement a file system and multiple device drivers for things like a keyboard and real-time clock. The most important part of this MP is implementing system calls, to allow user code to be executed and interact with the kernel, and using your device drivers for input and output. Finally, students implement scheduling to allow for multiple processes to run concurrently.
Course Structure (Fall 2024)
The coursework is entirely MP and exam-based. There are 4 MPs, with MP0 worth 5%, MP1 and MP2 each worth 10%, and MP3 is worth 25%.
There are 2 midterms and a final exam for the course, all weighted equally.
Exams
Midterm 1 topics: RISC-V ISA, Memory Usage, Calling Convention, Device I/O, CPU Interrupt, Management.
Midterm 2 topics: Concurrency with Interrupts, Multithreading, Context Switching, Device Abstraction, Device Drivers, Filesystem.
Final: Cumulative + Virtual Memory, Processes, Paging, System Call, Fork.
Machine Problems
The class begins with MP0, which just helps you set up your ECE391 environment and introduces you to useful concepts in git and gdb.
In MP1, you will write RISC-V Assembly code to perform functions for a simple program. This involves writing a tasklet and i/o control functions, which mainly involve manipulating data structures (array, list, etc.) with assembly code. You will also write code to display on the screen in particular ways.
In MP2, you will implement an interrupt-based communication between the CPU and devices, including writing the UART operations and setting up the PLIC to manage serial communication and interrupts. You will then implement thread management and context switching in a co-operative multi-threaded system. This includes working with kernel threads that voluntarily yield control when waiting for events such as I/O or timer interrupts, and manage them using condition variables and the thread scheduler.
In MP3, you will work in a group of 3 to create an operating system from scratch. You will implement interrupt logic, user threading, kernel and application paging (virtual memory system), initialize some devices and a filesystem with the virtio interface, and create a system call interface to support system calls. The operating system will support running several tasks (“threads”) spawned by a number of user programs; programs will interface with the kernel via system calls.
Instructors
This course is routinely taught by two professors. Professor Zbigniew Kalbarczyk has taught every recent semester, as well as Professor Steve Lumetta and Professor Nikita Borisov in other semesters. Professor Kirill Levchenko and Professor Dong Kai Wang has taught the Fall 2024 semester.
The course has professors handling the lecture component and the TAs handling the (optional) lab component. Undergraduate course assistants aid with office hours and grading.
Course Tips
Start on the MPs as soon as you get them. In MP3 Particularly, each new checkpoint builds on the last, so missing parts on one checkpoint can hugely hinder you if you get behind. It is also very valuable to use the lab (ECEB 3026) to work, to get tips from course assistants during office hours, and other students as you work.
All of the MPs for this course are pretty difficult. Debugging is going to be a majority of the work on these MPs, aside from conceptual understanding. Follow good software engineering practices like writing readable code, and keep in mind you can use GDB for debugging most of the time. This will come in handy during your assignments.
The final MP for this course is to develop an operating system, and you will complete this in a group. Make sure to find a group you can work well with, and keep constant communication to make sure your whole group moves forward. Working together in person is highly advantageous, and the lab is a great place to work on this MP.
This course is known to be notoriously difficult, but with disciplined reviewing of important content from lectures as well as starting on MPs early, a good grade in the class is very achievable.
Life After
This course teaches the fundamentals of system software, and concepts can be applied to any aspect of software engineering. Companies like Apple, Google, and Microsoft develop complex operating systems, which knowledge in this class can help with developing immensely. Embedded systems are another field that uses concepts from this class, and courses like CS 431 explore this. Other fields like Computer Security and Networking build off this course, and you can expand on these concepts through courses like ECE 422/CS 461 and ECE/CS 438.
If you are more into hardware, ECE 411 will be a very good class to take, learning how the ISAs that you interact with in software are implemented in hardware.
Infamous Topics
- Synchronization primitives: Things like spin locks, semaphores, and Mutexes. These are very important to ensure proper execution in multiprocessor systems, however can be hard to grasp for students.
- Virtual Memory: A very important concept for security and resource management. This concept can evade some students during system design questions on midterms.
- Signals: These allow for the kernel to deliver software interrupts for programs to receive and respond to. This is one of the last things taught in the course and is one of the trickiest things on the final exam.
Resources
- Recommended Text 1: Catsoulis, John, Designing Embedded Hardware
- Recommended Text 2: Love, Robert, Linux Kernel Development
Resources (Fall 2024)
- Recommended Text 1: Borin, Edson, An Introduction to Assembly Programming with RISC-V
- Recommended Text 2: Arpaci-Dusseau, Operating Systems: Three Easy Pieces