How to install OpenBSD on a Raspberry Pi 4

Published by mr.pigeon on

How to install OpenBSD on a Raspberry Pi 4

OpenBSD on Raspberry Pi

Introduction

OpenBSD is a free, open-source, multi-platform BSD based UNIX-like operating system. OpenBSD integrates cutting edge security technology suitable for building firewalls and private network services in a distributed environment. The OpenBSD team makes a new release approximately every six months, with the target release dates in May and November.

OpenBSD attempts to minimize the need for customization and tweaking. For the vast majority of users, OpenBSD just works on their hardware for their application. The targeted version of OpenBSD used in this guide is OpenBSD/arm64 which has a port for a Raspberry Pi 4 (Broadcom BCM2711).

In this tutorial we will guide you through the necessary steps needed to successfully download, boot, configure networking, configure timezone, and install basic packages to get started.

To complete this guide you will need the following parts or similar:

  • Micro-SD Card (8GB minimum): To store the UEFI firmware for Raspberry Pi 4
  • Micro-SD to USB (16GB minimum): Will be used to install OpenBSD operating system
  • Raspberry Pi 4 (1/2/4/8gb)
  • Serial Console: USB TTY - Silicon Labs CP210x UART

Step 1: Download

UEFI firmware for Raspberry Pi 4

We are going to use our first micro-sd card only to store the experimental EDK2 UEFI firmware. With the help of that firmware, we will be able to boot from a USB device later on and install OpenBSD operating system.

For Raspberry Pi 4, we can find the latest build of the UEFI firmware on GitHub. Download RPi4_UEFI_Firmware*.zip file and extract it to a temporary folder, we will copy it's content later to our formatted micro-sd card.

mkdir tmp && cd tmp
wget https://github.com/pftf/RPi4/releases/download/v1.16/RPi4_UEFI_Firmware_v1.16.zip
unzip RPi4_UEFI_Firmware*.zip

The only thing we need to make sure at this point is that our first micro-sd card has one partition on it, and it is formatted as either FAT16 or FAT32. So lets first take that thing away.

Assuming you are preparing your micro-sd card from a linux machine, insert your micro-sd card to a USB adapter, and connect it to your computer. Locate your device in dmesg, and prepare a single partition formatted as FAT16 or FAT32.

Assuming your micro-sd card device was detected as /dev/sdd

sudo parted --script /dev/sdd 
  mklabel msdos 
  mkpart primary fat32 1MiB 100% 
  set 1 boot on

Now will be a good time to can copy the UEFI files saved to a temporary directory from earlier. Just copy the content of the extracted zip file to the root of the micro-sd card. When finished, remove that micro-sd card and plug it to the Raspberry Pi's SD slot, and connect the second micro-sd card to your computer so you can copy the OpenBSD install files on it.

OpenBSD Files

Download the OpenBSD/arm64 port miniroot67.fs which is the install image, and a signature check file SHA256.sig that will be used to run a check for file corruption.

cd tmp
wget https://cdn.openbsd.org/pub/OpenBSD/6.7/arm64/miniroot67.fs
wget https://cdn.openbsd.org/pub/OpenBSD/6.7/arm64/SHA256.sig

Check the downloaded miniroot*.fs image file

sha256 -C SHA256 miniroot*.fs

A passing result would show this:

(SHA256) minirootXX.fs: OK

Copy the OpenBSD installer image to our micro-sd card

sudo dd if=~/tmp/miniroot67.fs of=/dev/sdd bs=1M status=progress

Step 2: Boot

USB TTY to Raspberry Pi's GPIO

On our first boot, we will need to interact with our Raspberry Pi 4 via serial console by connecting to the Pi's GPIO pins. Our serial console in this case is the USB to TTY cable made by Silicon Labs, CP2102 USB to UART Bridge Controller. It's RX goes to the Pi's TX on pin, and its' TX goes to the Pi's RX, last pin that we need to connect is the GND's. Using the pinout RX1/TX1 worked just fine for me.

