操作系统代写 P4: Device Drivers

Overview

P4: Device Drivers

It’s a great life when you’re living the dream, working for the retro-gaming ScaleTech company. Soon, your company will be releasing the latest iteration in the classic GatorRaider game line, but this time, with a twist – it comes with a custom gaming device known as the ChompStick. Naturally, in typical game industry fashion, you don’t actually have the hardware – it’s still being finalized in the manufacturing division – so you’re working with a virtual USB device that mimics its behavior. The actual hardware will surely bring a few surprises, but the team needs to get it as close as possible using what you currently have.

In this project, you will implement a userspace device driver that reads data from the virtual USB device and route the results to the standard Linux device system in Reptilian. Your device driver must allow the virtual device to be treated exactly like any other joystick device – to the point where it can be used to control software that uses typical joystick input. It’s crunch time – the game is being released before the hardware (because of course it is), and you only have 3 weeks to get the driver ready!

NOTE: Take Snapshots in VirtualBox! It’s easy to cause crashes when working in the USB subsystem.

Structure

The project is broken into three main steps:

  1. 1)  Connect to and read data from the device in the USB subsystem
  2. 2)  Interpret the data (per the device specification) to determine the current device state
  3. 3)  Route the data back into the Linux input system as a conventional joystick

While exact implementation may vary, the driver name and functionality must match the specification laid out in this document.

COP4600

USB Device Specification

The ChompStick device, in USB parlance, is an interrupt-driven device with a single endpoint – that is, it sends data along a single communications channel whenever a request is sent to the device. Whenever the USB subsystem polls the ChompStick device, it sends a single byte of data, formatted as follows:

Button Y-Axis

00011101

Byte Value

0x1D

X-Axis

3

Y-Axis

1

Button

1

Padding (Unused) X-Axis

When the button is pressed, the button bit will be set (1); otherwise, the bit will be unset (0). Each axis has a range from 1 to 3 – with 1 representing the lowest value:

Y-Axis Values X-Axis Values

123 123

·

·

ChompStick has a Vendor ID value of 0x9A7A and a Product ID value of 0xBA17.

Driver Specification

The userspace driver will be a stand-alone executable. As you are building a prototype driver, it is not necessary for it to run in the background; for testing purposes it will be run in a separate terminal. (The mainline kernel team will build on your work later.) The driver executable should be named chompdrv and should not require any parameters or other dependencies to successfully execute – as long as the USB device is present, it should route its state information to the joystick device.

When the driver is successfully implemented, the jstest tool (outlined below) should yield these values:

Running the Device, Driver, & Game

In order to use the virtual device, a few setup steps are necessary.

  1. 1)  Install the new kernel configuration (in in the Project folder on Canvas) in /usr/rep/build/config
  2. 2)  Copy the virtual device and utilities (in chompstick.tgz) to the virtual machine
  3. 3)  Rebuild and reinstall the kernel and kernel modules
  4. 4)  Install the USB and joystick tools: $ sudo apt-get install libusb-1.0-0-dev usbip joystick

ChompStick Y-Axis

JS Field

Axis 1

If 0

(Invalid)

If 1

32767

If 2

0

If 3

-32767

ChompStick X-Axis

JS Field

Axis 0

If 0

(Invalid)

If 1

-32767

If 2

0

If 3

32767

ChompStick Button

JS Field

Button 0

If 0

off

If 1

on

Running the Virtual Device

Running the device requires two terminals: one to control the device, and another to collect data from it.

Terminal 1

Run the chompapp program. This creates the virtual USB device and displays a text-based controller for it.

Terminal 2

1) Connect the device to the USB subsystem:

$ sudo usbip -a 127.0.0.1 1-1
2) Run the chompread program to fetch and display

the current state of the USB device.

Note that this is only showing the USB raw data – it isn’t connecting the device as a conventional joystick! Once you finish writing the driver, it will bridge the gap between the text controller and the joystick system.

Running the GatorRaider Game

The GatorRaider game can be used for testing the device in the Android GUI. Follow these steps to install it:

  1. 1)  Open “Settings” from the menu; navigate to “Security”
  2. 2)  Turn on “Unknown sources”, and click “OK”
  3. 3)  Open Chrome in the Reptilian GUI
  4. 4)  Go to http://cise.ufl.edu/~jblanch/os/gatorraider.apk.
  5. 5)  Once downloaded, click “open”, then “Install”.

You can run the app any time; go to “GatorRaider” from the main menu. It can be controlled via arrow keys or a joystick. You can plug in an XBox controller (or many other joysticks) and connect it to VirtualBox via the “Devices””USB” drop-down menu (along the top of the VM). Once your joystick driver is working, you’ll be able to control the character via the console app.

Testing Your Driver

To test your driver, you should run the chompapp program in a terminal as described earlier. In a second terminal, you will need to connect it to the USB subsystem, then run your driver:

    $ sudo usbip -a 127.0.0.1 1-1
    $ sudo ./chompdrv

Using Yet-Another Terminal

To test from the command line, open yet another terminal window on Reptilian and run jstest: $ jstest /dev/input/js0

If your driver is successfully connected, you’ll see information about its buttons and axes. Note that if you’ve connected an external controller, js0 may be that external device. Be careful!

Using GatorRaider

The GatorRaider game is all set to use joystick controls. As such, once your driver is running, if it is properly functioning, it should automatically pick up input from this driver and use it to move the gator character!

Raw State: 0x1b Button State: 1
X State: 2
Y State: 3

    ┌────────┐
    │  Left  │
    └────────┘
(Pressed)
(Middle)
(Up)
┌────────┐
│   Up   │
└────────┘
┌────────┐
│ Button │
└────────┘
┌────────┐
│  Down  │
└────────┘

Q: Quit R: Refresh Space: Toggle Button Arrow Keys: Stick

┌────────┐ │Right │ └────────┘

Submissions

You will submit the following at the end of this project:

 Report on Canvas
 Screencast on Canvas
 Compressed tar archive (chompdrv.tar.gz) for chompdrv userspace driver on Canvas

Report

Your report will explain how you implemented the driver, including how you connected to the USB subsystem as well as the joystick input subsystem. It must include an explanation of the structures used and in what ways. It will include description of how testing was performed along with any known bugs. The report may be in Portable Document Format (pdf) or plain-text (txt) and should be no more than a page. It should cover all relevant aspects of the project and be organized and formatted professionally – this is not a memo!

Screencast

In addition to the written text report, you should submit a screencast (with audio) walking through the driver you wrote to connect the raw USB device to the joystick input system (~5 minutes).

Compressed Archive (classification.tar.gz)

Your compressed tar file should have the following directory/file structure:

To build the driver, we will execute these commands:

   $ tar zxvf chompdrv.tar.gz
   $ cd chompdrv
   $ make
   $ cd ..

To run the driver, we will execute this command:

$ chompdrv/chompdrv
Please test your driver build and linking before submission! If your driver does not compile it will result in zero

credit (0, none, goose-egg) for the code portion of the project. Helpful Links

You may find the following resources helpful when reading about how write the userspace driver:

https://www.dreamincode.net/forums/topic/148707-introduction-to-using-libusb-10/ https://www.kernel.org/doc/html/v4.12/input/uinput.html https://stackoverflow.com/questions/16032982/getting-live-info-from-dev-input

chompdrv.tar.gz
      chompdrv.tar

chompdrv (directory) chompdrv.c

Makefile

(Other source files)