(Adds section on systemd and systemctl.)
(Moves many sections to the Linux page as they are not specific to Ubuntu.)
Line 4: Line 4:
<br />
<br />
<br />
<br />
=== Setting up WLAN in a Headless Installation ===
If you are on a headless Ubuntu installation (i.e., no GUI) you can set up WLAN access via the command line.
<br />
<br />
In the '''/etc/netplan''' folder, find the network configuration definition file (most likely '''50-cloud-init.yaml'''). Open the file in an editor. You should find an existing ethernet configuration:
<pre class="code">
network:
    ethernets:
        eth0:
            dhcp4: true
            optional: true
    version: 2
</pre>
where ''eth0'' is an example ethernet interface. To add a WiFi configuration, add the lines
<pre class="code">
    wifis:
        <wlan>:
            optional: true
            access-points:
                "<ssid>":
                    password: "<password>"
            dhcp4: true
</pre>
where ''<wlan>'' is usually ''wlan0'', and ''<ssid>'' and ''<password>'' need to be replaced with the actual WiFi SSID and password.
<br/>
<br/>
As this is a YAML file, make sure that indentation levels are correct and only whitespace (no tab characters) is used.
<br/>
<br/>
Now activate the new configuration via
<pre class="terminal">
sudo netplan apply
</pre>
and check with
<pre class="terminal">
ip a
</pre>
<br/>


=== Determining the Version of Ubuntu Running ===
=== Determining the Version of Ubuntu Running ===
Line 97: Line 58:
<br/>
<br/>
<br/>
<br/>
=== SSH Logins Without Typing The Password ===
If you connect to a remote computer via ''ssh'' or copy files via ''scp'' frequently, you should consider using ''ssh-agent'', which saves you from typing your login password each time.
<br />
<br />
First, you create an RSA public/private key pair that identifies your local machine. You may already have created such a key in your SSH keychain. It is good security practice, however, to use a separate key for each device you want to connect to. Let us assume you want to connect to a [[Raspberry Pi]]. The command to create a new SSH key would be
<pre class="terminal">
ssh-keygen -t rsa -b 2048 -C "for Raspberry Pi"
</pre>
where '-b 2048' specifies the key length in bits. You will be prompted to enter the path and name of the file in which the key will be saved. Choose a name that makes it clear that it was created for connecting to the Raspberry Pi. Next, you will be prompted for a password. Just press the Enter key for no password.
<br />
<br />
Now that the SSH key is created, you need to copy the generated key ('''public''') into the folder ''/home/pi/.ssh/'' on the Raspberry Pi:
<pre class="terminal">
scp ~/.ssh/for-raspberry-pi_rsa.pub pi@192.168.1.10:/home/pi/.ssh/authorized_keys
</pre>
The copied file is renamed to '''authorized_keys''', which is the expected file name for the SSH server to look up the public keys of trusted clients.
<br />
If ''authorized_keys'' is to hold multiple keys, you should use '''ssh-copy-id''' instead of ''scp'':
<pre class="terminal">
ssh-copy-id -i ~/.ssh/for-raspberry-pi_rsa.pub pi@192.168.1.10
</pre>
<br />
Now use ''ssh-agent'' on your local machine to start a special shell session that uses the new SSH key to automatically authenticate any SSH connection from your machine to the Raspberry Pi:
<pre class="terminal">
eval "$(ssh-agent -s)" # starting a new shell session
ssh-add ~/.ssh/for-raspberry-pi_rsa
</pre>
Done! This was the last time you had to enter the password for user ''pi''.
<br />
<br />
By the way, you can list all the keys that were added to the SSH agent by entering
<pre class="terminal">
ssh-add -l
</pre>
<br />
<br />
=== Message of the Day (MOTD) ===
If a Ubuntu system is used in a hardware setup without a connected display (e.g., embedded in a robot) it is usually still accessible through a terminal session. To help the user successfully juggle multiple terminal sessions to multiple devices, you can set a custom ''message of the day'', or ''MOTD'', that will be shown at each login. Have a look at the files in '''/etc/update-motd.d/'''. This is where you can edit the parts of the dynamically generated MOTD. The files are shell scripts which are executed in alphabetical order. The output of the shell commands form the MOTD. The names of the script files start with a number between 1 and 99, which makes ordering of the scripts immediately visible. You can edit the scripts to customize their output. You can delete a script file or flip its execution bit via ''chmod'' in order to disable it. You can also add a new script file to insert your custom message between two existing MOTD items. Please refer to the Internet knowledge for the details.
<br />
<br />
Additionally you can create the file '''/etc/motd''' whose static contents will be appended to the dynamically generated MOTD. You can embellish your MOTD with ASCII art, for example, like the Robo.Fish logo below
<br />
<br />
<pre class="code">
                                      .';cldxxkkkxxdolc;,..
                                  .;oOXWWMMMMMMMMMMMMMMWWXKOxo:,.
                                'o0WMMMMMMMMMMMMMMMMMMMMMMMMMMMWX0xl:'.
                              .;xXMMMMMMMMMMMMMMMMMMMMMMMMMWWWNNXXKKK0kd:.
                            .:ONMMMMMMMMMMMMMMMMMMWXKOxdoc:;;,'..........