To see the Raspberry Pi's console output we can use the cu tool. If you don't have that specific tool, you can either look it up for your linux distribution, or use some other tools such as screen, minicom, putty, tip, and so on.

For example, to look up for the correct tty device attached to your system you can run:

$ dmesg | egrep --color 'ttyUSB'
cp210x ttyUSB0: usb_serial_generic_read_bulk_callback - urb stopped: -32

Attach to the session:

sudo cu -l /dev/ttyUSB0 -s 115200
  • -l : specify the serial console device.
  • -s : specify the connection speed.

Change Boot Order

The first thing you will see when booting the Pi, is it's hardware initialization and after that, the pi will read boot files from the internal micro-sd card, which will show us this prompt:

Esc (setup), F1 (shell), ENTER (boot).....

Hit the Esc button to enter the UEFI menu, and change default boot order. We want to configure our Raspberry Pi to boot from the second micro-SD card connected via USB. To do so, navigate to Boot Manager and make sure that UEFI Generic Mass Storage Device is first in order to boot from. See Figure 2.

figure1-UEFI-menu

Figure 1: UEFI Firmware Menu

figure2-UEFI-Boot-Manager

Figure 2: UEFI Boot Manager

Install OpenBSD

When booting from our second micro-sd, you will be greeted with the guided command-line installation of OpenBSD to the micro-sd card itself.

Welcome to the OpenBSD/arm64 6.7 installation program.
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell? I

Hit the I button, to proceed with the installation. It should be self explanatory, here is the install backlog you can reference to.

install backlog: click to expand

