Compare commits
10 Commits
c3ab31fb31
...
da7c837fc0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da7c837fc0 | ||
|
|
4a269c01d8 | ||
|
|
d82196bc35 | ||
|
|
96e42a411d | ||
|
|
2a34727289 | ||
|
|
20c51ebc83 | ||
|
|
dcea5bf679 | ||
|
|
67efdf6d41 | ||
|
|
51d9ba3390 | ||
|
|
5f4c121113 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
*.lock
|
||||
flymd*
|
||||
public/
|
||||
resources/
|
||||
static/
|
||||
themes/
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "themes/papermod"]
|
||||
path = themes/papermod
|
||||
url = git@github.com:adityatelange/hugo-PaperMod.git
|
||||
105
Makefile
105
Makefile
@@ -1,109 +1,32 @@
|
||||
# This Makefile was originally taken from https://github.com/alimac/alimac.io/
|
||||
# Website hostname, used to set:
|
||||
# - image and container names
|
||||
# - path to web root (in /tmp directory)
|
||||
WEB_BUCKET=bdebyl.net
|
||||
STATIC_BUCKET=bdebyl.static
|
||||
STATIC_DIR=static
|
||||
WEBSITE=debyl.io
|
||||
|
||||
HUGO_IMAGE_NAME=bdebyl/hugo
|
||||
HUGO_IMAGE_TAG?=latest
|
||||
HUGO_IMAGE=$(HUGO_IMAGE_NAME):$(HUGO_IMAGE_TAG)
|
||||
|
||||
THUMBR_IMAGE_NAME=bdebyl/thumbr
|
||||
THUMBR_IMAGE_TAG?=latest
|
||||
THUMBR_IMAGE?=$(THUMBR_IMAGE_NAME):$(THUMBR_IMAGE_TAG)
|
||||
|
||||
AWS_IMAGE_NAME=bdebyl/awscli
|
||||
AWS_IMAGE_TAG?=latest
|
||||
AWS_IMAGE=$(AWS_IMAGE_NAME):$(AWS_IMAGE_TAG)
|
||||
|
||||
MDLINT_IMAGE_NAME=peterdavehello/markdownlint
|
||||
MDLINT_IMAGE_TAG?=latest
|
||||
MDLINT_IMAGE?=$(MDLINT_IMAGE_NAME):$(MDLINT_IMAGE_TAG)
|
||||
MDLINT_PATH?=content/
|
||||
|
||||
# Container Variables
|
||||
RUN_USER=--user $(shell id -u $$USER):$(shell id -g $$USER)
|
||||
RUN_VOL=-v $(shell pwd):/src
|
||||
AWS_ENV=-e "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" -e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" -e "AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}"
|
||||
|
||||
MOUNT_BUCKET?=1
|
||||
|
||||
DOCKER_PORT=-p 1313:1313/tcp
|
||||
DOCKER_RUN=docker run --rm ${RUN_USER} ${RUN_VOL}
|
||||
AWS=aws --profile default
|
||||
|
||||
# Look up CloudFront distribution ID based on website alias
|
||||
DISTRIBUTION_ID=$(shell docker run --rm ${AWS_ENV} ${AWS_IMAGE} cloudfront list-distributions \
|
||||
--query 'DistributionList.Items[].{id:Id,a:Aliases.Items}[?contains(a,`${WEB_BUCKET}`)].id' \
|
||||
DISTRIBUTION_ID=$(shell ${AWS} cloudfront list-distributions \
|
||||
--query 'DistributionList.Items[].{id:Id,a:Aliases.Items}[?contains(a,`${WEBSITE}`)].id' \
|
||||
--output text)
|
||||
S3_SYNC=s3 sync --sse "AES256" public/ s3://${WEBSITE}
|
||||
CLOUDFRONT_INVALIDATE=cloudfront create-invalidation --distribution-id ${DISTRIBUTION_ID} --paths '/*'
|
||||
|
||||
ifdef DRYRUN
|
||||
S3_DRYRUN=--dryrun
|
||||
endif
|
||||
ifdef DELETE
|
||||
S3_DELETE=--delete
|
||||
endif
|
||||
S3_CACHE_CONTROL?=86400
|
||||
S3_CMD=s3 sync ${S3_DRYRUN} ${S3_DELETE} --metadata-directive REPLACE --cache-control max-age=${S3_CACHE_CONTROL},public --acl "public-read" --sse "AES256"
|
||||
S3_CMD_WEB=${S3_CMD} public/ s3://${WEB_BUCKET}
|
||||
S3_CMD_STATIC=${S3_CMD} static/ s3://${STATIC_BUCKET}
|
||||
CLOUDFRONT_PATHS?='/*'
|
||||
CLOUDFRONT_CMD=cloudfront create-invalidation --distribution-id ${DISTRIBUTION_ID} --paths ${CLOUDFRONT_PATHS}
|
||||
|
||||
all: build
|
||||
# Default target for make (<=3.80)
|
||||
default:
|
||||
-hugo server
|
||||
.PHONY: default
|
||||
|
||||
build:
|
||||
$(DOCKER_RUN) ${HUGO_IMAGE}
|
||||
-hugo build
|
||||
.PHONY: build
|
||||
|
||||
lint:
|
||||
$(DOCKER_RUN) -v $$PWD:/md:ro ${MDLINT_IMAGE} markdownlint ${MDLINT_PATH}
|
||||
.PHONY: lint
|
||||
|
||||
static-pull:
|
||||
if [ ! -d "${STATIC_DIR}/static" ]; then aws s3 sync s3://${STATIC_BUCKET} ${STATIC_DIR}/; fi
|
||||
.PHONY: static-pull
|
||||
|
||||
static-push:
|
||||
aws ${S3_CMD_STATIC}
|
||||
.PHONY: static-push
|
||||
|
||||
static-images:
|
||||
@${DOCKER_RUN} ${THUMBR_IMAGE} ${STATIC_DIR}/static/img
|
||||
.PHONY: static-images
|
||||
|
||||
css-push:
|
||||
aws s3 cp --acl "public-read" --sse "AES256" public/dist/style.css s3://${WEB_BUCKET}/dist/style.css
|
||||
.PHONY: css-push
|
||||
|
||||
run: static-pull
|
||||
-$(DOCKER_RUN) -it ${DOCKER_PORT} ${HUGO_IMAGE} -D server --bind=0.0.0.0
|
||||
.PHONY: run
|
||||
|
||||
version:
|
||||
$(DOCKER_RUN) ${HUGO_IMAGE} version
|
||||
.PHONY: version
|
||||
|
||||
new:
|
||||
$(DOCKER_RUN) ${HUGO_IMAGE} new post/"$(shell read -p 'Post Name (i.e. my_post.md): ' pn; echo $$pn)"
|
||||
.PHONY: new
|
||||
|
||||
clean:
|
||||
@# Clean up existing generated site
|
||||
rm -rf public/ resources/
|
||||
.PHONY: clean
|
||||
|
||||
static-clean:
|
||||
if [ -d "${STATIC_DIR}/static" ]; then rm -rfv static/
|
||||
.PHONY: static-clean
|
||||
rm -rfv public/
|
||||
|
||||
deploy: clean build
|
||||
@# Upload files to S3
|
||||
@$(DOCKER_RUN) ${AWS_ENV} ${AWS_IMAGE} ${S3_CMD_WEB}
|
||||
${AWS} ${S3_SYNC}
|
||||
.PHONY: deploy
|
||||
|
||||
cache:
|
||||
@# Invalidate caches
|
||||
@$(DOCKER_RUN) ${AWS_ENV} ${AWS_IMAGE} ${CLOUDFRONT_CMD}
|
||||
${AWS} ${CLOUDFRONT_INVALIDATE}
|
||||
.PHONY: cache
|
||||
|
||||
39
assets/css/extended/thumbnail.css
Normal file
39
assets/css/extended/thumbnail.css
Normal file
@@ -0,0 +1,39 @@
|
||||
.thumbnail-container {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.thumbnail-container a {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
margin: auto;
|
||||
padding: .75rem;
|
||||
text-align: center;
|
||||
max-width: 80%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.thumbnail sub {
|
||||
font-size: small;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.thumbnail-gallery {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.thumbnail-gallery a {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.thumbnail-gallery .thumbnail {
|
||||
display: inline-block;
|
||||
margin: .125rem;
|
||||
padding: .50rem;
|
||||
width: 42%;
|
||||
}
|
||||
193
config.yaml
193
config.yaml
@@ -1,12 +1,12 @@
|
||||
# core
|
||||
baseURL: "https://bdebyl.net/"
|
||||
title: "Collection of useful, and useless information"
|
||||
theme: "even"
|
||||
baseURL: https://debyl.io/
|
||||
title: debyl.io
|
||||
theme: papermod
|
||||
enableEmoji: true
|
||||
|
||||
# settings
|
||||
paginate: 5
|
||||
defaultContentLanguage: "en"
|
||||
languageCode: "en"
|
||||
defaultContentLanguage: en
|
||||
languageCode: en
|
||||
buildDrafts: false
|
||||
canonifyURLs: true
|
||||
enableRobotsTXT: true
|
||||
@@ -15,10 +15,17 @@ markup:
|
||||
goldmark:
|
||||
renderer:
|
||||
unsafe: true
|
||||
highlight:
|
||||
noClasses: false
|
||||
# anchorLineNos: true
|
||||
# codeFences: true
|
||||
# guessSyntax: true
|
||||
# lineNos: true
|
||||
# style: monokai
|
||||
|
||||
# google analytics
|
||||
googleAnalytics: "UA-163975086-1"
|
||||
googleVerification: ""
|
||||
googleAnalytics: UA-163975086-1
|
||||
googleVerification:
|
||||
|
||||
# See https://gohugo.io/about/hugo-and-gdpr/
|
||||
privacy:
|
||||
@@ -30,63 +37,135 @@ privacy:
|
||||
# https://gohugo.io/content-management/syntax-highlighting/
|
||||
pygmentsCodefences: true
|
||||
pygmentsCodefencesGuessSyntax: true
|
||||
pygmentsOptions: ""
|
||||
pygmentsOptions:
|
||||
pygmentsUseClasses: true
|
||||
|
||||
author:
|
||||
name: "Bastian de Byl"
|
||||
|
||||
sitemap:
|
||||
changefreq: "weekly"
|
||||
filename: "sitemap.xml"
|
||||
changefreq: weekly
|
||||
filename: sitemap.xml
|
||||
priority: 0.5
|
||||
|
||||
menu:
|
||||
outputs:
|
||||
home:
|
||||
- HTML
|
||||
- RSS
|
||||
- JSON
|
||||
|
||||
languages:
|
||||
en:
|
||||
languageName: English
|
||||
weight: 1
|
||||
taxonomies:
|
||||
category: categories
|
||||
tag: tags
|
||||
series: series
|
||||
menu:
|
||||
main:
|
||||
- name: "Home"
|
||||
- name: Archive
|
||||
url: archives
|
||||
weight: 5
|
||||
- name: Search
|
||||
url: search/
|
||||
weight: 10
|
||||
- name: Tags
|
||||
url: tags/
|
||||
weight: 10
|
||||
identifier: "home"
|
||||
url: "/"
|
||||
- name: "About"
|
||||
weight: 20
|
||||
identifier: "about"
|
||||
url: "/about"
|
||||
- name: "Archives"
|
||||
weight: 30
|
||||
identifier: "archives"
|
||||
url: "/post/"
|
||||
- name: "Tags"
|
||||
weight: 40
|
||||
identifier: "tags"
|
||||
url: "/tags/"
|
||||
|
||||
params:
|
||||
favicon: "/static/img/favicon.ico"
|
||||
since: "2017"
|
||||
logoImage: "/static/img/logo.png"
|
||||
images:
|
||||
- "/static/img/logo-prev.png"
|
||||
logoTitle: "bdebyl"
|
||||
keywords: ["bastian", "de byl", "bdebyl", "bastian de byl"]
|
||||
description: "A random assortment of my personal projects."
|
||||
env: production # to enable google analytics, opengraph, twitter-cards and schema.
|
||||
description: Theme PaperMod - https://github.com/adityatelange/hugo-PaperMod
|
||||
author: Bastian de Byl
|
||||
# author: [Me, You] # multiple authors
|
||||
|
||||
# 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: true
|
||||
# show "read more" link on post summary
|
||||
readMoreEnabled: 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>'
|
||||
ShowAllPagesInArchive: true
|
||||
ShowBreadCrumbs: true
|
||||
ShowCodeCopyButtons: true
|
||||
ShowPageNums: true
|
||||
ShowPostNavLinks: true
|
||||
ShowReadingTime: true
|
||||
ShowRssButtonInSectionTermList: true
|
||||
ShowShareButtons: true
|
||||
ShowToc: false
|
||||
comments: false
|
||||
defaultTheme: dark
|
||||
disableSpecial1stPost: false
|
||||
disableThemeToggle: true
|
||||
displayFullLangName: true
|
||||
images: [images/papermod-cover.png]
|
||||
|
||||
social:
|
||||
a-email: "mailto:bastian@bdebyl.net"
|
||||
g-github: "https://github.com/bdebyl"
|
||||
m-instagram: "https://instagram.com/bastian.remi"
|
||||
n-gitlab: "https://gitlab.com/bdebyl"
|
||||
e-linkedin: "https://www.linkedin.com/in/bastian-de-byl-90171b187"
|
||||
profileMode:
|
||||
enabled: false
|
||||
|
||||
homeInfoParams:
|
||||
Title: >
|
||||
:wave: Welcome
|
||||
Content: >
|
||||
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.
|
||||
<br/>
|
||||
<br/>
|
||||
This is just my personal blog site, feel free to get in touch with me
|
||||
using the icon links below.
|
||||
|
||||
socialIcons:
|
||||
- name: github
|
||||
title: Github
|
||||
url: https://github.com/bdebyl
|
||||
- name: X
|
||||
title: Twitter
|
||||
url: https://x.com/bastiandebyl
|
||||
- name: email
|
||||
title: Email
|
||||
url: mailto:bastian@debyl.io
|
||||
|
||||
# label:
|
||||
# iconSVG: '<svg xmlns=http://www.w3.org/2000/svg height=25 viewBox=0 -960 960 960 fill=currentColor><path d=M320-240h320v-80H320v80Zm0-160h320v-80H320v80ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z/></svg>'
|
||||
# text: Home
|
||||
# icon: icon.png
|
||||
# iconHeight: 35
|
||||
|
||||
assets:
|
||||
disableHLJS: true
|
||||
# favicon: <link / abs url>
|
||||
# favicon16x16: <link / abs url>
|
||||
# favicon32x32: <link / abs url>
|
||||
# apple_touch_icon: <link / abs url>
|
||||
# safari_pinned_tab: <link / abs url>
|
||||
|
||||
# cover:
|
||||
# hidden: true # hide everywhere but not in structured data
|
||||
# hiddenInList: true # hide on list pages and home
|
||||
# hiddenInSingle: true # hide on single page
|
||||
|
||||
# fuseOpts:
|
||||
# isCaseSensitive: false
|
||||
# shouldSort: true
|
||||
# location: 0
|
||||
# distance: 1000
|
||||
# threshold: 0.4
|
||||
# minMatchCharLength: 0
|
||||
# keys: [title, permalink, summary, content]
|
||||
|
||||
# privacy:
|
||||
# vimeo:
|
||||
# disabled: false
|
||||
# simple: true
|
||||
|
||||
# twitter:
|
||||
# disabled: false
|
||||
# enableDNT: true
|
||||
# simple: true
|
||||
|
||||
# instagram:
|
||||
# disabled: false
|
||||
# simple: true
|
||||
|
||||
# youtube:
|
||||
# disabled: false
|
||||
# privacyEnhanced: true
|
||||
|
||||
services:
|
||||
instagram:
|
||||
disableInlineCSS: true
|
||||
twitter:
|
||||
disableInlineCSS: true
|
||||
|
||||
@@ -29,7 +29,7 @@ link to a text file containing my full public key is attached.
|
||||
|
||||
`70A4 AA02 555D BD55 9189 B4E0 F32B E05E ADAA 54FC`[^2]
|
||||
|
||||
{{< sub >}}[**Public Key**](/static/pubkey.txt){{< /sub >}}
|
||||
[**Public Key**](/static/pubkey.txt)
|
||||
</center>
|
||||
|
||||
## Donations
|
||||
|
||||
6
content/archives.md
Normal file
6
content/archives.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "Archive"
|
||||
layout: "archives"
|
||||
# url: "/archives"
|
||||
summary: "archives"
|
||||
---
|
||||
@@ -4,8 +4,8 @@ date: 2019-01-16
|
||||
lastmod: 2019-02-11
|
||||
categories: ["Blog"]
|
||||
tags: ["photography"]
|
||||
images:
|
||||
- "/static/img/aperture-study/f17-f40-comp.jpg"
|
||||
cover:
|
||||
image: /static/img/aperture-study/f17-f40-comp.jpg
|
||||
---
|
||||
I found out recently that using the maximum aperture for a lens can have
|
||||
deminishing returns. Simply put: it makes the image look "soft", or otherwise
|
||||
|
||||
@@ -27,16 +27,12 @@ better understanding of the tools and methods used.
|
||||
|
||||
## Partitioning with `fdisk`
|
||||
|
||||
{{% admonition warning Warning %}}
|
||||
This operation will destroy any data on the device, please ensure to back up
|
||||
any data desired prior to this operation!
|
||||
{{% /admonition %}}
|
||||
|
||||
{{% admonition info Info %}}
|
||||
Replace instances of `/dev/sdN` with your actual device name (e.g. `/dev/sda`).
|
||||
References specific to partitions will be stated as such (e.g. `/dev/sdN1`,
|
||||
`/dev/sdN2`)
|
||||
{{% /admonition %}}
|
||||
|
||||
1. Remove any existing partitions on the drive:
|
||||
|
||||
|
||||
120
content/post/boot-partition-initramfs-bloat.md
Normal file
120
content/post/boot-partition-initramfs-bloat.md
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: "The Case of the Bloated Boot"
|
||||
date: 2025-09-22
|
||||
lastmod: 2025-09-22
|
||||
categories: ["Blog"]
|
||||
tags: ["linux"]
|
||||
---
|
||||
When `sudo mkinitcpio -P` fails because your boot partition is full, you've got
|
||||
a fun problem. The culprit? That massive fallback initramfs taking up precious
|
||||
space on a tiny boot partition.
|
||||
|
||||
<!--more-->
|
||||
|
||||
# The Problem
|
||||
|
||||
Picture this: you're dual-booting Linux and running a system update when
|
||||
suddenly `mkinitcpio` fails to generate the larger fallback image. Your boot
|
||||
partition is completely stuffed.
|
||||
|
||||
```bash
|
||||
$ df -h /boot
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/nvme0n1p1 256M 256M 0 100% /boot
|
||||
```
|
||||
|
||||
**Yikes.** Time to investigate what's eating all that space.
|
||||
|
||||
# Damage Assessment
|
||||
|
||||
A quick `du -sh` reveals the usual suspects:
|
||||
|
||||
```bash
|
||||
$ du -sh /boot/*
|
||||
157M /boot/initramfs-linux-fallback.img
|
||||
52M /boot/initramfs-linux.img
|
||||
16M /boot/vmlinuz-linux
|
||||
30M /boot/EFI
|
||||
```
|
||||
|
||||
The fallback initramfs is **three times larger** than the normal one. But why?
|
||||
|
||||
# The Autodetect Mystery
|
||||
|
||||
The secret lies in one simple flag in `/etc/mkinitcpio.d/linux.preset`:
|
||||
|
||||
```bash
|
||||
fallback_options="-S autodetect"
|
||||
```
|
||||
|
||||
That `-S autodetect` flag skips the autodetect hook, which normally shrinks your
|
||||
initramfs by only including modules your hardware actually needs. Without it,
|
||||
mkinitcpio includes **everything**.
|
||||
|
||||
## By the Numbers
|
||||
|
||||
Here's what that means in practice for me:
|
||||
|
||||
| Component | Normal (with autodetect) | Fallback (no autodetect) | Ratio |
|
||||
| :----------------- | -----------------------: | -----------------------: | ------: |
|
||||
| **Kernel modules** | 190 modules | 6,319 modules | **33x** |
|
||||
| **Firmware files** | 711 files | 2,996 files | **4x** |
|
||||
| **Total size** | 52M | 157M | **3x** |
|
||||
|
||||
The fallback image is essentially a universal boot disk that works on _any_
|
||||
hardware — your laptop, your friend's desktop, that ancient server in the
|
||||
closet. It includes drivers for RAID controllers you don't have, network cards
|
||||
from 2003, and GPU firmware for every generation of graphics hardware.
|
||||
|
||||
# The Nuclear Option
|
||||
|
||||
Since I never use the fallback image anyway (live USB for rescue), the
|
||||
solution was just to get rid of this:
|
||||
|
||||
1. **Remove the fallback image** to free immediate space:
|
||||
```bash
|
||||
sudo rm /boot/initramfs-linux-fallback.img
|
||||
```
|
||||
|
||||
2. **Disable future generation** by editing `/etc/mkinitcpio.d/linux.preset`:
|
||||
```bash
|
||||
# Change this line:
|
||||
PRESETS=('default' 'fallback')
|
||||
# To this:
|
||||
PRESETS=('default')
|
||||
```
|
||||
|
||||
3. **Test it works**:
|
||||
```bash
|
||||
sudo mkinitcpio -P
|
||||
```
|
||||
|
||||
Result: boot partition goes from 100% to 39% usage, and future kernel updates
|
||||
won't recreate the bloated fallback.
|
||||
|
||||
# Why It Matters
|
||||
|
||||
The autodetect hook is actually quite clever. On my system with 443MB of total
|
||||
kernel modules available, it correctly identified that I only need 190 of them
|
||||
— things like my specific WiFi driver, filesystem modules for ext4 and LVM, and
|
||||
encryption support for LUKS.
|
||||
|
||||
The fallback includes _everything else too_: drivers for hardware I'll never own
|
||||
(_especially since this is on a laptop_), filesystem support for formats I'll
|
||||
never use, and network protocols from the dawn of time. It's the digital
|
||||
equivalent of packing for a trip by bringing your entire garage of tools "just
|
||||
in case"
|
||||
|
||||
# The Takeaway
|
||||
|
||||
Unless you're regularly swapping hardware or need guaranteed boot recovery from
|
||||
the initramfs itself, the fallback image is dead weight. Modern autodetection
|
||||
works well enough that most people never need it. I've personnally never, ever
|
||||
used the fallback image and for the context of this laptop probably never will
|
||||
as a bootable USB is my go-to for any and all boot issues.
|
||||
|
||||
For those tight boot partitions in dual-boot setups, disabling fallback
|
||||
generation is it. Save the space for kernel updates that actually matter :^)
|
||||
|
||||
And if you _do_ need recovery? Well, that's what live USBs are for, but you're
|
||||
welcome to make your own decisions.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Sharing Same Bluetooth device on Windows/Linux dual-boot"
|
||||
title: "Sharing same Bluetooth device on Windows/Linux dual-boot"
|
||||
date: 2023-10-14
|
||||
lastmod: 2023-10-14
|
||||
lastmod: 2025-12-21
|
||||
categories: ["Tutorial"]
|
||||
tags: ["linux","windows","bluetooth"]
|
||||
contentCopyright: true
|
||||
@@ -9,16 +9,107 @@ hideHeaderAndFooter: false
|
||||
---
|
||||
This is a guide written on how to share the same Bluetooth device(s) across Windows and Linux without having to uniquely pair each.
|
||||
<!--more-->
|
||||
## Steps
|
||||
|
||||
## Method 1: Extract Keys from Linux (Recommended)
|
||||
|
||||
This method uses `hivexsh` to read the Windows registry directly from Linux without needing to boot into Windows.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Install hivex:
|
||||
|
||||
```bash
|
||||
# Arch Linux
|
||||
sudo pacman -S hivex
|
||||
|
||||
# Debian/Ubuntu
|
||||
sudo apt install libhivex-bin
|
||||
|
||||
# Fedora
|
||||
sudo dnf install hivex
|
||||
```
|
||||
|
||||
### Steps
|
||||
|
||||
1. Pair your Bluetooth device(s) with Linux **first**
|
||||
2. Reboot into Windows, then re-pair the devices with Windows
|
||||
3. Reboot back to Linux
|
||||
4. Mount your Windows partition (if not already mounted):
|
||||
|
||||
```bash
|
||||
sudo mount /dev/sdXN /mnt/windows
|
||||
```
|
||||
|
||||
5. Find your Bluetooth adapter MAC address and paired devices:
|
||||
|
||||
```bash
|
||||
ls /var/lib/bluetooth/
|
||||
# Example output: 24:EB:16:23:5B:94
|
||||
|
||||
ls /var/lib/bluetooth/24:EB:16:23:5B:94/
|
||||
# Example output: EC:66:D1:B1:9A:33 (your device)
|
||||
```
|
||||
|
||||
6. Use `hivexsh` to extract the pairing key from the Windows registry:
|
||||
|
||||
```bash
|
||||
hivexsh /mnt/windows/Windows/System32/config/SYSTEM
|
||||
```
|
||||
|
||||
7. Navigate to the Bluetooth keys (MAC addresses are lowercase, no colons):
|
||||
|
||||
```text
|
||||
cd ControlSet001\Services\BTHPORT\Parameters\Keys
|
||||
ls
|
||||
cd 24eb16235b94
|
||||
lsval
|
||||
```
|
||||
|
||||
Example output:
|
||||
```text
|
||||
"ec66d1b19a33"=hex(3):1d,68,ef,88,a8,fa,60,2e,a3,1c,69,2e,61,a4,36,4f
|
||||
```
|
||||
|
||||
8. Convert the key to Linux format (remove commas, uppercase):
|
||||
|
||||
```text
|
||||
1d,68,ef,88,a8,fa,60,2e,a3,1c,69,2e,61,a4,36,4f
|
||||
→ 1D68EF88A8FA602EA31C692E61A4364F
|
||||
```
|
||||
|
||||
9. Update the Linux Bluetooth info file:
|
||||
|
||||
```bash
|
||||
sudo nano /var/lib/bluetooth/24:EB:16:23:5B:94/EC:66:D1:B1:9A:33/info
|
||||
```
|
||||
|
||||
Replace the `Key=` value under `[LinkKey]` with the converted key.
|
||||
|
||||
10. Restart the Bluetooth service:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart bluetooth
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 2: Export Keys from Windows
|
||||
|
||||
This method requires exporting the registry keys while booted into Windows.
|
||||
|
||||
### Steps
|
||||
|
||||
1. Pair your Bluetooth device(s) with Linux **first**
|
||||
2. Reboot into Windows, then re-pair the devices with Windows
|
||||
3. Run `regedit` **as Administrator**
|
||||
4. Navigate to:
|
||||
```
|
||||
|
||||
```text
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys
|
||||
```
|
||||
|
||||
If you **do not see any Keys under the tree** then you need to open `regedit` as a system-account user. One way to do this is using the PsExec by [downloading it from Microsoft Sysinternals](https://learn.microsoft.com/en-us/sysinternals/downloads/psexec). Once it is downloaded, you will need to run a command-prompt **as Administrator** and navigate to the location `PsExec` is unzipped and run `PsExec.exe -s -i regedit`. The Bluetooth keys should now be visible.
|
||||
|
||||
5. Right-click on `Keys` in the left-hand pane and select `Export`. During the dialog change `Save as type` to `Text files` and that the `Export range` is set to `Selected branch`. Store this somewhere **accessible by both Windows and Linux** -- if a shared drive is unavailable, use a USB drive or cloud-storage.
|
||||
6. Reboot to Linux
|
||||
7. In a root (e.g. `sudo su`) terminal navigate to `/var/lib/bluetooth` then to the MAC address of your host-system (_there should only be a single sub-directory under `/var/lib/bluetooth`_)
|
||||
@@ -26,10 +117,17 @@ This is a guide written on how to share the same Bluetooth device(s) across Wind
|
||||
9. Open the `info` file, with root privileges, in the text editor of your choice.
|
||||
10. In another tab/window, using either a text viewer or editor, open the **previously exported Windows registry text file for the device**
|
||||
11. From the **Windows** file, copy the Bluetooth Key. Example:
|
||||
```
|
||||
|
||||
```text
|
||||
00000000 31 c0 08 fa 4f 7b d2 4c - 6f e1 7d ba 32 29 a9 a7 1À.ïO{ÒLoá}ºQ)©§
|
||||
```
|
||||
|
||||
_From the above copy `31 c0 .... a9 a7`_
|
||||
|
||||
12. Paste the key from the previous step into the `Key=` portion of the **Linux** Bluetooth `info` file. Make sure to **remove all spaces and change all characters to upper-case (all-caps)**.
|
||||
12. Paste the key from the previous step into the `Key=` portion of the **Linux** Bluetooth `info` file. Make sure to **remove all spaces, hyphens, and change all characters to upper-case (all-caps)**.
|
||||
13. Save the `info` file with the changes to complete device sharing. Repeat for any other Bluetooth devices to share.
|
||||
14. Restart the Bluetooth service:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart bluetooth
|
||||
```
|
||||
|
||||
@@ -6,8 +6,8 @@ tags: ["emacs", "linux"]
|
||||
categories: ["Tutorial"]
|
||||
contentCopyright: true
|
||||
hideHeaderAndFooter: false
|
||||
images:
|
||||
- "/static/img/emacs-clang-libopencm3/header-completion.png"
|
||||
cover:
|
||||
image: /static/img/emacs-clang-libopencm3/header-completion.png
|
||||
---
|
||||
With some minor dependencies, it's fairly straightforward in setting up your
|
||||
Emacs workflow to include IntelliSense-like auto-completion!
|
||||
@@ -114,13 +114,11 @@ The above assumes that `libopencm3` is also places within the project
|
||||
directory
|
||||
{{< /sub >}}
|
||||
|
||||
{{< admonition warning Note >}}
|
||||
There is a strange issue that is encountered with non-working completion for new
|
||||
header include statements. The workaround for this includes running `M-x irony-server-kill`after new header
|
||||
additions to your current working file. Irony's server is clever enough to
|
||||
restart itself after a completion request is triggered via `TAB` so this is a
|
||||
fairly uninvolved workaround.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -92,43 +92,34 @@ this via:
|
||||
- **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
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ date: 2018-01-11
|
||||
lastmod: 2019-01-16
|
||||
categories: ["Blog"]
|
||||
tags: ["electronics"]
|
||||
images:
|
||||
- "/static/img/headphone-fix/IMG_7505.jpg"
|
||||
cover:
|
||||
image: /static/img/headphone-fix/IMG_7505.jpg
|
||||
---
|
||||
A colleague offered a pair of Bern Bluetooth drop-in headphones to me fore free,
|
||||
with the catch being: _I had to fix them_
|
||||
@@ -19,7 +19,7 @@ with the catch being: _I had to fix them_
|
||||
|
||||
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
|
||||
side, I figured the only way _in_ was lifting the mesh cover off. So I went at
|
||||
it, carefully, with a pair of tweezers. I worked my way around the edge and
|
||||
wedged the mesh upwards.
|
||||
|
||||
@@ -60,7 +60,7 @@ search of `AIWI TI` (_as shown in the photograph_) resulted
|
||||
in [the following datasheet](http://www.ti.com/lit/ds/symlink/tpa6132a2.pdf)
|
||||
which verified that to be the case.
|
||||
|
||||
<center></center>
|
||||

|
||||
|
||||
**Bingo!** Now knowing the pinout, I could use my trusty multimeter (_a Fluke
|
||||
115_) to test continuity of the circuit from the known-good and the now
|
||||
|
||||
@@ -14,11 +14,9 @@ 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
|
||||
my [GitLab](https://gitlab.com/bdebyl) profile.
|
||||
{{< /admonition >}}
|
||||
|
||||
---
|
||||
|
||||
|
||||
293
content/post/kde-plasma-performance.md
Normal file
293
content/post/kde-plasma-performance.md
Normal file
@@ -0,0 +1,293 @@
|
||||
---
|
||||
title: "Taming the KDE Plasma Beast: Desktop Responsiveness on Arch Linux"
|
||||
date: 2026-01-04
|
||||
lastmod: 2026-01-04
|
||||
categories: ["Blog"]
|
||||
tags: ["linux", "kde", "performance"]
|
||||
---
|
||||
When your beefy Ryzen 9 system locks up during a simple `pacman -Syu`, something
|
||||
is very wrong. Here's how to stop Baloo, ClamAV, and poor IO scheduling from
|
||||
hijacking your desktop.
|
||||
|
||||
<!--more-->
|
||||
|
||||
# The Problem
|
||||
|
||||
Picture this: you're running system updates on a Ryzen 9 7945HX3D with 62GB of
|
||||
RAM and dual NVMe drives. DKMS starts compiling the nvidia module and suddenly
|
||||
your entire desktop freezes. Mouse cursor? Frozen. Keyboard? Unresponsive. The
|
||||
only option is reaching for the power button.
|
||||
|
||||
**This should not happen.** A modern system with this kind of hardware should
|
||||
handle background compilation without breaking a sweat. Time to investigate.
|
||||
|
||||
# The Culprits
|
||||
|
||||
After some digging, three major offenders emerged:
|
||||
|
||||
## 1. Baloo File Indexer
|
||||
|
||||
KDE's file indexer was the worst offender:
|
||||
|
||||
```bash
|
||||
$ balooctl6 status
|
||||
Total files indexed: 845,512
|
||||
Files waiting for content indexing: 103,138
|
||||
Current size of index is 24.27 GiB
|
||||
```
|
||||
|
||||
**Twenty-five gigabytes** of index data, with over 100,000 files still queued.
|
||||
Worse, checking mounted filesystems revealed the real problem:
|
||||
|
||||
```bash
|
||||
$ mount | grep cifs
|
||||
//truenas.localdomain/share on /mnt/share type cifs ...
|
||||
```
|
||||
|
||||
Baloo was trying to index a network share. Every file access over the network
|
||||
was blocking IO and competing with the desktop for resources. Classic.
|
||||
|
||||
## 2. ClamAV Daemon
|
||||
|
||||
The antivirus daemon was consuming 1.2GB of RAM just sitting there:
|
||||
|
||||
```bash
|
||||
$ systemctl status clamav-daemon
|
||||
Memory: 1.2G (peak: 2.1G)
|
||||
```
|
||||
|
||||
On Linux, ClamAV is honestly overkill for a desktop system. It's designed for
|
||||
mail servers and file shares, not personal workstations where you control what
|
||||
gets executed.
|
||||
|
||||
## 3. Wrong IO Scheduler
|
||||
|
||||
Both NVMe drives were using the BFQ scheduler:
|
||||
|
||||
```bash
|
||||
$ cat /sys/block/nvme*/queue/scheduler
|
||||
[bfq]
|
||||
[bfq]
|
||||
```
|
||||
|
||||
BFQ is great for HDDs and SATA SSDs where the kernel needs to optimize head
|
||||
movement and queue depth. NVMe drives have their own hardware schedulers with
|
||||
massive parallel queue support. Adding kernel-level scheduling just creates
|
||||
overhead.
|
||||
|
||||
# The Fixes
|
||||
|
||||
## Step 1: Kill Baloo
|
||||
|
||||
If you don't use KDE's file search (and let's be honest, most terminal users
|
||||
don't), just disable it:
|
||||
|
||||
```bash
|
||||
# Disable the indexer
|
||||
balooctl6 disable
|
||||
|
||||
# Delete the bloated database
|
||||
rm -rf ~/.local/share/baloo
|
||||
```
|
||||
|
||||
The config file at `~/.config/baloofilerc` will now show:
|
||||
|
||||
```ini
|
||||
[Basic Settings]
|
||||
Indexing-Enabled=false
|
||||
```
|
||||
|
||||
This persists across reboots. Done.
|
||||
|
||||
## Step 2: Remove or Throttle ClamAV
|
||||
|
||||
> **Security Consideration:** Removing antivirus software is a trade-off
|
||||
> between performance and security. While Linux desktops are less targeted than
|
||||
> Windows, threats do exist — especially if you download software from untrusted
|
||||
> sources, open email attachments, or share files with Windows users. **Proceed
|
||||
> at your own risk.**
|
||||
|
||||
For a personal desktop where you're not scanning incoming mail or shared files,
|
||||
you have a few options:
|
||||
|
||||
### Option A: Remove ClamAV entirely (at your own risk)
|
||||
|
||||
```bash
|
||||
sudo systemctl disable --now clamav-daemon clamav-freshclam
|
||||
sudo pacman -Rns clamav
|
||||
```
|
||||
|
||||
### Option B: Keep ClamAV but throttle it
|
||||
|
||||
If you want to keep real-time protection but prevent it from impacting system
|
||||
responsiveness, create a systemd override:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /etc/systemd/system/clamav-daemon.service.d
|
||||
sudo tee /etc/systemd/system/clamav-daemon.service.d/override.conf << 'EOF'
|
||||
[Service]
|
||||
Nice=19
|
||||
IOSchedulingClass=idle
|
||||
IOSchedulingPriority=7
|
||||
CPUSchedulingPolicy=idle
|
||||
CPUQuota=30%
|
||||
MemoryMax=1G
|
||||
EOF
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart clamav-daemon
|
||||
```
|
||||
|
||||
This forces ClamAV to only use idle CPU/IO time and caps its resource usage.
|
||||
|
||||
### Option C: Manual scans only
|
||||
|
||||
Disable the daemon but keep the package for on-demand scanning:
|
||||
|
||||
```bash
|
||||
sudo systemctl disable --now clamav-daemon clamav-freshclam
|
||||
# Scan manually when needed:
|
||||
# clamscan -r /path/to/scan
|
||||
```
|
||||
|
||||
### Alternatives to ClamAV
|
||||
|
||||
If you remove ClamAV, consider these complementary security measures:
|
||||
|
||||
- **[Firejail](https://wiki.archlinux.org/title/Firejail)** — Sandbox untrusted
|
||||
applications with minimal effort
|
||||
- **[AppArmor](https://wiki.archlinux.org/title/AppArmor)** — Mandatory access
|
||||
control for limiting application capabilities
|
||||
- **[USBGuard](https://wiki.archlinux.org/title/USBGuard)** — Protect against
|
||||
rogue USB devices
|
||||
- **Common sense** — Don't run random binaries from the internet, verify
|
||||
checksums, use official repositories
|
||||
|
||||
For most Linux desktop users who stick to official repos and don't open
|
||||
suspicious attachments, the risk is manageable. But if you're handling sensitive
|
||||
data or files from untrusted sources, keep some form of scanning available.
|
||||
|
||||
## Step 3: Fix the IO Scheduler
|
||||
|
||||
Create a udev rule to set the correct scheduler per drive type:
|
||||
|
||||
```bash
|
||||
sudo tee /etc/udev/rules.d/60-ioschedulers.rules << 'EOF'
|
||||
# NVMe drives have hardware schedulers - use none
|
||||
ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/scheduler}="none"
|
||||
# HDDs benefit from BFQ
|
||||
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
|
||||
# SATA SSDs - none is fine
|
||||
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
|
||||
EOF
|
||||
|
||||
# Apply immediately
|
||||
echo none | sudo tee /sys/block/nvme*/queue/scheduler
|
||||
```
|
||||
|
||||
## Step 4: Install ananicy-cpp
|
||||
|
||||
This is the real game-changer. [Ananicy-cpp](https://gitlab.com/ananicy-cpp/ananicy-cpp)
|
||||
automatically adjusts process priorities based on what's running:
|
||||
|
||||
```bash
|
||||
sudo pacman -S ananicy-cpp
|
||||
yay -S cachyos-ananicy-rules-git # Community rules
|
||||
sudo systemctl enable --now ananicy-cpp
|
||||
```
|
||||
|
||||
Now add custom rules for package management and compilation:
|
||||
|
||||
```bash
|
||||
sudo tee /etc/ananicy.d/package-managers.rules << 'EOF'
|
||||
# Package managers and compilers - lowest priority
|
||||
{"name": "pacman", "type": "BG_CPUIO"}
|
||||
{"name": "yay", "type": "BG_CPUIO"}
|
||||
{"name": "makepkg", "type": "BG_CPUIO"}
|
||||
{"name": "dkms", "type": "BG_CPUIO"}
|
||||
{"name": "mkinitcpio", "type": "BG_CPUIO"}
|
||||
{"name": "gcc", "type": "BG_CPUIO"}
|
||||
{"name": "cc1", "type": "BG_CPUIO"}
|
||||
{"name": "cc1plus", "type": "BG_CPUIO"}
|
||||
{"name": "rustc", "type": "BG_CPUIO"}
|
||||
{"name": "cargo", "type": "BG_CPUIO"}
|
||||
{"name": "ninja", "type": "BG_CPUIO"}
|
||||
{"name": "make", "type": "BG_CPUIO"}
|
||||
EOF
|
||||
```
|
||||
|
||||
The `BG_CPUIO` type sets `nice=16`, `ioclass=idle`, and `sched=idle`. These
|
||||
processes will only get CPU and disk time when nothing else needs it.
|
||||
|
||||
## Step 5: Tune VM Dirty Page Handling
|
||||
|
||||
The kernel's default dirty page settings are tuned for servers, not desktops.
|
||||
With 62GB of RAM, the defaults would allow gigabytes of dirty pages to
|
||||
accumulate before flushing — causing massive IO storms that freeze everything.
|
||||
|
||||
```bash
|
||||
sudo tee /etc/sysctl.d/99-desktop-responsiveness.conf << 'EOF'
|
||||
# Use absolute byte limits instead of percentages
|
||||
vm.dirty_ratio = 0
|
||||
vm.dirty_background_ratio = 0
|
||||
|
||||
# Start background writeback at 256MB
|
||||
vm.dirty_background_bytes = 268435456
|
||||
# Force sync at 1GB max
|
||||
vm.dirty_bytes = 1073741824
|
||||
|
||||
# Flush dirty pages faster
|
||||
vm.dirty_expire_centisecs = 1000
|
||||
vm.dirty_writeback_centisecs = 100
|
||||
|
||||
# Keep 256MB always free
|
||||
vm.min_free_kbytes = 262144
|
||||
|
||||
# Desktop-friendly swappiness
|
||||
vm.swappiness = 10
|
||||
vm.vfs_cache_pressure = 50
|
||||
EOF
|
||||
|
||||
sudo sysctl --system
|
||||
```
|
||||
|
||||
# The Results
|
||||
|
||||
| Before | After |
|
||||
|:-------|:------|
|
||||
| System freezes during updates | Desktop stays responsive |
|
||||
| 25GB Baloo database | 0 bytes |
|
||||
| 1.2GB ClamAV RAM usage | 0 bytes |
|
||||
| BFQ overhead on NVMe | Direct hardware scheduling |
|
||||
| Compilation starves desktop | Compilation yields to UI |
|
||||
|
||||
DKMS can now compile nvidia modules while I continue working. Package updates
|
||||
run in the background without the mouse cursor freezing. The system finally
|
||||
behaves like it should on modern hardware.
|
||||
|
||||
# Diagnostic Commands
|
||||
|
||||
When things go wrong, these help identify the culprit:
|
||||
|
||||
```bash
|
||||
# What's causing IO wait?
|
||||
iotop -oPa
|
||||
|
||||
# System IO-bound?
|
||||
vmstat 1 5
|
||||
|
||||
# Processes stuck in disk wait (D state)?
|
||||
ps auxf | grep " D "
|
||||
|
||||
# Current dirty page status
|
||||
grep -E "^(Dirty|Writeback):" /proc/meminfo
|
||||
```
|
||||
|
||||
# The Takeaway
|
||||
|
||||
A powerful system shouldn't freeze during routine operations. The defaults in
|
||||
most Linux distributions are tuned for servers or general compatibility, not
|
||||
desktop responsiveness. A few targeted tweaks — killing unnecessary indexers,
|
||||
fixing IO schedulers, and prioritizing interactive processes — make all the
|
||||
difference.
|
||||
|
||||
No more hard resets during system updates :^)
|
||||
@@ -1,154 +0,0 @@
|
||||
---
|
||||
title: "Installing LineageOS Unofficial on Pixel 3a"
|
||||
date: 2020-07-13
|
||||
lastmod: 2020-07-13
|
||||
draft: false
|
||||
tags: ["android", "security", "hacking"]
|
||||
categories: ["Tutorial"]
|
||||
contentCopyright: true
|
||||
hideHeaderAndFooter: false
|
||||
images:
|
||||
- "/static/img/lineageos-pixel3a/lineage-settings.png"
|
||||
---
|
||||
{{< admonition warning "Out of Date" >}}
|
||||
This guide is now out of date since LineageOS officially supports the Pixel 3a,
|
||||
see more here: <https://wiki.lineageos.org/devices/sargo/install>
|
||||
{{< /admonition >}}
|
||||
|
||||
In this post I aim to highlight my findings in deciding to go through the
|
||||
process of installing LineageOS on my Pixel 3a. Currently, LineageOS does not
|
||||
officially support the Pixel 3a. However, InvisibleK (Dan Pasanen) does host
|
||||
updated versions of his unofficial LineageOS build for the Pixel 3a complete
|
||||
with a custom recovery to utilize for this purpose!
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< thumbgallery >}}
|
||||
{{< thumb src="/static/img/lineageos-pixel3a/lineage-settings.png"
|
||||
alt="Screenshot showing the LineageOS version and other LineageOS settings on the Pixel 3a" >}}
|
||||
{{< thumb src="/static/img/lineageos-pixel3a/lineage-trust.png"
|
||||
alt="Screenshot showing the LineageOS Trust feature" >}}
|
||||
{{< /thumbgallery >}}
|
||||
|
||||
# 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
|
||||
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
|
||||
you may have to find resources on how to go about this. I do not intend to go
|
||||
over this here -- _sorry_
|
||||
|
||||
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>
|
||||
|
||||
# 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
|
||||
your device! Stop now and back up any files, 2FA codes, or other prior to
|
||||
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>
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
1. Unlock the bootloader if the 'Status' is locked:
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
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/)
|
||||
@@ -67,10 +67,8 @@ It may be worth mentioning, to folks less familiar with `awk`, that the
|
||||
being piped into `sha1sum`. I discovered incorrect `sha1sum` outputs **without**
|
||||
`FNR==1` resulting in a useless password check!
|
||||
|
||||
{{< admonition note Note >}}
|
||||
`IFS=` would not have fixed the above newline issue, as the problem stems
|
||||
from the output of `pass "$p"` and **not** the filenames.
|
||||
{{< /admonition >}}
|
||||
|
||||
That takes care of gathering our passwords, but we'll revisit this again in the
|
||||
next part.
|
||||
@@ -106,7 +104,7 @@ getpws()
|
||||
}
|
||||
```
|
||||
|
||||
This accomplishes our *first goal* of checking duplicate passwords --
|
||||
This accomplishes our _first goal_ of checking duplicate passwords --
|
||||
**hooray!**
|
||||
|
||||
# Passwortstärke
|
||||
@@ -117,10 +115,9 @@ it's weak (_i.e. "Exists in attack dictionary", "Too short", etc._) was to use
|
||||
well-documented or fully-fledged application to fully determine password
|
||||
strength though for my purposes it will be good enough (_I don't care to write
|
||||
my own version of this, yet.._).
|
||||
{{< admonition note Note >}}
|
||||
|
||||
I made this part of the script **optional**, as not every user would want to
|
||||
install `cracklib` on their system.
|
||||
{{< /admonition >}}
|
||||
|
||||
This addition was made in the following order:
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ tags: ["libopencm3", "stm32", "tutorial"]
|
||||
categories: ["Tutorial"]
|
||||
contentCopyright: true
|
||||
hideHeaderAndFooter: false
|
||||
images:
|
||||
- "/static/img/stm32-examples/part0/stm32-basic-gpio-leds.jpeg"
|
||||
cover:
|
||||
image: /static/img/stm32-examples/part0/stm32-basic-gpio-leds.jpeg
|
||||
---
|
||||
One of the simplest projects to get started with the STM32 microcontroller
|
||||
series: turn on the lights!
|
||||
@@ -17,21 +17,12 @@ series: turn on the lights!
|
||||
{{< thumb src="/static/img/stm32-examples/part0/stm32-basic-gpio-leds.jpeg"
|
||||
alt="Photo of STM32 discovery board with illuminated green and blue LEDs" >}}
|
||||
|
||||
{{< admonition warning "Windows Users" >}}
|
||||
This series of write-ups assumes the reader is on a Linux operating
|
||||
system. Windows users _can_ utilize the [**Windows Subsystems for
|
||||
Linux**](https://docs.microsoft.com/en-us/windows/wsl/install-win10) though your
|
||||
mileage may vary!
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
# Straight to the Chase
|
||||
|
||||
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>
|
||||
@@ -50,8 +41,6 @@ int main(void) {
|
||||
}
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
# Getting Started with libopencm3
|
||||
|
||||
[libopencm3](https://github.com/libopencm3/libopencm3) is a very powerful,
|
||||
@@ -127,11 +116,9 @@ Makefile's variables of things you may want to change:
|
||||
|
||||
# Explanation
|
||||
|
||||
{{< admonition info "Naming Convention" >}}
|
||||
As a note to the reader: below I will not refer to the GPIO port or pins using
|
||||
the `#define` friendly names from above. This is purely for the sake
|
||||
of clarity in hopes of avoiding confusion.
|
||||
{{< /admonition >}}
|
||||
|
||||
Although the source code is fairly simple, lets dive into it at least
|
||||
_somewhat_.
|
||||
|
||||
@@ -6,8 +6,8 @@ tags: ["libopencm3", "stm32", "tutorial"]
|
||||
categories: ["Tutorial"]
|
||||
contentCopyright: true
|
||||
hideHeaderAndFooter: false
|
||||
images:
|
||||
- "/static/img/stm32-examples/part1/blinky.gif"
|
||||
cover:
|
||||
image: /static/img/stm32-examples/part1/blinky.gif
|
||||
---
|
||||
After having reviewed [**Part 0**](/post/stm32-part0) of this series, we can now
|
||||
explore controlling GPIO with the hardware timers! Other tutorials have used the
|
||||
@@ -26,8 +26,6 @@ timers and their associated GPIO ports with Alternate Function modes.
|
||||
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>
|
||||
@@ -79,8 +77,6 @@ int main(void) {
|
||||
}
|
||||
```
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
# Set up the GPIO
|
||||
|
||||
Assuming the reader is either familiar with GPIO setup for the STM32F0, or has
|
||||
@@ -107,10 +103,8 @@ For accomplishing this, a few things need to happen:
|
||||
1. The desired GPIO pins need to be set to `GPIO_MODE_AF` in `gpio_mode_setup()`
|
||||
1. The alternate function mode number `GPIO_AFx` has to be set for the pins using `gpio_set_af()`
|
||||
|
||||
{{< admonition warning "Note for Different STM32Fx Microcontrollers" >}}
|
||||
Review the datasheet for the specific **STM32Fx** microcontroller being
|
||||
programmed, as the Alternate Function mappings may be *significantly* different!
|
||||
{{< /admonition >}}
|
||||
programmed, as the Alternate Function mappings may be _significantly_ different!
|
||||
|
||||
## GPIO Alternate Function Setup
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ date: 2019-02-28
|
||||
lastmod: 2019-02-28
|
||||
categories: ["Blog"]
|
||||
tags: ["electronics"]
|
||||
images:
|
||||
- "/static/img/thinkpad-usb-fix/DSC04781.jpg"
|
||||
cover:
|
||||
image: /static/img/thinkpad-usb-fix/DSC04781.jpg
|
||||
---
|
||||
From the moment that I first had my (_used_) ThinkPad X220, the bottom-right USB
|
||||
port nearest to the SD card reader had been broken. The pad (_or bolster_) was
|
||||
|
||||
@@ -13,10 +13,8 @@ is done!
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< admonition info Info >}}
|
||||
If the reader is unfamiliar with OpenPGP, it's suggested to check out the prior
|
||||
write-up on this blog: [**OpenPGP Best Practices (and Git)**](/post/gpg_best_practices_and_git/)
|
||||
{{< /admonition >}}
|
||||
|
||||
# Importing Secret Keys
|
||||
|
||||
@@ -229,4 +227,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/
|
||||
[^1]: [guardianproject.info/archive/luks/](https://guardianproject.info/archive/luks/)
|
||||
|
||||
112
content/post/yoga6-fingerprint-arch.md
Normal file
112
content/post/yoga6-fingerprint-arch.md
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "Fingerprint Support on Lenovo Yoga 6 with Arch Linux"
|
||||
date: 2025-09-23
|
||||
lastmod: 2025-09-23
|
||||
categories: ["Blog"]
|
||||
tags: ["linux", "archlinux", "hardware"]
|
||||
---
|
||||
Got a Lenovo Yoga 6 2-in-1 and frustrated that your fingerprint reader isn't working on Arch Linux? You're not alone. The standard fprintd package doesn't include the necessary firmware for this laptop's Synaptics sensor.
|
||||
|
||||
<!--more-->
|
||||
|
||||
# The Problem
|
||||
|
||||
The Lenovo Yoga 6 2-in-1 laptop comes with a Synaptics fingerprint sensor that requires proprietary firmware not included in the standard fprintd package. Without this firmware, fprintd can't communicate with the sensor, leaving you with a non-functional fingerprint reader.
|
||||
|
||||
# The Solution
|
||||
|
||||
The AUR package `libfprint-2-tod1-synatudor-git` provides the necessary Touch-On-Display (TOD) driver and firmware for Synaptics sensors, including the one in the Yoga 6.
|
||||
|
||||
## Installation Steps
|
||||
|
||||
1. **Install the AUR package:**
|
||||
```bash
|
||||
yay -S libfprint-2-tod1-synatudor-git
|
||||
```
|
||||
Or if you're using paru:
|
||||
```bash
|
||||
paru -S libfprint-2-tod1-synatudor-git
|
||||
```
|
||||
|
||||
2. **Install fprintd (if not already installed):**
|
||||
```bash
|
||||
sudo pacman -S fprintd
|
||||
```
|
||||
|
||||
3. **Enable and start the fprintd service:**
|
||||
```bash
|
||||
sudo systemctl enable --now fprintd.service
|
||||
```
|
||||
|
||||
4. **Verify the fingerprint reader is detected:**
|
||||
```bash
|
||||
fprintd-list-devices
|
||||
```
|
||||
|
||||
You should see output listing your Synaptics sensor.
|
||||
|
||||
## Setting Up Fingerprints
|
||||
|
||||
Once the driver is installed and working:
|
||||
|
||||
1. **Enroll your fingerprints:**
|
||||
```bash
|
||||
fprintd-enroll
|
||||
```
|
||||
Follow the prompts to scan your finger multiple times.
|
||||
|
||||
2. **Test authentication:**
|
||||
```bash
|
||||
fprintd-verify
|
||||
```
|
||||
|
||||
## PAM Integration
|
||||
|
||||
To use fingerprint authentication for system login and authentication, add fingerprint support to the appropriate PAM configuration files:
|
||||
|
||||
1. **For system login**, add to `/etc/pam.d/system-local-login`:
|
||||
```
|
||||
auth sufficient pam_fprintd.so
|
||||
```
|
||||
|
||||
2. **For display managers**, the configuration may already exist:
|
||||
- SDDM: `/etc/pam.d/sddm` should have `auth sufficient pam_fprintd.so`
|
||||
- LightDM: `/etc/pam.d/lightdm` should have `auth sufficient pam_fprintd.so`
|
||||
|
||||
3. **For sudo authentication**, add to `/etc/pam.d/sudo`:
|
||||
```
|
||||
auth sufficient pam_fprintd.so
|
||||
```
|
||||
|
||||
The `sufficient` directive means fingerprint authentication will be attempted first, falling back to password if fingerprint fails.
|
||||
|
||||
# Why This Works
|
||||
|
||||
The `libfprint-2-tod1-synatudor-git` package provides:
|
||||
- The proprietary Synaptics firmware blob required by the sensor
|
||||
- The TOD (Touch-On-Display) driver implementation for libfprint2
|
||||
- Proper USB device ID mappings for various Synaptics sensors
|
||||
|
||||
Without this package, fprintd only has access to open-source drivers that don't support the proprietary communication protocol used by many modern fingerprint sensors.
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
If the fingerprint reader still doesn't work:
|
||||
|
||||
1. **Check USB device detection:**
|
||||
```bash
|
||||
lsusb | grep -i synaptics
|
||||
```
|
||||
|
||||
2. **Review fprintd logs:**
|
||||
```bash
|
||||
journalctl -u fprintd -b
|
||||
```
|
||||
|
||||
3. **Ensure secure boot is disabled** - some proprietary firmware doesn't load with secure boot enabled.
|
||||
|
||||
4. **Reboot after installation** - the driver may need a fresh start to properly initialize.
|
||||
|
||||
# Final Notes
|
||||
|
||||
While it's unfortunate that proprietary firmware is required, this AUR package makes fingerprint authentication possible on the Yoga 6 and similar laptops with Synaptics sensors. The convenience of fingerprint login, especially on a 2-in-1 device, is worth the extra installation step.
|
||||
5
content/search.md
Normal file
5
content/search.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "Search"
|
||||
placeholder: Enter text to search..
|
||||
layout: "search"
|
||||
---
|
||||
11
layouts/shortcodes/img.html
Normal file
11
layouts/shortcodes/img.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{{- $src := .Get "src" }}
|
||||
{{- $sub := .Get "sub" -}}
|
||||
{{- $alt := .Get "alt" -}}
|
||||
<div class="thumbnail-container">
|
||||
<a href="{{ $src }}"><div class="thumbnail">
|
||||
<center><img src="{{ $src }}" alt="{{ $alt }}" title="{{ $alt }}"></center>
|
||||
{{- if $sub -}}
|
||||
<sub>{{ $sub }}</sub>
|
||||
{{- end -}}
|
||||
</div></a>
|
||||
</div>
|
||||
1
layouts/shortcodes/sub.html
Normal file
1
layouts/shortcodes/sub.html
Normal file
@@ -0,0 +1 @@
|
||||
<center><sub><i>{{ .Inner | markdownify }}</i></sub></center>
|
||||
15
layouts/shortcodes/thumb.html
Normal file
15
layouts/shortcodes/thumb.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{{- $src := .Get "src" }}
|
||||
{{- $sub := .Get "sub" -}}
|
||||
{{- $alt := .Get "alt" -}}
|
||||
{{ if not .Parent }}
|
||||
<div class="thumbnail-container">
|
||||
{{ end }}
|
||||
<a href="{{ $src }}"><div class="thumbnail">
|
||||
<center><img src="{{ $src | replaceRE "^(.*static/img)/(.*)$" "$1/w_500/$2" }}" alt="{{ $alt }}" title="{{ $alt }}"></center>
|
||||
{{- if $sub -}}
|
||||
<center><sub>{{ $sub }}</sub></center>
|
||||
{{- end -}}
|
||||
</div></a>
|
||||
{{ if not .Parent }}
|
||||
</div>
|
||||
{{ end }}
|
||||
3
layouts/shortcodes/thumbgallery.html
Normal file
3
layouts/shortcodes/thumbgallery.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="thumbnail-gallery">
|
||||
{{.Inner}}
|
||||
</div>
|
||||
1
themes/papermod
Submodule
1
themes/papermod
Submodule
Submodule themes/papermod added at 9f1f414be8
Reference in New Issue
Block a user