.                        'o0WMMMMMMMMMMMMMMWN0xl:,..
Xx:.                  .:kXWMMMMMMMMMMMMMN0d:'.
MMWKxc'.          .'cxXWMMMMMMMMMMMMNOo:,.
MMMMMMN0xc,.  .,cd0NWMMMMMMMMMMMMN0o,.
MMMMMMWWNX0d:;ckKNWMMMMMMMMMMWN0xl,.
lllcc:;,'..    ..,;:clloollc:,..
</pre>
<br />
The MOTD can be previewed without needing to start a new shell session:
<pre class="terminal">
sudo run-parts /etc/update-motd.d/
</pre>
<br />
<br />
=== Switching to GUI-less (Multi-user) Mode ===
Ubuntu uses systemd to control whether the graphical user interface is loaded and shown. To turn off the graphical desktop immediately enter
<pre class="terminal">
sudo systemctl isolate multi-user.target
</pre>
To prevent the GUI from being loaded during the system startup, type
<pre class="terminal">
sudo systemctl set-default multi-user.target
</pre>
To return to the graphical desktop, type
<br/>
<pre class="terminal">
sudo systemctl isolate graphical.target
</pre>
and to make the graphical desktop the default again, type
<pre class="terminal">
sudo systemctl set-default graphical.target
</pre>
<br />
=== Setting the Screen Resolution for GUI-less Mode ===
* Restart the machine to the Grub boot menu.
* Press 'c' to get into the Grub command console.
* Run the command 'vbeinfo' to list possible resolutions.
* Note down the desired resolution. For example, ''1024x768x32'', where ''32'' is the color mode.
* Type ''exit'' to return to the Grub boot menu and boot into Ubuntu.
* Open '''/etc/default/grub''' in an editor to add the line
<pre class="code">
GRUB_GFXPAYLOAD_LINUX=1024x768x32
</pre>
* Optionally, add the line
<pre class="code">
GRUB_GFXMODE=1024x768
</pre>
to set the screen resolution for the GRUB boot menu itself.
* Finally, run the Grub updater
<pre class="terminal">
sudo update-grub
</pre>
<br />
<br />


