CU-dgpgu9 Added markdownlint and fixed markdown
This commit is contained in:
16
.drone.yml
16
.drone.yml
@@ -3,11 +3,25 @@ kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: lint
|
||||
image: peterdavehello/markdownlint
|
||||
commands:
|
||||
- markdownlint content/
|
||||
trigger:
|
||||
event:
|
||||
exclude:
|
||||
- promote
|
||||
|
||||
- name: build
|
||||
image: bdebyl/hugo
|
||||
commands:
|
||||
- git clone https://github.com/bdebyl/hugo-theme-even.git themes/even
|
||||
- hugo
|
||||
when:
|
||||
event:
|
||||
- promote
|
||||
target:
|
||||
- production
|
||||
|
||||
- name: deploy
|
||||
image: bdebyl/awscli
|
||||
@@ -29,6 +43,6 @@ steps:
|
||||
- production
|
||||
---
|
||||
kind: signature
|
||||
hmac: 3109d79e76507ab2e9a820522c68b429007ca6f25e0ca16b1b46ed0aba66d23e
|
||||
hmac: 7f15ec618d95cce36ecf999e018b38c056d52538fd6b5c81bdf5c6ce46e0fd21
|
||||
|
||||
...
|
||||
|
||||
8
.markdownlint.json
Normal file
8
.markdownlint.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD025": false,
|
||||
"MD013": false,
|
||||
"MD033": {
|
||||
"allowed_elements": ["center", "sub", "i"]
|
||||
}
|
||||
}
|
||||
62
config.yaml
62
config.yaml
@@ -1,31 +1,45 @@
|
||||
# core
|
||||
baseURL: "https://bdebyl.net/"
|
||||
title: "A random assortment of my personal projects."
|
||||
title: "Collection of useful, and useless information"
|
||||
theme: "even"
|
||||
|
||||
# settings
|
||||
paginate: 5
|
||||
defaultContentLanguage: "en"
|
||||
languageCode: "en"
|
||||
paginate: 5
|
||||
copyright: "Bastian de Byl" # default: author.name
|
||||
preserveTaxonomyNames: true
|
||||
enableRobotsTXT: true
|
||||
buildDrafts: false
|
||||
canonifyURLs: true
|
||||
enableRobotsTXT: true
|
||||
preserveTaxonomyNames: true
|
||||
markup:
|
||||
goldmark:
|
||||
renderer:
|
||||
unsafe: true
|
||||
|
||||
googleVerification: "" # Google Verification
|
||||
googleAnalytics: "UA-163975086-1" # UA-XXXXXXXX-X
|
||||
# google analytics
|
||||
googleAnalytics: "UA-163975086-1"
|
||||
googleVerification: ""
|
||||
|
||||
# See https://gohugo.io/about/hugo-and-gdpr/
|
||||
privacy:
|
||||
googleAnalytics:
|
||||
anonymizeIP: true
|
||||
youtube:
|
||||
privacyEnhanced: true
|
||||
|
||||
# https://gohugo.io/content-management/syntax-highlighting/
|
||||
pygmentsOptions: ""
|
||||
pygmentsCodefences: true
|
||||
pygmentsUseClasses: true
|
||||
pygmentsCodefencesGuessSyntax: true
|
||||
pygmentsOptions: ""
|
||||
pygmentsUseClasses: true
|
||||
|
||||
author:
|
||||
name: "Bastian de Byl"
|
||||
|
||||
sitemap:
|
||||
changefreq: "weekly"
|
||||
priority: 0.5
|
||||
filename: "sitemap.xml"
|
||||
priority: 0.5
|
||||
|
||||
menu:
|
||||
main:
|
||||
@@ -56,16 +70,12 @@ params:
|
||||
|
||||
# paginate of archives, tags and categories
|
||||
archivePaginate: 20
|
||||
|
||||
# show 'xx Posts In Total' in archive page ?
|
||||
showArchiveCount: true
|
||||
|
||||
# The date format to use; for a list of valid formats, see https://gohugo.io/functions/format/
|
||||
dateFormatToUse: "2006-01-02"
|
||||
|
||||
# show word count and read time ?
|
||||
moreMeta: false
|
||||
|
||||
postMetaInFooter: true # contain author, lastMod, markdown link, license
|
||||
linkToMarkDown: true # Only effective when hugo will output .md files.
|
||||
contentCopyright: '<a rel="license" href="http://creativecommons.org/licenses/by-nc/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc/4.0/80x15.png" /></a>'
|
||||
@@ -75,27 +85,3 @@ params:
|
||||
g-github: "https://github.com/bdebyl"
|
||||
m-instagram: "https://instagram.com/bastian.remi"
|
||||
n-gitlab: "https://gitlab.com/bdebyl"
|
||||
|
||||
# See https://gohugo.io/about/hugo-and-gdpr/
|
||||
privacy:
|
||||
googleAnalytics:
|
||||
anonymizeIP: true
|
||||
youtube:
|
||||
privacyEnhanced: true
|
||||
|
||||
# Uncomment these options to make hugo output .md files.
|
||||
#[mediaTypes]
|
||||
# [mediaTypes."text/plain"]
|
||||
# suffixes: ["md"]
|
||||
#
|
||||
#[outputFormats.MarkDown]
|
||||
# mediaType: "text/plain"
|
||||
# isPlainText: true
|
||||
# isHTML: false
|
||||
#
|
||||
#[outputs]
|
||||
# home: ["HTML", "RSS"]
|
||||
# page: ["HTML", "MarkDown"]
|
||||
# section: ["HTML", "RSS"]
|
||||
# taxonomy: ["HTML", "RSS"]
|
||||
# taxonomyTerm: ["HTML"]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
title: "About"
|
||||
---
|
||||
# About
|
||||
|
||||
I created this site as a way of showcasing my projects, or other general
|
||||
ideas. It's a sort of _engineering_ portfolio, if you will.
|
||||
|
||||
@@ -17,10 +18,12 @@ Git repositories[^1], or ways to contact me such as
|
||||
[email](mailto:bastian@bdebyl.net).
|
||||
|
||||
# GPG Fingerprint
|
||||
|
||||
The image at the **top-left** of this site (_on desktop_) is my OpenPGP v4 key
|
||||
fingerprint QR-code. Feel free to scan it using the
|
||||
[OpenKeychain](https://www.openkeychain.org/) app! I'll provide it here in-case
|
||||
you are on a mobile device, and my full public key:
|
||||
|
||||
<center>
|
||||

|
||||
|
||||
@@ -28,7 +31,8 @@ you are on a mobile device, and my full public key:
|
||||
</center>
|
||||
|
||||
{{< admonition info "Public Key" true >}}
|
||||
```
|
||||
|
||||
```text
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
mQINBFoTpoMBEADDIjRewOTvJBQF4ZxK/LS7yBL0TuU7VbZzEH3s5YKj63P/Rmvx
|
||||
8/jMm0iop+uiPNo+0imIGYsdfW77bt95I9+kBm27eVf8mDMldMiS/LBCCmnuQ19u
|
||||
@@ -146,11 +150,12 @@ teulWQZ/WMzUvU9IR6q3RcYbHm3yzbXVGzHXeLGUDWjvbKsDezUmn2desfexh+U7
|
||||
KpNnEkXDMtMCsNkEMzM+3/BkuxLO52zYpDe5tV7Igx0=
|
||||
=N6h6
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
# Resume
|
||||
|
||||
I do not currently keep an up-to-date version of my resume. In the past, I have
|
||||
written up my resume using [LaTeX](https://www.latex-project.org/) as a PDF. I
|
||||
may explore other solutions such as simply keeping it on this website.. _we'll
|
||||
|
||||
@@ -17,28 +17,30 @@ setting for a specific lens.
|
||||
<!--more-->
|
||||
|
||||
# The Setup
|
||||
|
||||
I started out using a tripod, with the same ISO and exposure compensation using
|
||||
a [**Minolta 50mm f1/7**](https://en.wikipedia.org/wiki/Minolta_AF_50mm_f/1.7)
|
||||
lens. Starting at *f/1.7* I worked my way up at reasonable steps to *f/4.0*. My
|
||||
aim was to compare the differences. See the shots below. The target couch
|
||||
cushion was set up roughly a meter from the bottom center of the tripod.
|
||||
|
||||
|
||||
# Depth-of-Field
|
||||
There may be something to be said about maintaining the best DoF
|
||||
(*Depth-of-field*). However, using [PhotoPills DoF Calculator]
|
||||
(https://www.photopills.com/calculators/dof) proves just how **wild**, using a
|
||||
50mm lens, an aperture of *f/1.7* is. Shooting a target of *2 meters* results in
|
||||
a depth-of-field of **16 centimeters** -- that's a very narrow range! Bumping up
|
||||
the aperture value to *f/2.8* provides a much more reasonable *27 centimeters*,
|
||||
though still a bit narrow. Either way this allays any fears I had of losing out
|
||||
on that sweet, *sweet* [bokeh](https://en.wikipedia.org/wiki/Bokeh), though the
|
||||
photos themselves illustrate that not a significant amount of Depth-of-Field is
|
||||
lost at that target distance of 1 meter.
|
||||
|
||||
There may be something to be said about maintaining the best DoF
|
||||
(*Depth-of-field*). However, using [PhotoPills DoF Calculator](https://www.photopills.com/calculators/dof)
|
||||
proves just how **wild**, using a 50mm lens, an aperture of *f/1.7* is.
|
||||
Shooting a target of *2 meters* results in a depth-of-field of **16
|
||||
centimeters** -- that's a very narrow range! Bumping up the aperture value to
|
||||
*f/2.8* provides a much more reasonable *27 centimeters*, though still a bit
|
||||
narrow. Either way this allays any fears I had of losing out on that sweet,
|
||||
*sweet* [bokeh](https://en.wikipedia.org/wiki/Bokeh), though the photos
|
||||
themselves illustrate that not a significant amount of Depth-of-Field is lost
|
||||
at that target distance of 1 meter.
|
||||
|
||||
# Comparison
|
||||
|
||||
## *f/1.7*--*f/4.0*
|
||||
|
||||
The biggest difference can be seen between the *f/1.7* and *f/4.0* shots. Note
|
||||
the increase in clarity on the pillows fabric.
|
||||
|
||||
@@ -49,6 +51,7 @@ the increase in clarity on the pillows fabric.
|
||||
---
|
||||
|
||||
## *f/1.7*--*f/2.8*
|
||||
|
||||
At *f/2.8* and above I started noticing less increase in perceived sharpness of
|
||||
the image, though the difference in comparison to *f/1.7* was still fairly
|
||||
noticeable
|
||||
@@ -60,6 +63,7 @@ noticeable
|
||||
---
|
||||
|
||||
## *f/2.8*--*f/4.0*
|
||||
|
||||
Aside from the perceived exposure difference from what is most likely a
|
||||
difference in shutter speed, the overall difference does not seem as dramatic
|
||||
from *f/2.8* to *f/4.0*. Personally, I'd say that *f/2.8* is the clear winner in
|
||||
@@ -72,6 +76,7 @@ finding the best middle-ground between maximum aperture and image quality.
|
||||
---
|
||||
|
||||
# Individual Photos
|
||||
|
||||
Below is the entire collection of all the photos taken of the subject at
|
||||
increasing aperture steps.
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ better understanding of the tools and methods used.
|
||||
---
|
||||
|
||||
# Partitioning
|
||||
|
||||
1. Create a partition scheme using partitioner of choice (e.g. `gdisk`, `fdisk`,
|
||||
`cgdisk`).
|
||||
- First partition should be EFI/boot partition at around 256MB+ (type:
|
||||
@@ -25,93 +26,116 @@ better understanding of the tools and methods used.
|
||||
1. Make the the EFI/boot partition FAT32 via `mkfs.fat -F32`
|
||||
|
||||
# Encryption
|
||||
|
||||
1. Format the Linux LVM partition:
|
||||
```
|
||||
# cryptsetup luksFormat /dev/sdaN
|
||||
|
||||
```bash
|
||||
cryptsetup luksFormat /dev/sdaN
|
||||
Enter passphrase:
|
||||
```
|
||||
|
||||
**Note:** _Remember your passphrase! You will need this every time you boot
|
||||
your computer_
|
||||
1. Create a mapping for your Linux LVM (LUKS):
|
||||
|
||||
```bash
|
||||
cryptsetup open --type luks /dev/sdaN <map_name>
|
||||
```
|
||||
# cryptsetup open --type luks /dev/sdaN <map_name>
|
||||
```
|
||||
|
||||
_Use whatever name you want. Ex. `lvm`, `volume`, etc._
|
||||
1. Create the physical volume, volume group, and logical volumes for
|
||||
`<map_name>` specified in the previous step:
|
||||
|
||||
```bash
|
||||
pvcreate /dev/mapper/<map_name>
|
||||
vgcreate <volume_name> /dev/mapper/<map_name>
|
||||
```
|
||||
# pvcreate /dev/mapper/<map_name>
|
||||
# vgcreate <volume_name> /dev/mapper/<map_name>
|
||||
```
|
||||
|
||||
_Use whatever volume name you want. Ex. `volume`, `main`, `linux`, etc._
|
||||
|
||||
```bash
|
||||
lvcreate -L2G <volume_name> -n swap
|
||||
```
|
||||
# lvcreate -L2G <volume_name> -n swap
|
||||
```
|
||||
|
||||
_Select size for swap, if desired. Here we use `2G` for 2Gb._
|
||||
|
||||
```bash
|
||||
lvcreate -L16G <volume_name> -n root
|
||||
lvcreate -l 100%FREE <volume_name> -n home
|
||||
```
|
||||
# lvcreate -L16G <volume_name> -n root
|
||||
# lvcreate -l 100%FREE <volume_name> -n home
|
||||
```
|
||||
|
||||
1. Specify and write the desired filesystems:
|
||||
```
|
||||
# mkfs.ext4 /dev/mapper/<volume_name>-root
|
||||
# mkfs.ext4 /dev/mapper/<volume_name>-home
|
||||
# mkswap /dev/mapper/<volume_name>-swap
|
||||
|
||||
```bash
|
||||
mkfs.ext4 /dev/mapper/<volume_name>-root
|
||||
mkfs.ext4 /dev/mapper/<volume_name>-home
|
||||
mkswap /dev/mapper/<volume_name>-swap
|
||||
```
|
||||
|
||||
# Install Linux
|
||||
|
||||
1. Mount the boot partition and logical volumes for installation:
|
||||
```
|
||||
# mount /dev/mapper/<volume_name>-root /mnt
|
||||
# mkdir /mnt/home
|
||||
# mkdir /mnt/boot
|
||||
# mount /dev/mapper/<volume_name>-home /mnt/home
|
||||
# mount /dev/sdaN /mnt/boot
|
||||
# swapon /dev/mapper/<volume_name>-swap
|
||||
|
||||
```bash
|
||||
mount /dev/mapper/<volume_name>-root /mnt
|
||||
mkdir /mnt/home
|
||||
mkdir /mnt/boot
|
||||
mount /dev/mapper/<volume_name>-home /mnt/home
|
||||
mount /dev/sdaN /mnt/boot
|
||||
swapon /dev/mapper/<volume_name>-swap
|
||||
```
|
||||
|
||||
1. Install the base system (_Assuming you have internet connectivity. Use
|
||||
`wifi-menu`, or other, to connect to the internet at this point._):
|
||||
```
|
||||
# pacstrap /mnt base base-devel
|
||||
|
||||
```bash
|
||||
pacstrap /mnt base base-devel
|
||||
```
|
||||
|
||||
# Set-up Linux Installation
|
||||
|
||||
1. Generate the `fstab`:
|
||||
```
|
||||
# genfstab -p /mnt >> /mnt/etc/fstab
|
||||
|
||||
```bash
|
||||
genfstab -p /mnt >> /mnt/etc/fstab
|
||||
```
|
||||
|
||||
1. Move into the installation:
|
||||
```
|
||||
# arch-chroot /mnt
|
||||
|
||||
```bash
|
||||
arch-chroot /mnt
|
||||
```
|
||||
|
||||
1. Configure `initramfs`:
|
||||
1. Edit `HOOKS` in `/etc/mkinitcpio.conf` using text editor of your choice
|
||||
(e.g. `vi`, `nano`, etc.). Move the `keyboard` hook before `filesystems`,
|
||||
and add `encrypt` and `lvm2` hooks **before** `filesystems`:
|
||||
```
|
||||
# egrep '^HOOKS' /etc/mkinitcpio.conf
|
||||
|
||||
```bash
|
||||
$ egrep '^HOOKS' /etc/mkinitcpio.conf
|
||||
HOOKS=(base udev autodetect modconf block keyboard encrypt lvm2 filesystems fsck)
|
||||
```
|
||||
|
||||
_Read the comment documentation on `HOOKS` in the document to find out
|
||||
more._
|
||||
|
||||
1. Generate `initramfs`:
|
||||
```
|
||||
# mkinitcpio -p linux
|
||||
|
||||
```bash
|
||||
mkinitcpio -p linux
|
||||
```
|
||||
|
||||
1. Install a bootloader (e.g. `systemd-boot`, `grub`, `syslinux`, etc.):
|
||||
1. I will be using `systemd-boot`
|
||||
```
|
||||
# bootctl --path=/boot/ install
|
||||
|
||||
```bash
|
||||
bootctl --path=/boot/ install
|
||||
```
|
||||
|
||||
1. Edit the loader configuration using a text editor of your choice:
|
||||
```apacheconf
|
||||
# cat /boot/loader/loader.conf
|
||||
|
||||
```bash
|
||||
$ cat /boot/loader/loader.conf
|
||||
default arch
|
||||
timeout 3
|
||||
editor 0
|
||||
@@ -121,8 +145,9 @@ better understanding of the tools and methods used.
|
||||
can edit this name if desired._). Use `blkid /dev/sdaN` to find the UUID
|
||||
of your crypt device, and recall the volume name you gave your device
|
||||
above (_`main` in example below_):
|
||||
```apacheconf
|
||||
# cat /boot/loader/entries/arch.conf
|
||||
|
||||
```bash
|
||||
$ cat /boot/loader/entries/arch.conf
|
||||
title Arch Linux
|
||||
linux /vmlinuz-linux.img
|
||||
initrd /initramfs-linux.img
|
||||
@@ -131,26 +156,30 @@ better understanding of the tools and methods used.
|
||||
|
||||
1. Create a root password using `passwd`.
|
||||
1. Set a hostname:
|
||||
```
|
||||
# echo "<your_hostname>" > /etc/hostname
|
||||
|
||||
```bash
|
||||
echo "<your_hostname>" > /etc/hostname
|
||||
```
|
||||
|
||||
1. Set up the time:
|
||||
```
|
||||
# ln -fs /usr/share/zoneinfo/<continent>/<city/place> /etc/localtime
|
||||
# hwclock --systohc --utc
|
||||
|
||||
```bash
|
||||
ln -fs /usr/share/zoneinfo/<continent>/<city/place> /etc/localtime
|
||||
hwclock --systohc --utc
|
||||
```
|
||||
|
||||
1. Set the locale to `en_US`:
|
||||
```
|
||||
# sed -i 's/^\#en_US/en_US/' /etc/locale.gen
|
||||
# locale-gen
|
||||
# locale > /etc/locale.conf
|
||||
|
||||
```bash
|
||||
sed -i 's/^\#en_US/en_US/' /etc/locale.gen
|
||||
locale-gen
|
||||
locale > /etc/locale.conf
|
||||
```
|
||||
|
||||
1. Done!
|
||||
```
|
||||
# exit
|
||||
# unmount -R /mnt
|
||||
# reboot
|
||||
|
||||
```bash
|
||||
exit
|
||||
unmount -R /mnt
|
||||
reboot
|
||||
```
|
||||
|
||||
@@ -20,6 +20,7 @@ Emacs workflow to include IntelliSense-like auto-completion!
|
||||
# Dependencies
|
||||
|
||||
## System
|
||||
|
||||
Assuming you're running Linux, you'll need to have the following packages
|
||||
installed:
|
||||
|
||||
@@ -29,21 +30,25 @@ installed:
|
||||
## Emacs
|
||||
|
||||
### ELPA
|
||||
|
||||
If you already have ELPA/MELPA, feel free to skip this first part
|
||||
|
||||
To be able to easily fetch the packages, it's highly recommended you use the
|
||||
**Emacs Lisp Package Archive** (ELPA). To do this, all that's required is to
|
||||
simply add the following to your `init.el`/`.emacs`[^1] file:
|
||||
|
||||
```lisp
|
||||
(require 'package)
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "https://melpa.org/packages/"))
|
||||
(package-initialize)
|
||||
```
|
||||
|
||||
<sub>Emacs will need to be restarted or reloaded to load the package
|
||||
repository.</sub>
|
||||
|
||||
### Packages
|
||||
|
||||
Install the following packages in Emacs (`M-x package-install`):
|
||||
|
||||
- `irony`
|
||||
@@ -51,14 +56,15 @@ Install the following packages in Emacs (`M-x package-install`):
|
||||
- `company-irony`
|
||||
- `company-irony-c-headers` <sub>(_Required if you want header auto-completion_)</sub>
|
||||
|
||||
|
||||
# Configuration
|
||||
|
||||
## Company
|
||||
|
||||
Company ([company-mode](http://company-mode.github.io/)) needs to be required,
|
||||
added to the `after-init-hook` (_or similar / manually called_), and the back ends
|
||||
to be added to it's list of usable back ends. This is done in the initialization
|
||||
file[^1]:
|
||||
|
||||
```lisp
|
||||
(require 'company)
|
||||
(add-hook 'after-init-hook 'global-company-mode)
|
||||
@@ -66,11 +72,13 @@ file[^1]:
|
||||
```
|
||||
|
||||
## Irony
|
||||
|
||||
Initial setup of `irony` **requires** `M-x irony-install-server` to be run. If
|
||||
errors are encountered, please ensure that you have the necessary [system
|
||||
dependencies](https://github.com/Sarcasm/irony-mode#dependencies) installed.
|
||||
|
||||
Irony's `irony-mode` should be added to the relevant C/C++ mode hooks:
|
||||
|
||||
```lisp
|
||||
(add-hook 'c++-mode-hook 'irony-mode)
|
||||
(add-hook 'c-mode-hook 'irony-mode)
|
||||
@@ -79,21 +87,25 @@ Irony's `irony-mode` should be added to the relevant C/C++ mode hooks:
|
||||
|
||||
Additionally, it's a good idea to add the compile options auto setup helper
|
||||
command to the `irony-mode` hook:
|
||||
```
|
||||
|
||||
```lisp
|
||||
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
There are several ways to make `irony-mode` aware of what it should look for in
|
||||
it's completion. My preferred method, though not the only one, is to simply add
|
||||
my compile flags in the special `.clang_complete` file as part of the working
|
||||
directory of the project.
|
||||
|
||||
For an STM32F0 project, the context of the `.clang_complete` file would be:
|
||||
```
|
||||
|
||||
```text
|
||||
-I./libopencm3/include
|
||||
-DSTM32F0
|
||||
```
|
||||
|
||||
<sub>The above assumes that `libopencm3` is also places within the project
|
||||
directory</sub>
|
||||
|
||||
@@ -106,9 +118,9 @@ fairly uninvolved workaround.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Example
|
||||
|
||||
{{< img src="/static/img/emacs-clang-libopencm3/completion.png"
|
||||
sub="Completion"
|
||||
alt= "Screenshot showing auto completion for C functions in emacs">}}
|
||||
|
||||
[^1]: [Emacs Initialization File]
|
||||
(https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html)
|
||||
[^1]: [Emacs Initialization File](https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html)
|
||||
|
||||
@@ -21,16 +21,18 @@ git config --global commit.gpgSign true
|
||||
|
||||
For reference, I am directly referencing the subkey ID I use for **signing only**
|
||||
denoted by `[S]`:
|
||||
```
|
||||
|
||||
```text
|
||||
pub rsa4096/ADAA54FC 2017-11-21 [SC] [expires: 2020-02-23]
|
||||
uid Bastian de Byl <bastiandebyl@gmail.com>
|
||||
sub rsa4096/A72FC2F1 2017-11-21 [E] [expires: 2020-02-23]
|
||||
sub rsa4096/875953A2 2019-02-23 [S] [expires: 2020-02-23]
|
||||
```
|
||||
|
||||
<sub>Note: _I am using git version `2.20.1` in the above example._</sub>
|
||||
|
||||
|
||||
# Getting Started with OpenPGP
|
||||
|
||||
It is recommended to read through the
|
||||
[Getting Started](https://www.gnupg.org/gph/en/manual/c14.html) page on the
|
||||
official GnuPG website. It is also **strongly** recommend to use the
|
||||
@@ -40,6 +42,7 @@ create a separate subkey for **signing only** -- read more about that
|
||||
[here](https://wiki.debian.org/Subkeys).
|
||||
|
||||
# OpenPGP Keyserver Pool
|
||||
|
||||
As of GnuPG version
|
||||
[2.1.11](https://github.com/riseupnet/riseup_help/issues/294#issuecomment-192913705),
|
||||
the `hpks.pool.sks-keyservers.net` CA certificate is installed and made use by
|
||||
@@ -51,13 +54,16 @@ signature. Instructions can be found on the
|
||||
reading further below.
|
||||
|
||||
## Verification
|
||||
|
||||
To verify and retrieve the necessary keys to do so (automatically, if possible):
|
||||
|
||||
```bash
|
||||
gpg --auto-key-retrieve --verify sks-keyservers.netCA.pem.asc sks-keyservers.netCA.pem
|
||||
```
|
||||
|
||||
The expected output:
|
||||
```
|
||||
|
||||
```text
|
||||
gpg: Signature made Wed 30 Mar 2016 11:06:29 AM EDT
|
||||
gpg: using RSA key 250B7AFED6379D85
|
||||
gpg: key 0B7F8B60E3EDFAE3: 1214 signatures not checked due to missing keys
|
||||
@@ -76,57 +82,66 @@ Primary key fingerprint: 94CB AFDD 3034 5109 5618 35AA 0B7F 8B60 E3ED FAE3
|
||||
```
|
||||
|
||||
## Adding the HKPS Pool CA
|
||||
|
||||
Once the signature has been verified, the CA can be moved over to
|
||||
`/usr/share/ca-certificates` to update the list of trusted CA certificates. Do
|
||||
this via:
|
||||
|
||||
+ **ArchLinux:** `sudo update-ca-trust`
|
||||
+ **Debian/Ubuntu, RHEL:** `sudo update-ca-certificates`
|
||||
|
||||
- **ArchLinux:** `sudo update-ca-trust`
|
||||
- **Debian/Ubuntu, RHEL:** `sudo update-ca-certificates`
|
||||
|
||||
{{< admonition tip "CA Path" >}}
|
||||
On my system the full path to the CA certs is:
|
||||
|
||||
- `/etc/ca-certificates/extracted/cadir/sks-keyservers.net_CA.pem`
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
Two following parameters should be added to your `~/.gnupg` configuration files:
|
||||
|
||||
### GnuPG Versions >2.1
|
||||
|
||||
|
||||
{{< admonition note "gpg.conf" >}}
|
||||
```
|
||||
|
||||
```text
|
||||
keyserver hkps://hkps.pool.sks-keyservers.net
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
|
||||
{{< admonition note "dirmngr.conf" >}}
|
||||
```
|
||||
|
||||
```text
|
||||
hkp-cacert /etc/ca-certificates/path/to/CA.pem
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
### GnuPG Versions <2.1
|
||||
|
||||
{{< admonition note "gpg.conf" >}}
|
||||
```
|
||||
|
||||
```text
|
||||
keyserver hkps://hkps.pool.sks-keyservers.net
|
||||
keyserver-options ca-cert-file=/path/to/CA/sks-keyservers.netCA.pem
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
## *Optional* - Ensure keys refreshed through keyserver
|
||||
|
||||
To ensure no keys are pulled from insecure sources, or that an attacked would
|
||||
not be able to designate a keyserver they control, it is recommended to add the
|
||||
following additional parameter to the above `gpg.conf` file:
|
||||
```
|
||||
|
||||
```text
|
||||
keyserver-options no-honor-keyserver-url
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# More Information
|
||||
|
||||
The
|
||||
[OpenPGP Best Practices](https://riseup.net/en/security/message-security/openpgp/best-practices)
|
||||
page is a good resource for finding out more on best practices. A few points
|
||||
|
||||
@@ -20,31 +20,37 @@ enable more hardening features. By default, the `linux-hardened` kernel on Arch
|
||||
Linux has security leaning defaults.
|
||||
|
||||
# Laying the Ground Work
|
||||
|
||||
On Arch Linux, it's as simple as:
|
||||
```
|
||||
|
||||
```text
|
||||
# pacman -S linux-hardened linux-hardened-headers
|
||||
```
|
||||
_Optionally (additionally) run `mkinitcpio -p linux-hardened` as root if
|
||||
this wasn't already done automatically as part of the installation_
|
||||
|
||||
<sub><i>Optionally (additionally) run `mkinitcpio -p linux-hardened` as root if
|
||||
this wasn't already done automatically as part of the installation</i></sub>
|
||||
|
||||
The steps to boot to the hardened kernel will change based on your boot
|
||||
loader. Personally, I am using
|
||||
[`systemd-boot`](https://wiki.archlinux.org/index.php/Systemd-boot) and will
|
||||
therefore start with that.
|
||||
|
||||
|
||||
## Boot Loader Configuration
|
||||
|
||||
### **`systemd-boot`**
|
||||
|
||||
Create a new loader config will need to be created on top of your existing one
|
||||
in `/boot/loader/entries/`
|
||||
|
||||
**Example**
|
||||
#### Example Systemd-boot Entry
|
||||
|
||||
```apacheconf
|
||||
title Arch Linux (Hardened)
|
||||
linux /vmlinuz-linux-hardened
|
||||
initrd /initramfs-linux-hardened.img
|
||||
options ...
|
||||
```
|
||||
|
||||
_The `options` line above will be specific to your system. This can be copied
|
||||
from existing, working loader configurations or such as the one described in
|
||||
[Installing Arch Linux](/post/archinstall/#set-up-linux-installation)_
|
||||
@@ -53,14 +59,17 @@ Change the default **or** enable `auto-entries` to selectively boot from it in
|
||||
`/boot/loader/loader.conf`
|
||||
|
||||
### **`grub`**
|
||||
|
||||
For grub, it should be as simple as running `grub-mkconfig -o
|
||||
/boot/grub/grub.cfg` (_as root_)
|
||||
|
||||
### **`syslinux`**
|
||||
|
||||
Similar to `systemd-boot`, `syslinux` requires an additional entry in it's
|
||||
configuration file, found at `/boot/syslinux/syslinux.conf`
|
||||
|
||||
**Example**
|
||||
#### Example Syslinux Config
|
||||
|
||||
```apacheconf
|
||||
PROMPT 1
|
||||
TIMEOUT 50
|
||||
@@ -73,10 +82,12 @@ LABEL archhardened
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
<sub>Note that the `APPEND` may differ from the example, same with `options`
|
||||
for `systemd-boot`</sub>
|
||||
|
||||
# Finish Line
|
||||
|
||||
It's that simple! There are additional system hardening steps one may opt to
|
||||
take such as:
|
||||
|
||||
@@ -90,6 +101,7 @@ On top of that, there are other tools one could leverage in addition to a
|
||||
hardened kernel, though that's out-of-scope for this post. One example would be
|
||||
something as simple as **disabling SSH password authentication**
|
||||
(`/etc/ssh/sshd_config`):
|
||||
|
||||
```apacheconf
|
||||
..
|
||||
PasswordAuthentication no
|
||||
|
||||
@@ -13,7 +13,8 @@ with the catch being: _I had to fix them_
|
||||
alt="Photo of Bern brand headphones under magnifying glass" >}}
|
||||
<!--more-->
|
||||
|
||||
# Don't Turn It On, Take It Apart!
|
||||
# Don't Turn It On, Take It Apart
|
||||
|
||||
Past mistakes have taught me to be gentle and patient when it comes to taking
|
||||
things apart. This was no exception either. After looking over the unit on each
|
||||
side, I figured the only way *in* was lifting the mesh cover off. So I went at
|
||||
@@ -21,6 +22,7 @@ it, carefully, with a pair of tweezers. I worked my way around the edge and
|
||||
wedged the mesh upwards.
|
||||
|
||||
# Okay, Maybe Turn It On
|
||||
|
||||
Now that the problematic speaker side was successfully opened without any
|
||||
damage, it was time to investigate what was wrong.
|
||||
|
||||
@@ -41,8 +43,8 @@ problematic, speaker. The result was much different, indicating either noise or
|
||||
an open circuit. It may be worth mentioning that the right speaker was
|
||||
disconnected at this point in time to ease the troubleshooting process.
|
||||
|
||||
# Where Did It All Go Wrong
|
||||
|
||||
# Where Did It All Go Wrong?
|
||||
Lucky for me the PCB pads were labeled -- even better `SPKL+` (_left_) and
|
||||
`SPKR+` (_right_) were easy to find.
|
||||
|
||||
@@ -70,8 +72,8 @@ bother desoldering the left speaker connections to make removal easier. So, with
|
||||
a bit of gentle back and forth I was able to get it the PCB out and inspect
|
||||
traces on the bottom side.
|
||||
|
||||
# Something's Not Quite Right
|
||||
|
||||
# Something's Not Quite Right...
|
||||
Continuity from `SPKL+` to the QFN pin was good, yet `SPKR+` to the op-amp
|
||||
showed open circuit. Visibly, everything on the PCB looked fine. There were no
|
||||
apparent signs of damaged or lifted traces, nor bad soldered wires or
|
||||
@@ -90,8 +92,8 @@ bodge wire was in order_..
|
||||
{{< thumb src="/static/img/headphone-fix/IMG_7515.jpg" sub="Note the bodge wire"
|
||||
alt="Photo of close-up magnified view with soldered fix wire in right speaker PCB" >}}
|
||||
|
||||
|
||||
# All's Well That Ends Well
|
||||
|
||||
Again, using my trusty Fluke 115, I verified continuity from the chip's `OUTR`
|
||||
pin to `SPKR+`. Lo and behold it was now closed-circuit! I was very happy to see
|
||||
the expected waveform from the known-good left channel now also appearing on the
|
||||
|
||||
@@ -13,6 +13,7 @@ from WordPress)
|
||||
|
||||
<!--more-->
|
||||
# Disclaimer
|
||||
|
||||
{{< admonition warning "Out of Date" >}}
|
||||
The information in this article is **out-of-date**. I am, and have been, using my
|
||||
own fork of the [hugo-even-theme](https://gitlab.com/bdebyl/hugo-theme-even) on
|
||||
@@ -26,8 +27,8 @@ relevant
|
||||
[commit](https://github.com/bdebyl/hugo-tracks-theme/commit/86ca4963c4d0a67ddb1560197c91617e7d3e3754) on
|
||||
my GitHub fork of the **Tracks** theme.
|
||||
|
||||
|
||||
# Rough Start
|
||||
|
||||
Right off the bat I noticed the navigation bar seemed a bit off, to say the least:
|
||||
|
||||
<center></center>
|
||||
@@ -40,7 +41,7 @@ page header.
|
||||
|
||||
> **.Site.Sections**
|
||||
>
|
||||
> top-level directories of the site.
|
||||
> top-level directories of the site.
|
||||
|
||||
\- [Source](https://gohugo.io/variables/site/#site-variables-list)
|
||||
|
||||
@@ -53,8 +54,8 @@ fully understanding where the `0` and `1` "sections" even originated from. In
|
||||
any case, I decided the only course of action was to use something other than
|
||||
sections for the behavior I wanted.
|
||||
|
||||
|
||||
# The Fix
|
||||
|
||||
Looking at other template files in the theme's layout, I stumbled on a chunk of
|
||||
code in `layouts/partials/headers.html` that defined the behavior of the
|
||||
aforementioned "navbar" problem:
|
||||
@@ -91,8 +92,8 @@ appears to be used*) to include the nav links and get my desired behavior:
|
||||
</div>
|
||||
```
|
||||
|
||||
# But Wait, There's More
|
||||
|
||||
# But Wait, There's More!
|
||||
After getting more comfortable with how themes are written for Hugo, I found a
|
||||
slew of other problems with the ported **Tracks** theme:
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ with a custom recovery to utilize for this purpose!
|
||||
alt="Screenshot showing the LineageOS Trust feature" >}}
|
||||
{{< /thumbgallery >}}
|
||||
|
||||
|
||||
<!--more-->
|
||||
# Thank You
|
||||
|
||||
Before going on any further, I'd like to take a moment to give my sincere thanks
|
||||
to InvisibleK (Dan Pasanen). Having to set up the entire custom build for Pixel
|
||||
3a of LineageOS myself would add far more overhead in the overall simple task in
|
||||
@@ -33,6 +33,7 @@ trying to get LineageOS to work on a Pixel 3a!
|
||||
[**tl;dr**](#flash-custom-recovery)
|
||||
|
||||
# Preface
|
||||
|
||||
There are plenty of guides out there on how to install and set up ADB and
|
||||
Fastboot on your host machine. For me, on Arch Linux, this was as simple as
|
||||
running `pacman -S android-tools`. However, should you be on MacOS or Windows
|
||||
@@ -43,11 +44,14 @@ Additionally, this _guide_ also assumes the reader has some familiarity with ADB
|
||||
and/or Fastboot.
|
||||
|
||||
# Source Files
|
||||
|
||||
If you, the reader, know what you're doing and simply just require the files
|
||||
for your Pixel 3a they can be found here:
|
||||
- https://updater.invisiblek.org/sargo
|
||||
|
||||
- <https://updater.invisiblek.org/sargo>
|
||||
|
||||
# Installation
|
||||
|
||||
{{< admonition warning "Warning!" >}}
|
||||
If it isn't abundantly clear by now, be aware that you **will be destroying all
|
||||
the data currently on your Pixel 3a** in the process of installing LineageOS on
|
||||
@@ -56,69 +60,88 @@ proceeding.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Note about TWRP
|
||||
|
||||
As of writing this, TWRP[^1] (_a custom recovery commonly used in custom OS
|
||||
installation_) does not support Android 10. This would have been the preferred
|
||||
for a custom recovery, though not strictly required. Since we will be installing
|
||||
LineageOS 17.1 for Android 10 we cannot use TWRP.
|
||||
|
||||
## Flash to Stock
|
||||
|
||||
Google is kind enough to provide a variety of versions of the stock images for
|
||||
the Pixel devices. In my process of installing LineageOS, as it will be on
|
||||
Android 10, I made sure to flash to the latest stock version of Pixel 3a Android
|
||||
10. Do note that the versions are listed in reverse order, with the latest being
|
||||
found in the bottom-most row.
|
||||
- https://developers.google.com/android/images
|
||||
|
||||
- <https://developers.google.com/android/images>
|
||||
|
||||
Additionally, Google provides a helper script `flash-all` that I highly
|
||||
recommend running as-is to flash your Pixel 3a to stock. This can take a few
|
||||
minutes to complete.
|
||||
|
||||
## Flash Custom Recovery
|
||||
|
||||
Using InvisibleK's build page, you'll find the required custom recovery image
|
||||
for flashing found at the bottom of the list of zip files marked with a lone
|
||||
"download" link.
|
||||
|
||||
Flash it via the following steps:
|
||||
|
||||
1. Reboot to recovery
|
||||
|
||||
```bash
|
||||
$ adb reboot bootloader
|
||||
adb reboot bootloader
|
||||
```
|
||||
|
||||
1. Unlock the bootloader if the 'Status' is locked:
|
||||
|
||||
```bash
|
||||
fastboot flashing unlock
|
||||
```
|
||||
$ fastboot flashing unlock
|
||||
```
|
||||
|
||||
1. Flash the custom recovery (_make sure to replace `N` with the version you
|
||||
downloaded, mine was '4'_)
|
||||
|
||||
```bash
|
||||
$ fastboot flash boot sargo-recovery-eng-N.img
|
||||
fastboot flash boot sargo-recovery-eng-N.img
|
||||
```
|
||||
|
||||
1. Boot the custom recovery either by re-entering recovery mode or fastboot --
|
||||
make sure to wait for it to enter Android Recovery after
|
||||
|
||||
```bash
|
||||
$ fastboot boot sargo-recovery-eng-N.img
|
||||
fastboot boot sargo-recovery-eng-N.img
|
||||
```
|
||||
|
||||
## Install LineageOS
|
||||
|
||||
Now that the custom recovery is set up and booted into, we're ready to install LineageOS!
|
||||
|
||||
1. **Important!** Once in recovery, ensure to `Wipe data/factory reset` prior to
|
||||
proceeding.
|
||||
1. Select `Apply update from ADB`
|
||||
1. ADB Sideload the version, if not latest, of LineageOS you want for your Pixel
|
||||
3a
|
||||
|
||||
```bash
|
||||
$ adb sideload lineage-17.1-2020517-UNOFFICIAL-sargo.zip
|
||||
adb sideload lineage-17.1-2020517-UNOFFICIAL-sargo.zip
|
||||
```
|
||||
|
||||
1. Wait for installation to complete then select 'Reboot system now' from the
|
||||
recovery menu
|
||||
1. **Enjoy LineageOS!**
|
||||
|
||||
## Verification
|
||||
|
||||
Once in LineageOS, you can browse the settings to verify the installation and
|
||||
set up Trust the preferred way. Personally, I chose to leave the defaults.
|
||||
|
||||
# Bugs / Issues
|
||||
|
||||
I plan to keep this list of bugs and issues I discover up to date, but this is
|
||||
what I have encountered so far:
|
||||
|
||||
- WiFi calling does not seem to work
|
||||
|
||||
[^1]: [Team Win Recovery Project](https://twrp.me/)
|
||||
|
||||
@@ -16,6 +16,7 @@ script with the following goals:
|
||||
|
||||
<!--more-->
|
||||
# Preface
|
||||
|
||||
The full **source code** for this script can be found in my public scripts
|
||||
repository:
|
||||
[scripts/bash/pass-check.sh](https://gitlab.com/bdebyl/scripts/blob/master/bash/pass-check.sh)
|
||||
@@ -27,6 +28,7 @@ to generate, and manage my passwords. On mobile, this is done using the official
|
||||
shared across my devices using Git[^2]
|
||||
|
||||
# Pump Your Brakes
|
||||
|
||||
Instead of jumping right into checking all my passwords, in plain-text, against
|
||||
the `pwnedpasswords` API, it would be best to figure out how to safely transform
|
||||
them to SHA-1[^3]. The API supports sending the first 5 characters of a SHA-1
|
||||
@@ -34,9 +36,11 @@ hash, returning a list of all SHA-1s of exposed passwords (_with the exposed
|
||||
count_) for the user to verify them on their end.
|
||||
|
||||
# Gathering Passwords
|
||||
|
||||
The easiest way to get a comprehensive list (_associative array_[^4]) of
|
||||
passwords and their `pass` path was to use `find` to look for `*.gpg` files in
|
||||
my `.password-store` directory:
|
||||
|
||||
```bash
|
||||
# Fetches all passwords in $PASSDIR and checks for duplicates (base check)
|
||||
getpws()
|
||||
@@ -52,6 +56,7 @@ getpws()
|
||||
done < <(find "$PASSDIR" -name "*.gpg" -type f -print0)
|
||||
}
|
||||
```
|
||||
|
||||
To note, `find` with `-print0` is used to avoid printing newline characters
|
||||
(_unlikely, but good practice_), so that we can utilize the null terminator `''`
|
||||
within `read -d ''`. Also, `read -r` simply prevents backslashes from being
|
||||
@@ -71,10 +76,12 @@ That takes care of gathering our passwords, but we'll revisit this again in the
|
||||
next part.
|
||||
|
||||
# Sharing is not Caring
|
||||
|
||||
The most efficient way of checking for duplicates was simply to iterate over the
|
||||
array of passwords gathered, and check against the current one found in the
|
||||
`getpws()` function's loop. The names of the duplicate passwords are stored in
|
||||
_another_ associative array for printing later as part of the "report".
|
||||
|
||||
```bash
|
||||
# Checks for duplicate sha1sums of passwords in the associative array
|
||||
checkdupes()
|
||||
@@ -88,6 +95,7 @@ checkdupes()
|
||||
```
|
||||
|
||||
That being done, we just incorporate it into the above `getpws()` loop!
|
||||
|
||||
```bash
|
||||
getpws()
|
||||
{
|
||||
@@ -102,6 +110,7 @@ This accomplishes our *first goal* of checking duplicate passwords --
|
||||
**hooray!**
|
||||
|
||||
# Passwortstärke
|
||||
|
||||
The simplest method of password strength checking, with indications as to _why_
|
||||
it's weak (_i.e. "Exists in attack dictionary", "Too short", etc._) was to use
|
||||
[`cracklib`](https://github.com/cracklib/cracklib). Sadly, it's not the most
|
||||
@@ -117,6 +126,7 @@ This addition was made in the following order:
|
||||
|
||||
1. First, we need to find the executable **and** create _yet another_ useful
|
||||
associative array for us to store the outputs (_a.k.a. messages_):
|
||||
|
||||
```bash
|
||||
CRACKLIB=$(command -v cracklib-check)
|
||||
declare -A pwscracklib
|
||||
@@ -124,6 +134,7 @@ This addition was made in the following order:
|
||||
|
||||
1. Then a convenient function to iterate over all found passwords, safely
|
||||
"expose" them, and run the check storing all **relevant** "outputs":
|
||||
|
||||
```bash
|
||||
# Run through the global pws associative array and check for suggestions
|
||||
checkcracklib()
|
||||
@@ -140,6 +151,7 @@ This addition was made in the following order:
|
||||
Done! It's _that_ easy.
|
||||
|
||||
# Have you been Pwned
|
||||
|
||||
The last, but **most important**, step was to add the actual check against the
|
||||
`pwnedpass` API check! This gets a bit fun as we use
|
||||
[Shell Parameter Expansion](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html)
|
||||
@@ -152,6 +164,7 @@ exposed (_"pwned"_) password's SHA-1 hash, and the amount of times they have
|
||||
been leaked as a response. The prefix of the first 5 characters is dropped in
|
||||
this list, thus we check for a match of our password using everything after the
|
||||
first 5 characters of the SHA-1 hash and we're done!
|
||||
|
||||
```bash
|
||||
# Check passwords against the HIBP password API (requires internet)
|
||||
checkpwnapi()
|
||||
|
||||
@@ -30,6 +30,7 @@ For those that want to cut to the chase and save time, here is the full source
|
||||
code with friendly names to get you started:
|
||||
|
||||
{{< admonition note "Source Code" true >}}
|
||||
|
||||
```C
|
||||
#include <libopencm3/stm32/gpio.h>
|
||||
#include <libopencm3/stm32/rcc.h>
|
||||
@@ -47,9 +48,11 @@ int main(void) {
|
||||
while (1);
|
||||
}
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
# Getting Started with libopencm3
|
||||
|
||||
[libopencm3](https://github.com/libopencm3/libopencm3) is a very powerful,
|
||||
useful, open-source firmware library for use in writing programs for various
|
||||
different ARM Cortex-M microcontrollers. It's read me contains plenty of
|
||||
@@ -60,8 +63,8 @@ Additionally, there is a
|
||||
[libopencm3-template](https://github.com/libopencm3/libopencm3-template)
|
||||
repository to help in getting started.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
Prior to doing any ARM Cortex-M development, the necessary dependencies need to
|
||||
be installed in order to successfully build/compile source code into a binary
|
||||
capable of being flashed (written) onto the microcontroller:
|
||||
@@ -74,6 +77,7 @@ capable of being flashed (written) onto the microcontroller:
|
||||
- **Text Editor or IDE**: Anything, _really_.
|
||||
|
||||
## Flashing the STM32F0 Discovery Board
|
||||
|
||||
The discovery series boards provided by ST come with an on-board
|
||||
[ST-LINK/V2](https://www.st.com/en/development-tools/st-link-v2.html)
|
||||
programmer. There are several ways to flash your build programs using this,
|
||||
@@ -86,6 +90,7 @@ not be overlooked for too long! For the sake of brevity, this guide will omit
|
||||
diving into that until later.
|
||||
|
||||
## Makefile
|
||||
|
||||
The aforementioned `libopencm3-examples` repository provides a useful, yet
|
||||
overly complex, Makefile. For the reader, this has been boiled down (_assuming
|
||||
they are also using `stlink` mentioned above_) the following, simple Makefile[^2] on
|
||||
@@ -95,6 +100,7 @@ To flash, it's as simple as `make flash` (_will also build the binary for your
|
||||
convenience_).
|
||||
|
||||
## Linker Script
|
||||
|
||||
The loader (`.ld`) file is specific to the _flavor_ of ARM Cortex-M
|
||||
microcontroller being used. The authors of `libopencm3` provide example
|
||||
loader files that can be used for most projects (_e.g. located in
|
||||
@@ -104,12 +110,13 @@ for proper use. There are several articles online that go into detail about
|
||||
linker scripts
|
||||
|
||||
## Project Structure
|
||||
|
||||
The Makefile, as of writing this, assumes your project directory structure has
|
||||
`libopencm3` either cloned, copied, or initialized as a git submodule within the
|
||||
same directory of your `main.c`. It is advised that you look through the
|
||||
Makefile's variables of things you may want to change:
|
||||
|
||||
```
|
||||
```text
|
||||
.
|
||||
├── libopencm3
|
||||
├── main.c
|
||||
@@ -139,16 +146,19 @@ The Discovery board comes with two LEDs for use by the user, tied to Port C pins
|
||||
8 (blue LED), and 9 (green LED).
|
||||
|
||||
## Reset and Clock Control (RCC)
|
||||
|
||||
The **RCC**, and it's registers, are an important part in _using_ the STM32
|
||||
microcontroller's peripherals. Luckily, utilizing `libopencm3` we can forego
|
||||
bit-banging our way through each register's bits found in the reference
|
||||
manual[^5] and simply utilize the GPIO port that we need -- in this case
|
||||
`GPIOC`:
|
||||
|
||||
```C
|
||||
rcc_periph_clock_enable(RCC_GPIOC);
|
||||
```
|
||||
|
||||
## GPIO Setup
|
||||
|
||||
Next, we need to define what mode we want the GPIO pins on their respective port
|
||||
to be along with the internal pull-up or pull-down resistor mode:
|
||||
|
||||
@@ -169,20 +179,22 @@ to be along with the internal pull-up or pull-down resistor mode:
|
||||
authors, along with the function definition can be found
|
||||
[**here**](https://libopencm3.org/docs/latest/html/)</i></sub></center>
|
||||
|
||||
|
||||
Having clarified that, as we want to **drive** the LEDs, we will need to
|
||||
configure the pins as outputs with no internal pull-up or pull-down resistor:
|
||||
|
||||
```C
|
||||
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
|
||||
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO9);
|
||||
```
|
||||
|
||||
_Simplified using bitwise[^6] OR:_
|
||||
|
||||
```C
|
||||
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8 | GPIO9);
|
||||
```
|
||||
|
||||
## GPIO Output Options Setup
|
||||
|
||||
Now that the GPIO mode has been set up, the GPIO output options need to be
|
||||
defined as well. This will encompass the output type, and output speed:
|
||||
|
||||
@@ -216,11 +228,13 @@ gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, GPIO9);
|
||||
```
|
||||
|
||||
_Simplified[^6]:_
|
||||
|
||||
```C
|
||||
gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_LOW, GPIO8 | GPIO9);
|
||||
```
|
||||
|
||||
## Turn it on!
|
||||
## Turn it On
|
||||
|
||||
There are no additional options required for the user to be able to now set, or
|
||||
clear, the desired GPIO pins. Thus, we set it _and forget it_:
|
||||
|
||||
@@ -230,12 +244,14 @@ gpio_set(GPIOC, GPIO9);
|
||||
```
|
||||
|
||||
_Simplified[^6]:_
|
||||
|
||||
```C
|
||||
gpio_set(GPIOC, GPIO8 | GPIO9);
|
||||
```
|
||||
|
||||
Lastly, we need to make sure our program never **exits** and does something
|
||||
_undesirable_ by keeping it inside a loop:
|
||||
|
||||
```C
|
||||
while(1);
|
||||
```
|
||||
@@ -256,7 +272,7 @@ Explained](http://www.learningaboutelectronics.com/Articles/While-(1)-embedded-C
|
||||
|
||||
[^1]: [GNU Arm Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm)
|
||||
[^2]: [Makefile](https://gitlab.com/bdebyl/stm32f0-example-project/blob/b858d5e38026bcce3b8aad4085ffb665ddf63eef/Makefile) as of writing this post
|
||||
[^3]: https://gitlab.com/bdebyl
|
||||
[^3]: <https://gitlab.com/bdebyl>
|
||||
[^4]: [STM32F0 Discovery User Manual](https://www.st.com/content/ccc/resource/technical/document/user_manual/30/ae/6e/54/d3/b6/46/17/DM00050135.pdf/files/DM00050135.pdf/jcr:content/translations/en.DM00050135.pdf)
|
||||
[^5]: [STM32F0 Reference Manual](https://www.st.com/content/ccc/resource/technical/document/reference_manual/c2/f8/8a/f2/18/e6/43/96/DM00031936.pdf/files/DM00031936.pdf/jcr:content/translations/en.DM00031936.pdf)
|
||||
[^6]: [Bitwise Operators in C](https://en.wikipedia.org/wiki/Bitwise_operations_in_C)
|
||||
|
||||
@@ -26,6 +26,7 @@ For those that want to cut to the chase and save time, here is the full source
|
||||
code with friendly names to get you started:
|
||||
|
||||
{{< admonition note "Source Code" true >}}
|
||||
|
||||
```C
|
||||
#include <libopencm3/stm32/gpio.h>
|
||||
#include <libopencm3/stm32/rcc.h>
|
||||
@@ -76,20 +77,23 @@ int main(void) {
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
|
||||
# Set up the GPIO
|
||||
|
||||
Assuming the reader is either familiar with GPIO setup for the STM32F0, or has
|
||||
reviewed [**Part 0**](/post/stm32-part0) of this series we will set up the GPIO
|
||||
pins tied to the LEDs (_port C, pins 8 and 9_) in the Alternate Function mode.
|
||||
|
||||
Knowing that we'll be using `GPIOC`, we should enable this peripheral:
|
||||
|
||||
```C
|
||||
rcc_periph_clock_enable(RCC_GPIOC);
|
||||
```
|
||||
|
||||
## Alternate Functions
|
||||
|
||||
The STM32 microcontroller's GPIO has a hardware feature allowing you to tie
|
||||
certain port's pins to a different register as part of the output or input
|
||||
control:
|
||||
@@ -107,8 +111,8 @@ Review the datasheet for the specific **STM32Fx** microcontroller being
|
||||
programmed, as the Alternate Function mappings may be *significantly* different!
|
||||
{{< /admonition >}}
|
||||
|
||||
|
||||
## GPIO Alternate Function Setup
|
||||
|
||||
For the STM32F0 we are using in this series, the Alternate Function selection
|
||||
number desired is `GPIO_AF0` for use with `TIM3_CH3` (_timer 3, channel 3_) and
|
||||
`TIM3_CH4` (_timer 3, channel 4_):
|
||||
@@ -116,8 +120,8 @@ number desired is `GPIO_AF0` for use with `TIM3_CH3` (_timer 3, channel 3_) and
|
||||
sub="STM32F051 Alternate Function Mapping"
|
||||
alt="Screenshot of alternate function pin definition table for STM32F0" >}}
|
||||
|
||||
|
||||
Ultimately, the code with `libopencm3` becomes the following for our use case:
|
||||
|
||||
```C
|
||||
gpio_mode_setup(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8 | GPIO9);
|
||||
gpio_set_output_options(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_HIGH, GPIO8 | GPIO9);
|
||||
@@ -125,16 +129,19 @@ gpio_set_af(GPIOC, GPIO_AF0, GPIO8 | GPIO9);
|
||||
```
|
||||
|
||||
# Set up the General Purpose Timer
|
||||
|
||||
From the previous section we chose the two on-board LEDs on the STM32F0
|
||||
Discovery board tied to `PC8` and `PC9`. From the Alternate Function GPIO
|
||||
mapping, we know these will be Timer 3 (_channels 3, and 4_).
|
||||
|
||||
Knowing that we'll be using `TIM3`, we should enable this peripheral:
|
||||
|
||||
```C
|
||||
rcc_periph_clock_enable(RCC_TIM3);
|
||||
```
|
||||
|
||||
## Timer Mode
|
||||
|
||||
The first step in setting up the timer, similar to GPIO, is setting the timer
|
||||
mode. The encompass the divider amount (_dividing the peripheral clock_),
|
||||
alignment for capture/compare, and up or down counting:
|
||||
@@ -165,6 +172,7 @@ timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
|
||||
```
|
||||
|
||||
## Timer Prescaler
|
||||
|
||||
In addition to the timer clock, set by the peripheral clock (internal), each
|
||||
timer has a perscaler value. This determines the counter clock frequency and is
|
||||
equal to `Frequency/(Prescaler + 1)`. This is the value the timer will count to prior
|
||||
@@ -175,6 +183,7 @@ integer value_).
|
||||
For the sake of simplicity in dividing the clock into easy decimal values, we
|
||||
will utilize setting up the High Speed Internal clock to 48MHz and dividing by
|
||||
48,000:
|
||||
|
||||
```C
|
||||
rcc_clock_setup_in_hsi_out_48mhz(); // Place at the beginning of your int 'main(void)'
|
||||
...
|
||||
@@ -184,18 +193,20 @@ timer_set_prescaler(TIM3, (rcc_apb1_frequency/48000)/2*SECONDS));
|
||||
```
|
||||
|
||||
## Timer Period
|
||||
|
||||
Having set the prescaler to determine the maximum count of the timer, there is
|
||||
an additional period we need to set. For our purposes, this will simply be the
|
||||
same value of the prescaler:
|
||||
|
||||
```C
|
||||
timer_set_period(TIM3, 48000);
|
||||
```
|
||||
|
||||
## Timer Additional Configuration
|
||||
There are two minor settings we want to configure for the timer:
|
||||
<div style="display: none;">[^1]</div>
|
||||
|
||||
1. Disable preloading the ARR<sup id="fnref:1" class="footnote-ref"><a href="#fn:1">1</a></sup> (auto-reload register) when the timer is reset
|
||||
There are two minor settings we want to configure for the timer:
|
||||
|
||||
1. Disable preloading the ARR[^1] (auto-reload register) when the timer is reset
|
||||
1. Run the timer in continuous mode (never stop counting, clear the status
|
||||
register automatically)
|
||||
|
||||
@@ -205,6 +216,7 @@ timer_continuous_mode(TIM3);
|
||||
```
|
||||
|
||||
## Timer Channel Output Compare Mode
|
||||
|
||||
Since we are utilizing Timer 3's channel 3 (`GPIOC8`), and channel 4 (`GPIOC9`)
|
||||
we need to determine the output compare mode we want to use for each channel. By
|
||||
default the mode for each channel is frozen (unaffected by the comparison of the
|
||||
@@ -232,6 +244,7 @@ timer_set_oc_mode(TIM3, TIM_OC4, TIM_OCM_PWM2);
|
||||
In layman's terms: _only one LED will be on at a time, alternating._
|
||||
|
||||
## Timer Channel Output Compare Value
|
||||
|
||||
Lastly, we need to set the values that the output compare looks to for it's
|
||||
comparison. For this example, we want a 50%-on/50%-off time for ease of timing
|
||||
the duration of LEDs on-time determined by the frequency and period of the
|
||||
@@ -244,6 +257,7 @@ timer_set_oc_value(TIM3, TIM_OC4, 24000);
|
||||
```
|
||||
|
||||
### Exercise for the Reader
|
||||
|
||||
A fun exercise in C to reduce repetition would be by creating an array of timer
|
||||
output compare address values and looping through them to set them to the same
|
||||
value.
|
||||
@@ -254,6 +268,7 @@ microcontroller. That being said, there is still some fun to have.
|
||||
|
||||
The following snippet will be provided as a note and exercise for the reader in
|
||||
exploring memory allocation and garbage collection:
|
||||
|
||||
```C
|
||||
int tim_oc_ids[2] = { TIM_OC3, TIM_OC4 };
|
||||
|
||||
@@ -261,10 +276,12 @@ for (i = 0; i < (sizeof(tim_oc_ids)/sizeof(tim_oc_ids[0])); ++i) {
|
||||
timer_set_oc_value(TIM3, tim_oc_ids[i], 24000);
|
||||
}
|
||||
```
|
||||
|
||||
<center><sub>_Determining the 'length' of an array in C is different than in
|
||||
other languages.[^2]_</sub></center>
|
||||
|
||||
## Enable the Timer
|
||||
|
||||
Lastly, to kick everything off we need to enable both the timer and the relevant
|
||||
output-compare outputs.
|
||||
|
||||
@@ -277,6 +294,7 @@ timer_enable_counter(TIM3);
|
||||
```
|
||||
|
||||
### Another Exercise for the Reader
|
||||
|
||||
The same for loop for `timer_set_oc_value()` can be appended to
|
||||
for `timer_enable_oc_output()` as discussed previously:
|
||||
|
||||
@@ -290,8 +308,10 @@ for (i = 0; i < (sizeof(tim_oc_ids)/sizeof(tim_oc_ids[0])); ++i) {
|
||||
```
|
||||
|
||||
# Fin
|
||||
|
||||
Lastly, as always, we should not forget to place the microcontroller in an
|
||||
infinite loop:
|
||||
|
||||
```C
|
||||
while (1);
|
||||
```
|
||||
|
||||
@@ -17,6 +17,7 @@ to say this required fixing.
|
||||
<!--more-->
|
||||
|
||||
# Damage Assessment
|
||||
|
||||
The first step was to look at the PCB to assess how this could be, if at all,
|
||||
replaced. From the outside you could see the damage done. Note the single
|
||||
pin left and lack of the inner pad (_bolster?_).
|
||||
@@ -25,8 +26,8 @@ pin left and lack of the inner pad (_bolster?_).
|
||||
sub="One pin remains"
|
||||
alt="Photo showing one pin remaining on a damaged USB receptacle ">}}
|
||||
|
||||
|
||||
# Measure Twice
|
||||
|
||||
Next on the list: measurements. To find a suitable replacement receptacle, I
|
||||
needed to have the relevant dimensions in comparing to receptacle part drawings
|
||||
of those available for sale.
|
||||
@@ -50,13 +51,14 @@ Using generic, non-branded digital calipers I was able to get the following
|
||||
| Pad Width | _1.9mm_ |
|
||||
<center><sub>Fig. 1</sub></center>
|
||||
|
||||
|
||||
# Shopping with Purpose
|
||||
|
||||
Using the value above, I was able to track down a USB receptacle[^1] on
|
||||
Digi-Key[^2] that matched my requirements very, _very_
|
||||
closely.
|
||||
|
||||
## Resounding Comparison
|
||||
|
||||
Keep in mind the measured values were an eyeball approximation with a low cost,
|
||||
unbranded digital caliper. Those values are nearly spot-on.
|
||||
|
||||
@@ -76,6 +78,7 @@ other the two receptacles matched up just as I had hoped.. **Fantastic!**
|
||||
alt="Photo showing new USB receptacle on top of damaged one for comparison" >}}
|
||||
|
||||
# It's not over yet
|
||||
|
||||
Initial attempts at desoldering the existing (_broken_) receptacle proved
|
||||
futile. Even with liberal application of flux, high soldering iron temperatures
|
||||
well beyond typical soldering temperatures[^3], the solder would not flow and
|
||||
@@ -92,6 +95,7 @@ having spent about half an hour on it with tweezers, solder wick, a solder
|
||||
sucker (_desoldering pump_), and flush cutters, I gave up.
|
||||
|
||||
# Throwing in the Towel
|
||||
|
||||
It turned out the only way to attach the replacement was to modify the new part
|
||||
to fit -- _luckily I had ordered two replacements as I broke the first one in
|
||||
the modification "process"_. Cutting and bending the pins, I was able to get it
|
||||
@@ -108,6 +112,7 @@ been able to bend the flat pads towards the entry of the receptacle down to
|
||||
attempt to solder them to the surface mount pads.
|
||||
|
||||
# All the King's horses, all the King's men
|
||||
|
||||
Alas, it was time to put the laptop back together. To my dismay there were
|
||||
further problems. Due to the modification and forced fitment of the replacement,
|
||||
the USB receptacle was sticking out too far off of the PCB preventing the
|
||||
|
||||
@@ -19,18 +19,22 @@ write-up on this blog: [**OpenPGP Best Practices (and Git)**](/post/gpg_best_pra
|
||||
{{< /admonition >}}
|
||||
|
||||
# Importing Secret Keys
|
||||
|
||||
Personally, my secret (primary) key is not kept on any device. It's stored, and
|
||||
backed up in encrypted external media devices (_USB, etc._) only to be imported
|
||||
when keys require editing.
|
||||
|
||||
## Mounting Secure Device (LUKS)
|
||||
|
||||
This is done using `cryptsetup` and Linux Unified Key Setup[^1] (LUKS) for
|
||||
encryption. Plugging in my USB device and mounting it requires only _one_
|
||||
additional step. Instead of initially running `mount /dev/sdXN` we first must
|
||||
"open" the encrypted drive via:
|
||||
|
||||
```bash
|
||||
cryptsetup --type luks open /dev/sdXN encryptedusb
|
||||
```
|
||||
|
||||
{{< sub >}}
|
||||
The `encryptedusb` name is a user-specified friendly name that has
|
||||
no relevance to accessing the drive
|
||||
@@ -39,47 +43,58 @@ no relevance to accessing the drive
|
||||
**Now** the device can be mounted to a directory, but not via the `/dev/sdXN` device
|
||||
-- rather the `/dev/mapper/encryptedusb` device (_or whatever friendly name you
|
||||
gave it_).
|
||||
|
||||
```bash
|
||||
mount /dev/mapper/encryptedusb /mnt/media
|
||||
```
|
||||
|
||||
## Backing up the Keys
|
||||
|
||||
Once the device has been securely mounted, it's a good idea to either export
|
||||
the keys currently in the keyring **or** back-up the entire `~/.gnupg`
|
||||
directory. The backup created will be stored on the previously mounted external
|
||||
media device.
|
||||
|
||||
### GPG Key Export Backup
|
||||
|
||||
It's as simple as exporting the secret key, which will also contain your public
|
||||
key:
|
||||
|
||||
```bash
|
||||
gpg --armor --export-secret-key your@email.address > /mnt/media/some/dir/secretkey.gpg.bak
|
||||
```
|
||||
|
||||
### GPG Directory Backup (optional)
|
||||
|
||||
This isn't entirely necessary, though it's never a bad idea to create a hard
|
||||
back-up of the directory -- _just don't forget to remove it after!_
|
||||
|
||||
```bash
|
||||
cp ~/.gnupg /mnt/media/some/backup/dir/.gnupg.bak
|
||||
```
|
||||
|
||||
{{< sub >}}
|
||||
Note: If the `~/.gnupg.bak` directory already exists, the above command will
|
||||
copy it to `~/gnupg.bak/.gnupg`!
|
||||
{{< /sub >}}
|
||||
|
||||
## Import and Update Expiration
|
||||
|
||||
Now that back-ups have been taken care of, the current keyring can either be
|
||||
emptied, deleted, or simply worked with. That's up to the user.
|
||||
|
||||
### Import
|
||||
|
||||
In any event, the next step ultimately becomes importing the secret (primary)
|
||||
key:
|
||||
|
||||
```bash
|
||||
gpg --import /mnt/media/some/backup/dir/secretprimarykey.gpg
|
||||
```
|
||||
|
||||
Verify the presence of the primary secret key, noting no presence of `sec#` in
|
||||
the output indicating only a partially stripped secret key, via:
|
||||
|
||||
```bash
|
||||
gpg --list-secret-keys
|
||||
|
||||
@@ -89,9 +104,11 @@ sec rsa4096 2017-11-21 [SC] [expires: 2021-02-16]
|
||||
```
|
||||
|
||||
### Update
|
||||
|
||||
Updating the primary secret key and all it's sub keys is done via `gpg` in the
|
||||
following manner:
|
||||
```
|
||||
|
||||
```text
|
||||
gpg --edit-key your@email.address
|
||||
|
||||
gpg> key 0
|
||||
@@ -114,6 +131,7 @@ gpg> save
|
||||
```
|
||||
|
||||
At this point, it's a good idea to send the key to the key server:
|
||||
|
||||
```bash
|
||||
gpg --send-keys your@email.address
|
||||
# or
|
||||
@@ -121,8 +139,10 @@ gpg --keyserver pgp.mit.edu --send-keys your@email.address
|
||||
```
|
||||
|
||||
## Cleanup
|
||||
|
||||
Now it's time to export the primary key and it's sub keys to the encrypted
|
||||
external media device:
|
||||
|
||||
```bash
|
||||
gpg --armor --export-secret-key your@email.address > /mnt/media/some/dir/secretkey.gpg
|
||||
gpg --armor --export-secret-subkeys your@email.address > /mnt/media/some/dir/secretsubkey.gpg
|
||||
@@ -130,6 +150,7 @@ gpg --armor --export-secret-subkeys your@email.address > /mnt/media/some/dir/sec
|
||||
|
||||
Then, delete the primary secret key from your keyring and import **only** the
|
||||
secret sub-key:
|
||||
|
||||
```bash
|
||||
gpg --delete-secret-keys your@email.address
|
||||
# reply 'yes' to the prompts as needed
|
||||
@@ -138,29 +159,33 @@ gpg --import /mnt/media/some/dir/secretsubkey.gpg
|
||||
```
|
||||
|
||||
### Verification
|
||||
|
||||
Once **only** the secret sub-key has been imported from the previous step, it
|
||||
should be verified that the primary secret key is **not** in your keyring
|
||||
(partial stripped key designated via `sec#` in the following):
|
||||
```
|
||||
|
||||
```text
|
||||
gpg --list-secret-keys
|
||||
|
||||
--------------------------------
|
||||
sec# rsa4096 2017-11-21 [SC] [expires: 2021-02-16]
|
||||
...
|
||||
```
|
||||
|
||||
{{< sub >}}
|
||||
Note: `sec#` is what we are looking for. If it is indicated as only `sec` then
|
||||
the primary secret key is **still** in the keyring! Repeat the prior steps to
|
||||
attempt this again should you have to, but do so carefully.
|
||||
{{< /sub >}}
|
||||
|
||||
|
||||
## Unmounting
|
||||
|
||||
Lastly, remember to remove any local back-ups of the keyring or keys you stored
|
||||
on the host! These should _only_ exist on the encrypted external device.
|
||||
|
||||
To un-mount the LUKS[^1] encrypted device, it's just one additional step to the
|
||||
usual `umount`:
|
||||
|
||||
```bash
|
||||
umount /mnt/media
|
||||
cryptsetup --type luks close encryptedusb
|
||||
@@ -169,13 +194,16 @@ cryptsetup --type luks close encryptedusb
|
||||
That being done, it is safe to remove the external device!
|
||||
|
||||
# OpenKeychain Export & Import
|
||||
|
||||
Provided the reader is on an Android device, it can be mounted onto the local
|
||||
host using `simple-mtpfs`.
|
||||
|
||||
## Mounting Android Device
|
||||
|
||||
First, plug in the Android device via a suitable USB cable to the local host and
|
||||
set the USB managed option to "File Transfer" on the Android device. After this
|
||||
the device should be mountable:
|
||||
|
||||
```bash
|
||||
simple-mtpfs -l
|
||||
1: Google IncNexus/Pixel (MTP)
|
||||
@@ -184,10 +212,12 @@ simple-mtpfs --device 1 /mnt/android
|
||||
```
|
||||
|
||||
## Export Secret Key
|
||||
|
||||
Once the device is mounted, we want to export the _partially_ stripped key (_not
|
||||
the primary key_) to be imported using OpenKeychain on the Android device. The
|
||||
next steps quote from the [OpenKeychain
|
||||
FAQ](https://www.openkeychain.org/faq/#how-to-import-an-openkeychain-backup-with-gpg):
|
||||
|
||||
```bash
|
||||
# generate a strong random password
|
||||
gpg --armor --gen-random 1 20
|
||||
@@ -199,5 +229,4 @@ gpg --armor --export-secret-keys YOUREMAILADDRESS | gpg --armor --symmetric --ou
|
||||
Import it in OpenKeychain (_may require deletion in OpenKeychain first -- make
|
||||
sure **not to revoke and delete!**_) and we're done!
|
||||
|
||||
|
||||
[^1]: https://guardianproject.info/archive/luks/
|
||||
|
||||
Reference in New Issue
Block a user