```bash
pigeon at arch-pi in ~
â sudo cu -l /dev/ttyUSB0 -s 115200
[sudo] password for pigeon:
Connected.
erase ^?, werase ^W, kill ^U, intr ^C, status ^T

Welcome to the OpenBSD/arm64 6.7 installation program.
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell? I
At any prompt except password prompts you can escape to a shell by
typing '!'. Default answers are shown in []'s and are selected by
pressing RETURN. You can exit this program at any time by pressing
Control-C, but this can leave your system in an inconsistent state.

Terminal type? [vt220]
System hostname? (short form, e.g. 'foo') openbsd-pi4

Available network interfaces are: bse0 vlan0.
Which network interface do you wish to configure? (or 'done') [bse0]
IPv4 address for bse0? (or 'dhcp' or 'none') [dhcp]
bse0: no link....
bse0: 192.168.1.103 lease accepted from 192.168.1.1 (xx:xx:xx:xx:83:92)
IPv6 address for bse0? (or 'autoconf' or 'none') [none]
Available network interfaces are: bse0 vlan0.
Which network interface do you wish to configure? (or 'done') [done]
Using DNS domainname Home
Using DNS nameservers at 192.168.1.1 0.0.0.0

Password for root account? (will not echo)
Password for root account? (again)
Start sshd(8) by default? [yes]
Setup a user? (enter a lower-case loginname, or 'no') [no] pigeon
Full name for user batman? [batman]
Password for user batman? (will not echo)
Password for user batman? (again)
WARNING: root is targeted by password guessing attacks, pubkeys are safer.
Allow root ssh login? (yes, no, prohibit-password) [no] no
What timezone are you in? ('?' for list) [America/Detroit]

Available disks are: sd0.
Which disk is the root disk? ('?' for details) [sd0] ?
sd0: Kingston, DataTraveler 3.0 serial.09511666F260C96B37DC (57.6G)
Available disks are: sd0.
Which disk is the root disk? ('?' for details) [sd0]
Disk: sd0 geometry: 7522/255/63 [120845300 Sectors]
Offset: 0 Signature: 0xAA55
Starting Ending LBA Info:
#: id C H S - C H S [ start: size ]
-------------------------------------------------------------------------------
*0: 0C 2 10 9 - 2 140 10 [ 32768: 8192 ] FAT32L
1: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused
2: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused
3: A6 2 140 11 - 4 52 48 [ 40960: 26624 ] OpenBSD
Use (W)hole disk or (E)dit the MBR? [whole]
Creating a msdos partition and an OpenBSD partition for rest of sd0...done.
/dev/rsd0i: 32668 sectors in 8167 FAT16 clusters (2048 bytes/cluster)
bps=512 spc=4 res=1 nft=2 rde=512 mid=0xf8 spf=32 spt=63 hds=255 hid=32768 bsec=32768
The auto-allocated layout for sd0 is:
# size offset fstype [fsize bsize cpg]
a: 1024.0M 65536 4.2BSD 2048 16384 1 # /
b: 3187.1M 2162688 swap
c: 59006.5M 0 unused
d: 3975.4M 8689952 4.2BSD 2048 16384 1 # /tmp
e: 6345.0M 16831552 4.2BSD 2048 16384 1 # /var
f: 6144.0M 29826144 4.2BSD 2048 16384 1 # /usr
g: 1024.0M 42409056 4.2BSD 2048 16384 1 # /usr/X11R6
h: 8252.9M 44506208 4.2BSD 2048 16384 1 # /usr/local
i: 16.0M 32768 MSDOS
j: 2048.0M 61408064 4.2BSD 2048 16384 1 # /usr/src
k: 6144.0M 65602368 4.2BSD 2048 16384 1 # /usr/obj
l: 20830.1M 78185280 4.2BSD 2048 16384 1 # /home
Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout? [a] A
/dev/rsd0a: 1024.0MB in 2097152 sectors of 512 bytes
6 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0l: 20830.1MB in 42660000 sectors of 512 bytes
103 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0d: 3975.4MB in 8141600 sectors of 512 bytes
20 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0f: 6144.0MB in 12582912 sectors of 512 bytes
31 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0g: 1024.0MB in 2097152 sectors of 512 bytes
6 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0h: 8252.9MB in 16901856 sectors of 512 bytes
41 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0k: 6144.0MB in 12582912 sectors of 512 bytes
31 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0j: 2048.0MB in 4194304 sectors of 512 bytes
11 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd0e: 6345.0MB in 12994592 sectors of 512 bytes
32 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/sd0a (33aaa1c1ee2ad147.a) on /mnt type ffs (rw, asynchronous, local)
/dev/sd0l (33aaa1c1ee2ad147.l) on /mnt/home type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd0d (33aaa1c1ee2ad147.d) on /mnt/tmp type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd0f (33aaa1c1ee2ad147.f) on /mnt/usr type ffs (rw, asynchronous, local, nodev)
/dev/sd0g (33aaa1c1ee2ad147.g) on /mnt/usr/X11R6 type ffs (rw, asynchronous, local, nodev)
/dev/sd0h (33aaa1c1ee2ad147.h) on /mnt/usr/local type ffs (rw, asynchronous, local, nodev)
/dev/sd0k (33aaa1c1ee2ad147.k) on /mnt/usr/obj type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd0j (33aaa1c1ee2ad147.j) on /mnt/usr/src type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd0e (33aaa1c1ee2ad147.e) on /mnt/var type ffs (rw, asynchronous, local, nodev, nosuid)

Let's install the sets!
Location of sets? (disk http nfs or 'done') [http]
HTTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]
HTTP Server? (hostname, list#, 'done' or '?') [list] ftp.eu.openbsd.org
Server directory? [pub/OpenBSD/6.7/arm64]

Select sets by entering a set name, a file name pattern or 'all'. De-select
sets by prepending a '-', e.g.: '-game*'. Selected sets are labelled '[X]'.
[X] bsd [X] base67.tgz [X] game67.tgz [X] xfont67.tgz
[X] bsd.mp [X] comp67.tgz [X] xbase67.tgz [X] xserv67.tgz
[X] bsd.rd [X] man67.tgz [X] xshare67.tgz
Set name(s)? (or 'abort' or 'done') [done] all
[X] bsd [X] base67.tgz [X] game67.tgz [X] xfont67.tgz
[X] bsd.mp [X] comp67.tgz [X] xbase67.tgz [X] xserv67.tgz
[X] bsd.rd [X] man67.tgz [X] xshare67.tgz
Set name(s)? (or 'abort' or 'done') [done] base67
[X] bsd [X] base67.tgz [X] game67.tgz [X] xfont67.tgz
[X] bsd.mp [X] comp67.tgz [X] xbase67.tgz [X] xserv67.tgz
[X] bsd.rd [X] man67.tgz [X] xshare67.tgz
Set name(s)? (or 'abort' or 'done') [done] base67.tgz
[X] bsd [X] base67.tgz [X] game67.tgz [X] xfont67.tgz
[X] bsd.mp [X] comp67.tgz [X] xbase67.tgz [X] xserv67.tgz
[X] bsd.rd [X] man67.tgz [X] xshare67.tgz
Set name(s)? (or 'abort' or 'done') [done]
Get/Verify SHA256.sig 100% |**************************| 1453 00:00
Signature Verified
Get/Verify bsd 100% |**************************| 11656 KB 01:00
Get/Verify bsd.mp 100% |**************************| 11725 KB 01:08
Get/Verify bsd.rd 100% |**************************| 12563 KB 01:36
Get/Verify base67.tgz 100% |**************************| 187 MB 13:51
Get/Verify comp67.tgz 100% |**************************| 53636 KB 03:38
Get/Verify man67.tgz 100% |**************************| 7465 KB 00:37
Get/Verify game67.tgz 100% |**************************| 2730 KB 00:16
Get/Verify xbase67.tgz 100% |**************************| 19417 KB 01:13
Get/Verify xshare67.tgz 100% |**************************| 4500 KB 00:17
Get/Verify xfont67.tgz 100% |**************************| 39345 KB 03:07
Get/Verify xserv67.tgz 100% |**************************| 11344 KB 01:05
Installing bsd 100% |**************************| 11656 KB 00:00
Installing bsd.mp 100% |**************************| 11725 KB 00:01
Installing bsd.rd 100% |**************************| 12563 KB 00:01
Installing base67.tgz 100% |**************************| 187 MB 02:27
Extracting etc.tgz 100% |**************************| 262 KB 00:28
Installing comp67.tgz 100% |**************************| 53636 KB 01:07
Installing man67.tgz 100% |**************************| 7465 KB 00:28
Installing game67.tgz 100% |**************************| 2730 KB 00:00
Installing xbase67.tgz 100% |**************************| 19417 KB 00:59
Extracting xetc.tgz 100% |**************************| 7020 00:00
Installing xshare67.tgz 100% |**************************| 4500 KB 00:17
Installing xfont67.tgz 100% |**************************| 39345 KB 00:36
Installing xserv67.tgz 100% |**************************| 11344 KB 00:07
Location of sets? (disk http nfs or 'done') [done]
Time appears wrong. Set to 'Fri Jul 3 02:15:55 IDT 2020'? [yes]
Saving configuration files... done.
Making all device nodes... done.
Multiprocessor machine; using bsd.mp instead of bsd.
Relinking to create unique kernel... done.

CONGRATULATIONS! Your OpenBSD install has been successfully completed!

When you login to your new system the first time, please read your mail
using the 'mail' command.

Exit to (S)hell, (H)alt or (R)eboot? [reboot]

```

After install is complete, reboot the system, and run syspatch to apply security updates for your base system.

su -
syspatch

Step 3: Networking

Assuming this Raspberry Pi would act as a server for some kind of a service, it would be wise to configure it with a Static IP address. Do do so, we would need to edit the file /etc/hostname.bse0. Remove the dhcp line and replace it with inet ip subnet NONE

# su -
# vi /etc/hostname.bse0
inet 192.168.1.10 255.255.255.0 NONE

Next thing we need is our gateway. Create a file called /etc/mygate and add the IP of your gateway to this file.

#su -
#vi /etc/mygate
192.168.1.1

In case you have resolving issues, you can check /etc/resolve.conf.

# su -
# vi /etc/resolv.conf
search Home
nameserver 192.168.1.1
nameserver 8.8.8.8
nameserver 8.8.4.4
lookup file bind

Make sure you restart the networking service when you done editing the files above for the changes to take effect.

su -
sh /etc/netstart

Step 4: Install Packages

The traditional way is to use OpenBSD packages over building an application from ports. To install a package simply run:

su -
pkg_add -v -i package_name

Here are some packages I like to have on my setups:

  • vim
  • git
  • zsh
  • htop
  • neofetch
  • curl
  • wget

For more advanced users, using the ports method would be a better choice as there are many 3rd party packages that couldn't be installed by the traditional way.

