Tag Archives: linux

Flashing the Jetson TK1 and installing CUDA

A few notes on flashing the Jetson TK1, in case I need to do this again…

I flashed the 21.3 version of Linux for Tegra. The first step was to download the files into a directory on a Linux system, on a Linux partition (originally, I was unpacking these in a ntfs partition shared with the Windows part of my dual boot configuration, which screwed up the permissions when unpacking – this was subtle!):

  • http://developer.download.nvidia.com/embedded/L4T/r21_Release_v3.0/Tegra124_Linux_R21.3.0_armhf.tbz2
  • http://developer.download.nvidia.com/embedded/L4T/r21_Release_v3.0/Tegra_Linux_Sample-Root-Filesystem_R21.3.0_armhf.tbz2

Then, I could roughly follow the instructions from NVIDIA. Let’s assume the two files above are in a directory called ~/reflash/ on a Linux computer (e.g. my laptop, which is running Ubuntu 12.04).

cd ~/reflash
sudo tar xpf Tegra124_Linux_R21.3.0_armhf.tbz2
cd Linux_for_Tegra/rootfs/
sudo tar xpf ../../Tegra_Linux_Sample-Root-Filesystem_R21.3.0_armhf.tbz2
cd ..
sudo ./apply_binaries.sh

Now, you have to put the Jetson in recovery mode. Connect the Jetson to your PC using the microUSB port on the Jetson, then hold the recovery button down on the Jetson and the press the Reset button once, or the Power button if it was off. The Jetson doesn’t seem to display anything to the screen when in recovery, so I wait, say, a minute to be really sure it’s in recovery. Then type ‘lsusb’ on the PC to make sure it lists a device by “Nvidia Corp.”, to ensure you can actually talk to the Jetson.

Now, the next step is to actually flash the thing, but there are a few issues:

  1. The default flashing instructions won’t use all the space available on the embedded memory (uses about 8GB instead of 16GB), which may be annoying if you need to have more toolkits installed. To use the full space, use the flag ‘-S 14580MiB ‘ (and you may have good reason not to do this – note that is the maximum you can use, as discussed on the elinux wiki).
  2. On the ubuntu version that I was running, /dev/loop0 was already being used, so the flash script failed since it is hard coded to use /dev/loop0. A neat trick I found to get this to work was to type ‘losetup –find’, which for me showed /dev/loop1 as the first available device. I thus edited flash.sh to use /dev/loop1 instead of /dev/loop0 (it was around line 440 of flash.sh)

With those 2 notes in mind, the next step on the PC was:

sudo ./flash.sh -S 14580MiB jetson-tk1 mmcblk0p1

This took about 30min, after which the Jetson will automatically reboot. The instructions say to “Reset” the board (even though it just rebooted), so I unplugged the USB cable and pressed the Reset button. The network cable was plugged into the Jetson the whole time, so when it rebooted, I had no issue logging in using ssh (checked my router status page to figure out the right IP address for ssh).

CUDA was easy to install from the instructions on elinux. I downloaded the following onto the Jetson:

  • http://developer.download.nvidia.com/embedded/L4T/r21_Release_v3.0/cuda-repo-l4t-r21.3-6-5-prod_6.5-42_armhf.deb

I actually downloaded it to my PC and scp’ed it to the Jetson.  Then I followed the instructions from elinux, and typed the following on the Jetson:

sudo dpkg -i cuda-repo-l4t-r21.3_6.5-42_armhf.deb
sudo apt-get update
sudo apt-get install cuda-toolkit-6-5
sudo usermod -a -G video $USER

I tested that CUDA installed by typing on the Jetson:

nvcc -V

and then proceeded to install the examples and compile them.

Setting up a VPS to host your own server

Here are some simple instructions to get you started on setting up a virtual private server (VPS), so that you can host your own website. This website, for example, is setup on a VPS. This solution is more flexible, in my opinion, then purchasing “hosting” space, since you have full control over the server (for example, you may need to edit some php settings that hosted spaces don’t always let you do). Also, you can serve as many different websites as you want, and setup any server you like (I use it for VPN, mail, etc). You have to know some Linux though…

    1. Purchase a VPS. I have gotten some good deals on LowEndBox.com; they often have deals going on. You should choose a server with at least 1GB of RAM. KVM might be slightly better than openVZ, but you probably won’t note the difference. If you can, choose one that gives you a tun/tap interface (most do); this is useful if you ever want to setup a VPN (so that your ISP won’t spy on you!)
    2. When you setup your VPS, choose Ubuntu 12.04 or 14.04 64 bit (if you can, otherwise, the most recent version of Ubuntu).
    3. Login to your server and configure it. The VPS provider will have probably given you instructions to login as ‘root’. Once you have logged in by ssh, you should create your own user:
      adduser uname

      and add that user to the sudo group:

      sudo usermod -a -G sudo uname

Disable ssh for the root user (since that is an easy to guess username). Edit the file /etc/ssh/sshd_config and make sure you have the following line:

PermitRootLogon no

(typically just a matter of un-commenting the relevant line)
You should also install a LAMP stack (Linux, Apache, MYSQL, PHP) (google ‘Ubuntu LAMP stack’). As a minimum, install the apache web server, so that you can easily test your server with a browser.

sudo apt-get install apache
  1. Setup a DNS server. If you want to have a website with a domain name, rather than just an IP address. I typically by a domain name from GoDaddy. Once you own a domain name, you need to setup a DNS server (which tells other computers that your domain name points to a specific IP. I use freedns.afraid.org. You can get a free account, then add the domain that you own. If you then go to “sub-domains”, you can setup the IP address of your main domain and any subdomains that you want to setup under it (e.g. www.). Once you have setup the DNS on afraid.org, you need to go back to GoDaddy to manage your domain name and change its “domain name servers”, where you should set them to, for example, ns1.afraid.org, ns2.afraid.org, ns3.afraid.org, ns4.afraid.org (use all four). It might take several hours for GoDaddy and afraid.org to sync up, but when they do, your domain name is equivalent to the IP address (whether by ssh or html in your browser).

python script to solve ODEs

Here is a simple python script that will solve a system of N Ordinary Differential Equations, based on N initial conditions. It will plot the result using matplotlib (so you have to install that python module). It uses a Runge-Kutta 4th-5th order stepper (inspired by the course that I thought at USD and by Numerical Recipes). The “driver” that uses the stepper is not fancy (i.e. there is no variable optimized step size).

The specific problem is implemented by filling the derivs() function (it wants an array giving all the derivatives of the functions to be solved, yin, as a function of x). e.g. dy1/dx = a1, dy2/dx = a2 (where the as are the elements of the array and can depend on the ys and x).

The example below implements a simple harmonic oscillator (dx/dt=v, dv/dt=-kx), where position and speed are the two variables (y[0] and y[1]) to solve. The initial conditions are a speed of 0 and a position of x=1, at t=0.

#! /usr/bin/python

#from ROOT import TGraph, TCanvas
import matplotlib.pyplot as plt

#RK4-5 stepper
def step(stepsize, yin, x, derivs):
    dy=derivs(x,yin)
    k1=[]
    y2=[]
    for i in range(0,len(yin)):
        k1.append(stepsize*dy[i])
        y2.append(yin[i]+0.5*k1[i])

    dy=derivs(x+0.5*stepsize,y2)
    k2=[]
    y3=[]
    for i in range(0,len(yin)):
        k2.append(stepsize*dy[i])
        y3.append(yin[i]+0.5*k2[i])

    dy=derivs(x+0.5*stepsize,y3)
    k3=[]
    y4=[]
    for i in range(0,len(yin)):
        k3.append(stepsize*dy[i])
        y4.append(yin[i]+k3[i])

    dy=derivs(x+stepsize,y4)
    k4=[]
    yout=[]
    for i in range(0,len(yin)):
        k4.append(stepsize*dy[i])
        yout.append(yin[i]+k1[i]/6.0+k2[i]/3.0+k3[i]/3.0+k4[i]/6.0)

    return yout

def solve(stepsize,x0,nSteps,derivs,initialConditions):
    y=[]
    y.append([x0,initialConditions])
    print "Initial ", y
    for i in range (0,nSteps):
      x=x0+i*stepsize
      #print y[len(y)-1][1:][0]
      y.append([x,step(stepsize,y[len(y)-1][1:][0],x,derivs)])
    return y

def plot(yx):
    ny=len(yx[1])
    for i in range(0,ny):
        y=[]
        x=[]
        for j in range (0,len(yx)):
            x.append(yx[j][0])
            y.append(yx[j][1][i])
        plt.plot(x,y)
        plt.show()

#problem-specific derivatives
def derivs(x,yin):
    print "derivatives at ",x," ",yin
    dy=[yin[1],-0.5*yin[0]]
    return dy

########################################
########################################
#initial conditions for each function
initialConditions=[1,0]
yx=solve(0.1,0.0,100,derivs,initialConditions)

#Do the drawing
plot(yx)

IPTables rules for a server

Here are some useful iptables rules, that let you run ssh (22), openvpn server (1194), mail (25,110, 143, 993, 995), rsync (873), ping (icmp), SOCKS (1080), and web servers (80, 443), while blocking all other ports. These are assumed to be in a script that you can run at startup (for example in /etc/rc.local). On an openVZ machine, I had to replace ‘eth’ by ‘venet’ in this script.  Also, for the INPUT chain, it should also be ok (better) to have all the states (NEW, ESTABLISHED, RELATED) instead just (NEW, RELATED).

 

#! /bin/bash
#all output on tun and eth are ok
iptables -A OUTPUT -o tun+ -j ACCEPT
iptables -A OUTPUT -o eth+ -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

#allow specific incoming connections:
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 873 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 143 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 993 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 995 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED -p tcp --dport 1080 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -i eth0 -j DROP

#allow tun interface to forward to eth:
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
#definitely need this one:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
#can also have instead, if MASQUERADE does not work:
#iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source your_vps_ip
exit 0

Setting up a wordpress site

This website has good instructions! Here they are for Ubuntu, augmented with some small modifications:

  1.  Install a LAMP stack on your server (apache, mysql, php)
  2. Download the latest wordpress (say into your home directory)
    wget http://wordpress.org/latest.tar.gz
    tar -xvzf latest.tar.gz
    cp wordpress/wp-config-sample.php wordpress/wp-config.php
    
  3. Create a database and configure it
    mysql -u root -p #to start mysql
    CREATE DATABASE DatabaseName;
    CREATE USER User@localhost;
    SET PASSWORD FOR User@localhost= PASSWORD("ThePassword");//choose a different password!
    GRANT ALL PRIVILEGES ON DatabaseName.* TO User@localhost IDENTIFIED BY 'ThePassword';
    FLUSH PRIVILEGES;
    exit;
    
  4. Create the directories for the website<
    sudo mkdir /var/www/website #where website is, e.g. ryanmartinphd.com
    sudo cp -r wordpress/* /var/www/website/.
    cd /var/www
    sudo chown www-data:www-data * -R #www-data owns the direcctory
    sudo usermod -a -G www-data linux_user_name #not strictly necessary
    sudo vi /var/www/website/wp-config.php #edit this to set the database parameters (next step)
    
  5. Configure wordpress for the database.In the wp-config.php file, make sure to edit these to the same value you did when setting up the database in mysql:
    define('DB_NAME', 'DatabaseName');
    define('DB_USER', 'User');
    define('DB_PASSWORD', 'ThePassword');
    
  6. Configure a virtual host on apache. Start with the default virtual server:
    cd /etc/apache2/sites-available
    sudo cp default website
    sudo vi website
    

    Now edit the following lines:

    <VirtualHost *:80>
    	ServerAdmin your_email_address
    	ServerName website.com
    	ServerAlias www.website.com
    	
    	DocumentRoot /var/www/website
    	<Directory />
    		Options FollowSymLinks
    		AllowOverride None
    	</Directory>
    	<Directory /var/www/website>
    		Options Indexes FollowSymLinks MultiViews
    		AllowOverride All
    		Order allow,deny
    		allow from all
    	</Directory>

    Now, enable the site, install an additional php module, enable mod_rewrite, and restart apache:

    sudo a2ensite website
    sudo apt-get install php5-gd
    sudo a2enmod rewrite
    sude service apache2 restart
    
  7. Launch the wordpress site by navigating to it. This will let you create the first user and should automatically setup everything
  8. Edit /etc/php5/apache2/php.ini to change the max_post_size, and max_upload variables to something bigger than their defaults (e.g. 100M).

Installing openvpn server (Ubuntu 12.04)

This page is mostly based on these instructions (starting at appendix A2). I have followed the procedure below to get VPN servers running on 2 different virtual private servers. In each case, those have a “tun” interface (google how to check if tun interface is loaded for your VPS).

Everything is done as root. Comments on the various steps are marked with a pound sign (#).

Install OpenVPN and setup the structure to build the encryption keys

sudo -s #to become root
apt-get install openvpn #to install openvpn
cp –r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa #to copy rsa-config files and scripts
cd /etc/openvpn/easy-rsa

Open the file /etc/openvpn/easy-rsa/vars and make sure you have the following:

export EASY_RSA="/etc/openvpn/easy-rsa" #necessary
export KEY_COUNTRY="US"#optional
export KEY_PROVINCE="CA"#optional
export KEY_CITY="SanFrancisco"#optional
export KEY_ORG="MartinLys"#optional
export KEY_EMAIL="admin@myvpnserver.com"#optional
export KEY_EMAIL=mail@host.domain#optional
export KEY_CN=changeme#optional
export KEY_NAME=myvpnserver.com#optional
export KEY_OU=changeme#optional
export PKCS11_MODULE_PATH=changeme#optional
export PKCS11_PIN=1234#optional

Now build the certificates (from the easy-rsa directory):

source vars
./clean-all
./build-ca #the values that you enter are not important

Build the certificate/key files for the server

./build-key-server serverName

Answer the following questions:

Common Name [serverName]: #Must be the same as serverName
A challenge password: #Must leave blank!
Sign the certificate? [y/n]: y
1 out of 1 certificate requests certified, commit? [y/n] y

Now, generate the certificates for the clients (assuming you have a client called UserName, which does not need to be a linux user on your server)

./build-key UserName

Answer the questions

Common Name [UserName]: #must be the same as UserName
A challenge password: #Must leave blank!
Sign the certificate? [y/n]: y
1 out of 1 certificate requests certified, commit? [y/n] y

Repeat this for all clients (which will generate files in “keys/” called UserName.crt and UserName.key). Then, build the Diffie-Hellman key:

cd /etc/openvpn/easy-rsa/
./build-dh #(this takes a few seconds)

Then, create the OpenVPNaHMAC Key with:

openvpn –-genkey –-secret keys/ta.key

Create the file /etc/openvpn/server.conf with the following in it:

local XXX.XXX.XXX.XXX #this is the public IP of your server (try commenting this out if you get the error:" Socket bind failed on local address [AF_INET]xxxxx:1194: Cannot assign requested address"
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/serverName.crt #name that you gave build-ca
key /etc/openvpn/easy-rsa/keys/serverName.key #name that you gave build-ca
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
server 10.8.0.0 255.255.255.0 #range of IP address that it will give out (change this if it conflicts with your network and submask
push "dhcp-option DNS 8.8.8.8" #use Google DNS
push "dhcp-option DNS 8.8.8.4" #more Google DNS
push "redirect-gateway def1 bypass-dhcp"
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0 #TLS auth key
keepalive 10 120
cipher AES-128-CBC
comp-lzo #use compression
user nobody #run openvpn as nobody:nogroup
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 0 #increase the number if you want more logging (max = 5?)

Make sure the IP V4 forwarding is on, by making sure that the following line in /etc/sysctl.conf is uncommented:

net.ipv4.ip_forward=1

Apply the changes with :

sysctl -p

You need to add rules using iptables to forward the VPN traffic. I’m not completely sure that all the lines are necessary, but this seemed to work! On one of my virtual servers running in OpenVZ, I had to replace “eth0″ by “venet0″, as that was apparently the name of the network interface (use ifconfig to check which interface has the external address). Note that the rules refer to the subnet that you chose in server.conf (10.8.0.0/24 in this case, so modify the rules as appropriate). You could place the following in a (executable, chmod 700) script, e.g., /etc/openvpn/firewallrules.sh:

#! /bin/bash
#probably not necessary (default for output should be accept)
iptables -A OUTPUT -o tun+ -j ACCEPT
#not sure that this is needed:
iptables -A INPUT -i eth0 -m state --state NEW -p udp --dport 1194 -j ACCEPT
#these are most likely the ones that matter:
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
#definitely need this one:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
exit 0

You can add this to your start-up scripts, for example when your network interface comes up. In which case, edit /etc/network/interfaces, and add the following code immediately below the line with “iface eth0 inet dhcp” (or similar I actually put it under the “lo” interface and it worked fine), with indentation:

iface eth0 inet dhcp 
   pre-up /etc/openvpn/firewallrules.sh

When you reboot the server, openvpn server should now be running, and the forwarding should work. On my OpenVZ machine, I found that /etc/network/interfaces gets over-written at reboot, so I added the following line to /etc/rc.local:

/etc/openvpn/firewallrules.sh

To start openvpn server, as root, type:

openvpn /etc/openvpn/server.conf

You then need to create a configuration file for each client. If you place the following (executable, chmod 700) script in the etc/openvpn/build-client-config-file.sh:

#! /bin/bash
client=$1
server="serverName" #this is the IP address of the server (or domain name)
keydir="/etc/openvpn/easy-rsa/keys" #where the keys were saved if you followed the instruction on this webpage
ca="$keydir/ca.crt"
cert="$keydir/$client.crt"
key="$keydir/$client.key"
tls="$keydir/ta.key"
configfile=$1".ovpn"
echo -e "client \ndev tun\nproto udp\nkey-direction 1\nremote $server 1194\nresolv-retry infinite\nnobind\nns-cert-type server\ncomp-lzo\nverb 3\ncipher AES-128-CBC\n">$configfile
echo "<ca>">>$configfile
cat $ca>>$configfile
echo "</ca>">>$configfile
echo "<cert>">>$configfile
cat $cert>>$configfile
echo "</cert>">>$configfile
echo "<key>">>$configfile
cat $key>>$configfile
echo "</key>">>$configfile
echo "<tls-auth>">>$configfile
cat $tls>>$configfile
echo "</tls-auth>">>$configfile

You can easily create a config files for each client (called UserName, same as before, as the script will look for the corresponding files) by typing:

./build-client-config-file.sh UserName

This will output an OpenVPN configuration file called “UserName.ovpn” which can be given (securely) to the client. At this point, you could delete the following files from the server:

ca.key #I'm not sure you can actually delete this one, if you wanted to generate more clients.
UserName.key
UserName.ovpn