ECE 4750 Section 1: Linux Development Environment

Table of Contents

This discussion section serves as gentle introduction to the basics of using the Linux development environment on the ecelinux servers including how to log into the servers, how to work at the Linux command line, and how to use Git version control. You should start by logging into the ecelinux servers using the remote access option of your choice based on working through the remote access tutorial for the discussion section:

If you are having trouble using VSCode then use PowerSell or Mac Terminal for the discussion section.

Linux Command Line

We will using the ecelinux servers which run the Red Hat Enterprise Linux 7 operating system for all of the programming assignments. The heart of the Linux operating system is the Linux command line. This is a text-based console where you can enter commands to interact with the operating system.

Hello World

We begin with the ubiquitous “Hello, World” example. To display the message “Hello, World” we will use the echo command. The echo command simply “echoes” its input to the console.

% echo "Hello, World"

The string we provide to the echo command is called a command line argument. We use command line arguments to tell commands what they should operate on. Again, note that you do not need to enter % character.

Manual Pages

You can learn more about any Linux command by using the man command. Try using this to learn more about the echo command.

% man echo

You can use the up/down keys to scroll the manual one line at a time, the space bar to scroll down one page at a time, and the q key to quit viewing the manual.

Create, View, and List Files

We can use the echo command and a feature called command output redirection to create simple text files. Command output redirection is discussed more in the full tutorial. Command output redirection uses the > operator to take the output from one command and “redirect” it to a file. The following commands will create a new file named ece4750-sec01.txt that simply contains the text “Computer Architecture”.

% echo "Computer Architecture" > ece4750-sec01.txt

We can use the cat command to quickly display the contents of a file.

% cat ece4750-sec01.txt

For larger files, cat will output the entire file to the console so it may be hard to read the file as it streams past. We can use the less command to show one screen-full of text at a time. You can use the up/down keys to scroll the file one line at a time, the space bar to scroll down one page at a time, and the q key to quit viewing the file.

% less ece4750-sec01.txt

The > command output redirection operator will always create a brand new file (even if the target output file already exists). You can use the >> operator to append lines to the end of a file. Let’s add another line to our text file using the >> operator.

% echo "Using C/C++" >> ece4750-sec01.txt
% cat ece4750-sec01.txt

You can use the ls command to list the filenames of the files you have created.

% ls

We can provide command line options to the ls command to modify the command’s behavior. For example, we can use the -1 (i.e., a dash followed by the number one) command line option to list one file per line, and we can we can use the -l (i.e., a dash followed by the letter l) command line option to provide a longer listing with more information about each file.

Create, Change, and List Directories

Obviously, having all files in a single location would be hard to manage effectively. We can use directories (also called folders) to logically organize our files, just like one can use physical folders to organize physical pieces of paper. The mechanism for organizing files and directories is called the file system. When you first log in to an ecelinux machine, you will be in your home directory. This is your own private space on the server that you can use to work on the programming assignments and store your files. You can use the pwd command to print the directory in which you are currently working, which is known as the current working directory.

% pwd
/home/netid

You should see output similar to what is shown above, but instead of netid it should show your actual NetID. The pwd command shows a directory path. A directory path is a list of nested directory names; it describes a “path” to get to a specific file or directory. So the above path indicates that there is a toplevel directory named home that contains a directory named netid. This is the directory path to your home directory. As an aside, notice that Linux uses a forward slash (/) to separate directories, while Windows uses a back slash (\) for the same purpose.

We can use the mkdir command to make new directories. The following command will make a new directory named ece4750 within your home directory.

% mkdir ece4750

We can use the cd command to change our current working directory. The following command will change the current working directory to be the newly created ece4750 directory, before displaying the current working directory with the pwd command.

% cd ece4750
% pwd
/home/netid/ece4750

Use the mkdir, cd, and pwd commands to make another directory.

% mkdir sec01
% cd sec01
% pwd
/home/netid/ece4750/sec01

We sometimes say that sec01 is a subdirectory or a child directory of the ece4750 directory. We might also say that the ece4750 directory is the parent directory of the sec01 directory. Use the following command to create a new file in this child directory.