pfetch-OpenBSD-Pi4

What's Next

X: Graphical User Interface
LAMP

Conclusion

In this guide you have learned how to change the boot order on the Raspberry Pi 4 in order to boot from usb using a custom UEFI firmware prepared on a separate micro sd card. We also successfully attached to the Raspberry Pi's GPIO pins to get an interactive console using a USB to TTY device, install the OpenBSD operating system, and installed some basic packages.

Read More

Raspberry Pi
OpenBSD ARM
OpenBSD Handbook


15 Comments

Avatar

Doug Moss · August 2, 2020 at 4:37 pm

I must have missed something.
I can get to the serial console, with my CP2102.
I put the UEFI from github pftf on to a microSD in the onboard (bottom) slot, and it boots to the UEFI screen.
From a USB port, I have connected the miniroot67.fs I wrote (with dd) to another microSD.

Where are the OpenBSD files (bsd,bsd.mp,bsd.mp,base67.tgz,comp67.tgz,and so on) ?
Are they supposed to be on the microSD with the UEFI, or on the USB card with the miniroot? (in which case, how do you do that, since you use dd to write the miniroot67.fs ?)
or on some other device?

    mr.pigeon

    mr.pigeon · August 5, 2020 at 8:36 pm

    Hey Doug,
    The OpenBSD files, and the UEFI files should be on separate microSD cards.
    Regarding OpenBSD, you only need the file `miniroot67.fs`. This is the mini image containing a bootable guided installer.

    You actually booting from the microSD card that have the UEFI firmware which gives you the option to boot from another USB device, in our case a microSD card containing the OpenBSD installer. This device will be used to install the system on to.

      Avatar

      Rafael · August 6, 2020 at 4:30 pm

      So during the OpenBSD install, do you select the UEFI firmware SD card as the disk to install on? I guess we only need the UEFI firmware once to change the boot order, and then it can be overwritten with the OpenBSD installation. Am I correct?

        mr.pigeon

        mr.pigeon · August 7, 2020 at 1:12 pm

        Hey Rafael,
        No, I used the installation microSD card as the target to install to and kept the UEFI microSD as is.
        OpenBSD on Raspberry Pi is only available via EDK2-based UEFI firmware. There is no SD/MMC driver yet.

Avatar

David · August 28, 2020 at 9:18 am

this is a very interesting guide, thanks!
How ever there are some things i dont understand. I do get that i need the EDK2 firmware from the pftf project to be able to boot non-standard(i.e no rpi specific kernel/boot patches) arm64 operating systems. But i cant see a reason to use a second sd card (via usb?!?)? Why not use a fast USB stick as the installation medium? Am i getting something wrong?

    mr.pigeon

    mr.pigeon · September 4, 2020 at 2:01 pm

    Hey David,
    You’re welcome 😉

    Regarding your question, OpenBSD do not have SD/MMC driver for Raspberry Pi 4, therefore, we’re using the UEFI firmware to be able to boot from USB, and that gives us the option to install OpenBSD. Also, you could use any other medium that share USB port.

Avatar

Peracchi · September 18, 2020 at 1:53 am

Beforehand, thank you very much for this post!

Few days after you publish it, I followed all instructions with sucess.

Today I do it another time and get:

disks: sd0* sd1
>> OpenBSD/arm64 BOOTAA64 0.22
boot>
cannot open sd0a:/etc/random.seed: No such file or directory
booting sd0a:/bsd: 2305548+642928+8780112+741800 [184838+109+543888+209641]=0xff
a0b0
FACP CSRT DBG2 GTDT APIC PPTT BGRT

I do it again twice, same result…

