Marquette University logo      

 

 

Dr. Brylow

Submit: Turn in your source code using the turnin command on the lab machines. Please turn in only the files spinlock_util.S and spinlock.c.

Work should be completed in pairs. Be certain to include both names in the comment block at the top of all source code files. It would be courteous to confirm with your partner when submitting the assignment. You may modify any files in the operating system, but only changes to system/spinlock_util.S and system/spinlock.c will be graded for this assignment.

 

Raspberry Pi 3 B+:

Pi 3 processor image

 

In the coming multicore assignments, you will be running your kernel on the Raspberry Pi 3 Model B+ platform, which has four cores within its processor. All previous variants of this course have used single-core platforms (i.e., Linksys MIPS router, Raspberry Pi 1) to run students' code. This is the first Operating Systems course at Marquette (and in the world, as far as we know) that make use of real multicore hardware (as opposed to a virtual machine) to teach multicore concepts.

Your previous UART driver assignment ran on the Pi 3, but you only used one core for that. Now that your embedded O/S will be taking advantage of this multicore architecture, you need to know the multicore functions built in for you to use.

 

Unparkcore():

Although this concept is general to multicore platforms, the specific implementations vary from one platform to another.

When the Pi 3 B+ boots, only Core 0 is powered up, and Cores 1-3 are put in a sleep state. To wake up, or "unpark," a core, you send it an event to "wake it up," then the core will check the value in special location known as its "mailbox." The core then begins execution at the address that it finds in its mailbox.

start sequence + unpark core

 

In this example, core 3 is unparked and sent to execute a given test_procedure with no arguments (NULL). See the "Testing" section below for information about how to use this function.

unparkcore() is already implemented for you and can be found in system/unparkcore.c

    unparkcore(int core, void* address, void* argument);

In the implementation of unparkcore, you will see that it will unpark the core to an assembly routine called setupCore (found in system/setupCore.S). setupCore is necessary because the core needs to undergo specific initializations before any of your code can run.

unparkcore.c and setupCore.S are already implemented for you.

 

Preparation

NOTICE: Because you will be using your own kprintf.c file in this assignment, to keep TA-Bot in sync on our end, the method for untarring this project is slightly different from Project 3.

First, make a copy of your Project 3 directory:
    cp -R xinu-hw3 xinu-hw4
Then, untar the new project files on top of it:
    tar xvzf ~brylow/os/Projects/xinu-hw4.tgz

New files:

  • system/
    • spinlock.c
    • spinlock_util.S
    • unparkcore.c
    • setupCore.S
    • mmu.c
    • mmu_util.S
  • include/
    • spinlock.h
    • mmu.h
    • core.h

Copy your synchronous serial driver file (kprintf.c) into the system/ directory.

Like with any programming task, it is important to understand the concepts before jumping into the code. Before beginning this assignment, refer to Chapter 5 of your book. Make sure you understand approaches of critical sections and mutual exclusion.

Further, please read this ARM document explaining LDREX and STREX atomic operations which you will use in your implementation of _lock_acquire.

 

Objective: Enforcing mutual exclusion across multiple cores

What happens when multiple cores attempt to print over the UART at the same time -- without mutual exclusion? Undesirable behavior.

Currently, your embedded operating system does not support mutual exclusion across multiple cores. Refer to system/testcases.c. In its current state, unparking cores 1, 2, and 3 to a function that prints "Hello World from core n" yields a distorted mess of characters.

To amend this behavior, you will implemente a spin-lock for XINU's serial port.

For this assignment, you will have to complete the spin lock acquire (_lock_acquire) function in system/spinlock_util.S. You will also have to complete lock_acquire and lock_release in system/spinlock.c

Make sure:

  • You have followed the "Preparation" steps above
  • You use your serial_lock in kprintf (refer to include/spinlock.h)

 

Testing

Refer to the testcases() function within system/testcases.c. By default, the testcases function unparks cores 1, 2, and 3 to a function called core_print(). Since core_print() does not take parameters, unparkcore() passes it NULL arguments.

If the cores print out neatly, then you will know that your _lock_acquire function works correctly (and that you properly called lock_acquire and lock_release in your kprintf function).

 

 
  Marquette University. Be The Difference. Marquette | Corliss |