% cd /home/netid/ece4750/sec01
% echo "Computer Architecture" > ece4750-sec01.txt
% mkdir dirA
% ls

You can use the tree command to visualize the directory layout and where files are located:

% cd ~/ece4750
% tree

Note that the tilde character (~) is a shortcut which always refers to your home directory. There are a few other very useful shortcuts. You can use a single dot (.) to refer to the current working directory, and you can use a double dot (..) to refer to the parent directory of the current working directory.

% cd ~/ece4750/sec01
% cd ..
% cd ..
% pwd

Copy, Move, and Remove Files and Directories

We can use the cp command to copy files. The first argument is the name of the file you want to copy, and the second argument is the new name to give to the copy. The following commands will make two copies of the files we created in the previous section.

% cd ~/ece4750/sec01
% cp ece4750-sec01.txt ece4750-sec01-a.txt
% cp ece4750-sec01.txt ece4750-sec01-b.txt
% ls

Instead of copying we can also move a file with the mv command:

% cd ~/ece4750/sec01
% mv ece4750-sec01.txt ece4750-sec01-c.txt
% ls

Finally, we can use the rm command to remove files.

% cd ~/ece4750/sec01
% ls
% rm ece4750-sec01-a.txt

Text Editors

Students are free to use any text editor they want, although we recommend students use VS Code which we will learn about next week. VS Code is both a remote access option and a text editor. If you are using Terminal, you can always resort to nano, emacs, or even vim if you are brave:

% nano ece4750-sec01-b.txt

PowerShell users can launch notepad.exe instead, install the Windows Subsystem for Linux (WSL), or just give up on Windows entirely. :-)

For ECE 2400 Alumni (or Advanced Students)

For students that took ECE 2400, they will recognize this section as being identical to the first section in ECE 2400. We are trying to make sure all students are able to successfully log in to the ecelinux servers, setup their GitHub account correctly, and understand the basic Git workflow. ECE 2400 students probably already know all of this. They should still confirm they can fork and clone the example GitHub repo and then push/pull to this repo.

ECE 2400 students may want to experiment with cross-compiling C code (like we wrote in ECE 2400) for the RISC-V instruction set architecture and then running the resulting binary on a RISC-V instruction set simulator as discussed below.

Compile a simple C program for Intel x86

Let’s compile the very first program you saw in ECE 2400. First make sure we have a directory to work in:

% mkdir -p ${HOME}/ece4750/sec01
% cd ${HOME}/ece4750/sec01

Then use your favorite text editor to create a file named avg-main.c.

#include <stdio.h>

int avg( int x, int y )
{
  int sum = x + y;
  return sum / 2;
}

int main()
{
  int a = 10;
  int b = 20;
  int c = avg( a, b );
  printf( "average of %d and %d is %d\n", a, b, c );
  return  0;
}

Recall how to compile this C program into an x86 binary and execute this binary on the ecelinux server.

% cd ${HOME}/ece4750/sec01
% gcc -Wall -o avg-main avg-main.c
% ./avg-main

Cross-compile a simple C program for RISC-V RV32IM

In this course, we will be using the RISC-V instruction set architecture instead of the x86 instruction set architecture. You can use a cross-compiler to compile a C program into a RISC-V binary like this:

% cd ${HOME}/ece4750/sec01
% riscv32-unknown-elf-gcc -O3 -o avg-main-riscv avg-main.c

Now let’s take a look at the actual RISCV instructions using riscv32-objdump:

% riscv32-objdump avg-main-riscv

See if you can find the instructions that correspond to the avg function. See if you can figure out how the C code maps to these RISCV instructions. Use the TinyRV2 instruction set architecture manual located here:

Experiment with the following variation and look at the corresponding RISCV instructions.

unsigned int avg( unsigned int x, unsigned int y )
{
  unsigned int sum = x + y;
  return sum / 2;
}

Can you explain the difference from the original version of this code?

Execute RISC-V instructions on a simulator

CS 3410 uses a neat RISC-V simulator which works in your browser:

Try copying the RISC-V instructions for just the avg function into this RISC-V interpreter. Then execute instruction step-by-step and verify they behave as expected.