Only thing I got newer is RPi4_UEFI_Firmware_v1.20…

What do you think is the problem?

Avatar

Peracchi · September 19, 2020 at 3:50 pm

Hi!
First time I followed your guide everything worked.
Now, I only get:

disks: sd0* sd1
>> OpenBSD/arm64 BOOTAA64 0.22
boot>
cannot open sd0a:/etc/random.seed: No such file or directory
booting sd0a:/bsd: 2305548+642928+8780112+741800 [184838+109+543888+209641]=0xff
a0b0
FACP CSRT DBG2 GTDT APIC PPTT BGRT

Do you know what could be the problem?

    Avatar

    no name · September 21, 2020 at 2:49 pm

    try current miniroot.img

Avatar

Bernhard Ernst · October 2, 2020 at 1:57 pm

Hi there,
tried OpenBSD with my raspi 4 with 8 GB and version 1.4 and have the same result as Peracci. Even the miniroot image does not help. No chance yet to run OpenBSD on my raspi – so sad. 🙂
Berni

Avatar

Vasileios Prevelakis · October 10, 2020 at 1:16 am

Hi,

I am getting the same failure. I tried with the older EFI firmware (RPi4_UEFI_Firmware_v1.16.zip) and the latest (RPi4_UEFI_Firmware_v1.20.zip) and got the same behavior.

I then tried the snapshot 6.8 miniroot. This did not even start the BSD boot loader.

I finally tried the 6.7 miniroot with the 6.8 kernel and this time I got the following:

>> OpenBSD/arm64 BOOTAA64 0.22
boot>
cannot open sd0a:/etc/random.seed: No such file or directory
booting sd0a:/bsd: 3818189+1582080+3882232+0+757760=0x995360
FACP CSRT DBG2 GTDT APIC PPTT BGRT

>> OpenBSD/arm64 BOOTAA64 0.22
boot>
cannot open sd0a:/etc/random.seed: No such file or directory
booting sd0a:/bsd: 3818189+1582080+3882232+0+757760=0x995360
FACP CSRT DBG2 GTDT APIC PPTT BGRT

Synchronous Exception at 0x0000007F81201000

———–

The ” “Synchronous Exception” line appeared only on the serial console.

    mr.pigeon

    mr.pigeon · October 10, 2020 at 4:04 am

    Hey Vasileios,
    This tutorial is based on Raspberry Pi 4 (4gb model), what model do you have?

Avatar

Bernhard Ernst · October 13, 2020 at 4:07 pm

Today I started a new trial to install OpenBSD onto my Raspberry 4 (8GB) according to Mr. Pigeons above description. And it works!!!
As mostly the problem was not my Raspberry nor this description – the problem was sitting in front of the computer 🙁
My mistake simply was to disconnect the USB-uart adaptor after setting the raspis boot device to USB. But today I read the description again and seriously and now I understood that the complete Installation has to be done over the serial connection.
OK, I installed OpenBSD 6.7 onto the USB SD card and the system boots and runs the BSD fine. The only disadvantage is, that I have only access to the Raspberry via the serial port or ssh., as there is no output over HDMI on my monitor.
Any idea how to get output on the screen?
Thank to Mr. Pigeon and sorry for my silly mistake.
Berni

    mr.pigeon

    mr.pigeon · October 14, 2020 at 7:08 am

    I am glad to hear to you succeeded 😉 And yes, you should’ve proceed with the installation via UART 🙂
    Regarding your output issue, well I see two options for you.
    1. Get a physical adaptor to match the outputs you have on your monitor.
    2. If you want a graphical environment on your openbsd, you could install one, and connect to it via VNC.

Avatar

Bernhard Ernst · October 14, 2020 at 9:14 am

Thanks for your hints. I will try both options.
As a workaround it is possible to enter “set tty fb0” at the OpenBSD boot prompt. Now the complete output goes via HDMI and you see everthing on your monitor. No problem to install xorg now, what I have already done.
This is not so elegant because you have to enter this on every boot of the machine.

Leave a Reply

Your email address will not be published. Required fields are marked *