=== NFS (Network File System) ===
=== NFS (Network File System) ===
Line 239: Line 94:
where ''vers=4'' indicates the NFS protocol version, ''192.168.178.8'' is the address of the NFS server, ''/storage'' is the path of the served directory on the NFS server (in NFS version 4 the path is relative to the served NFS root directory), and ''/backups'' is the mount point on the client machine
where ''vers=4'' indicates the NFS protocol version, ''192.168.178.8'' is the address of the NFS server, ''/storage'' is the path of the served directory on the NFS server (in NFS version 4 the path is relative to the served NFS root directory), and ''/backups'' is the mount point on the client machine
<br />
<br />
<br />
=== systemd and systemctl ===
Ubuntu uses the ''systemd'' initialization manager. ''systemd'' manages services that can be configured to start when the system is booted or on demand.
<br />
<br />
The command-line tool for starting or stopping a service is '''systemctl'''. Here is an example of using ''systemctl'' to query the status of the SSH server.
<pre class="terminal">
systemctl status sshd
</pre>
<br />
To start or stop the server, you would type
<pre class="terminal">
sudo systemctl start sshd
sudo systemctl stop sshd
</pre>
<br />
To configure a service, edit its configuration file located in '''/etc/systemd/system'''.
<br />
<br />
=== Controlling Bluetooth ===
On most Linux systems, Bluetooth functionality is provided by the kernel module, libraries and utilities of the [http://www.bluez.org BlueZ] project. So, make sure that BlueZ is installed.
<pre class="terminal">
sudo apt install bluez
</pre>
<br />
==== Bluetooth Low Energy (BLE) Control in Terminal ====
Set the Bluetooth controller to operate in BLE mode only by editing '''/etc/bluetooth/main.conf''' to make sure that the value of ''ControllerMode'' is set to ''le''.
<pre class="code">
ControllerMode = le
</pre>
If a change had to be made, you need to reboot the system.
<br />
<br />
Now issue the command
<pre class="terminal">
sudo systemctl start bluetooth
</pre>
to start the ''bluetooth'' service. You can also stop, restart and query the status with by replacing ''start'' with ''stop'', ''restart'', ''status'', respectively.
<br />
<br />
With the bluetooth service running, enter the command
<pre class="terminal">
bluetoothctl
</pre>
which runs a Bluetooth control program in the terminal. In this program you can, for example, display the list of commands, query the controller, power on the controller, scan for devices with RSSI 80 or better, advertise with the local name ''RPi3'' and, finally, power off and quit the program with the following commands:
<pre class="terminal">
help
show
power on
menu scan
rssi 80
back
scan on
...
scan off
discoverable on
advertise on
menu advertise
name RPi3
back
...
advertise off
power off
quit
</pre>
==== Bluetooth Programming via D-Bus ====
Here is an (incomplete!) example of programming D-Bus in C++ using the [https://github.com/Kistler-Group/sdbus-cpp/blob/master/docs/using-sdbus-c++.md sdbus-c++] C++ binding, for which you need to install ''libsdbus-c++-dev''.
<pre class="terminal">
sudo apt install libbluetooth-dev libsdbus-c++-dev
</pre>
<br />
Inspired by [https://punchthrough.com/creating-a-ble-peripheral-with-bluez/ this article from PunchThrough's Andy Lee], I have created a basic BLE peripheral.
<pre class="code">
#include <sdbus-c++/sdbus-c++.h>
#include <iostream>
/**
* Names of D-Bus system services can be looked up with the terminal command
*
*  busctl list
*
* We see that the name of the D-Bus system service of the bluetooth daemon is 'org.bluez'.
* The D-Bus object path for a given system service can be queried with the terminal command
*
*  busctl tree <service name>
*
* For 'org.bluez' let us assume the object path is '/org/bluez/hci0'.
* We can now introspect the interfaces available in the D-Bus object via
*
*  busctl introspect org.bluez /org/bluez/hci0
*
* or
*
*  gdbus introspect -y -d "org.bluez" -o "/org/bluez/hci0"
*
* We will use to the methods and properties in the published interfaces
* to create a BLE peripheral which advertises a service named 'Test'.
* Additional information on the methods and their parameters can be looked up from
* the BlueZ documentation at https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
*/
int main(int numargs, char* args[])
{
        const char* bluezServiceName = "org.bluez";
        const char* bluezObjectPath = "/org/bluez/hci0";
        const char* interface_adapter = "org.bluez.Adapter1";
        const char* interface_advertisingManager = "org.bluez.LEAdvertisingManager1";
        auto bluezProxy = sdbus::createProxy(bluezServiceName, bluezObjectPath);
        if (bluezProxy == nullptr)
        {
                std::cerr << "Error while creating proxy to BlueZ D-Bus service." << std::endl;
                return EXIT_FAILURE;
        }
        bluezProxy->setProperty("Powered").onInterface(interface_adapter).toValue(true);
        bluezProxy->setProperty("Alias").onInterface(interface_adapter).toValue("Test");
// TO BE DONE
        bluezProxy->finishRegistration();
        std::cout << "BLE Peripheral Example" << std::endl;
        return EXIT_SUCCESS;
}
</pre>
<br />
build with
<pre class="terminal">
my_arch=`uname -i`
g++ -o ble-peripheral main.cpp -L/usr/lib/${my_arch}-linux-gnu -lsdbus-c++
</pre>
<br />
<br />



Revision as of 2022-12-09T12:57:03



Introduction

Ubuntu is a Linux distribution with excellent support and a broad user community. Many technical projects use this distribution as their target platform. Ubuntu is based on Debian Linux. The package management tools are therefore dpkg and apt-get.

Determining the Version of Ubuntu Running

Use the lsb_release command to view version information about the running LSB-compliant Linux system.

sudo apt install lsb-release
lsb_release -a

generates the example output

No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.1 LTS
Release:	22.04
Codename:	jammy


Upgrading To A New Release

First of all, check you current version by typing

lsb_release -a

To upgrade to a new major release (for example, 16.04 to 16.10) type the command

do-release-upgrade

If there is no major release available but a point release has been issued, you can upgrade by typing

sudo apt-get update
sudo apt-get dist-upgrade


Working With Repositories

Repository Sources

Third-party repositories can be added to the list of source repositories with the command

sudo apt-add-repository <repository URL>


Source repositories that are provided by Ubuntu can be found in the file /etc/apt/sources.list. Third-party repositories that have been added afterwards can be found in the directory /etc/apt/sources.list.d/.

Querying Installed Packages

To find out which package a given file belongs to:

apt contains <file path>


To find out which files are included in a package use the Debian utility dpgk:

dpkg -L <package name>



NFS (Network File System)

Setting up an NFS Server

sudo apt install nfs-kernel-server

then edit /etc/exports to add lines in the following format:

<directory>    <hostname>(<options>) [<hostname>(<options>)]*

where <directory> is the directory that you want to make available over NFS, followed by one or more pairs of client host names and access options. <hostname> can be an IP address, a domain name with wildcards, or a subnet. of the allowed client machine, <options> is a list of options that determine whether the directory is, e.g., writable. The file format is better explained in this article. Examples are

/home/james/photos    192.168.178.62(r,async) 192.168.178.55(r, async)
/mnt/storage2         192.168.178.0/24(rw,sync,no_subtree_check)

After editing /etc/exports, apply the NFS configuration via /usr/sbin/exportfs:

sudo exportfs -ar


Query the allowed NFS protocol versions for the clients via

sudo cat /proc/fs/nfsd/versions


Mounting an NFS Drive

sudo apt install nfs-common

and mount the NFS with the usual /usr/bin/mount command using the -t nfs option like in this example:

 
sudo mount -t nfs -o vers=4 192.168.178.8:/storage /backups

where vers=4 indicates the NFS protocol version, 192.168.178.8 is the address of the NFS server, /storage is the path of the served directory on the NFS server (in NFS version 4 the path is relative to the served NFS root directory), and /backups is the mount point on the client machine

Installing NVIDIA Drivers

Follow the instructions from Ubuntu to install device drivers for NVIDIA graphics cards and configure for your system. There are also instructions for manually installing a driver downloaded from NVIDIA, which is not recommended.

Alternative packages with newer drivers are available via Launchpad after adding the graphics-drivers repository by typing

sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update


If your monitor cable (HDMI, DisplayPort, etc.) is connected to the output of the integrated graphics solution of your computer (e.g., Intel Skylake Graphics) you should shut down your computer and your monitor, unplug the monitor cable from the integrated graphics port and plug it into one of the ports of the NVIDIA card. Restart your computer, boot into the BIOS utility provided by your motherboard and check that Secure Boot is disabled, otherwise it will prevent kernel modules from being loaded.

Make sure nvidia-prime is installed and use it to select the NVIDIA card as the prime graphics output:

sudo apt install nvidia-prime
sudo prime-select nvidia

This modifies /etc/ld.so.conf.d/x86_64-linux-gnu_GL.conf and /etc/ld.so.conf.d/x86_64-linux-gnu_EGL.conf to use the latest installed nvidia driver. To check the status of the graphics card and the driver assigned to it you can enter

inxi -G

The output should look like this:

Graphics:  Card: NVIDIA Device 1b81
           Display Server: X.Org 1.18.4 drivers: nvidia (unloaded: fbdev,vesa,nouveau)
           Resolution: 3840x2160@60.00hz
           GLX Renderer: GeForce GTX 1070/PCIe/SSE2 GLX Version: 4.5.0 NVIDIA 370.28

Note that nvidia is the selected driver in the line that starts with Display Server:.

You may have to add the string nomodeset to the line that starts with GRUB_CMDLINE_LINUX_DEFAULT= in the file /etc/default/grub. For example,

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nomodeset"

where quiet and splash were the default options on my system. Be sure to run

sudo update-grub

so that the change to /etc/default/grub has an effect on /boot/grub/grub.cfg. Beware, however, that adding nomodeset will also prevent your display mode from being detected and set automatically if anything should go wrong. Finally, if your boot disk contains multiple bootable Linux system partitions, make sure that the bootloader that you just updated is the one installed in the Master Boot Record (MBR). You can install a Grub bootloader in the MBR via

$ sudo grub-install --boot-directory=/boot /dev/sda
$ sudo update-grub 

where /dev/sda is an example and needs to be replaced with your specific boot disk device file.

Other useful commands to check the device status are:

ubuntu-drivers devices

for showing a list of packages from the Ubuntu repository that are drivers for the installed hardware,

sudo lshw -c display

for showing information about installed hardware in the display category,

lspci -nnk | grep -iA3 vga

for showing information about graphics cards connected to the PCI bus, and

xrandr

for showing a list of possible display modes in which the connected screen can operate.


Debug data: