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*
|
flymd*
|
||||||
public/
|
public/
|
||||||
resources/
|
resources/
|
||||||
static/
|
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=debyl.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
|
|
||||||
|
|
||||||
HUGO_IMAGE_NAME=bdebyl/hugo
|
AWS=aws --profile default
|
||||||
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}
|
|
||||||
|
|
||||||
# Look up CloudFront distribution ID based on website alias
|
# Look up CloudFront distribution ID based on website alias
|
||||||
DISTRIBUTION_ID=$(shell docker run --rm ${AWS_ENV} ${AWS_IMAGE} cloudfront list-distributions \
|
DISTRIBUTION_ID=$(shell ${AWS} cloudfront list-distributions \
|
||||||
--query 'DistributionList.Items[].{id:Id,a:Aliases.Items}[?contains(a,`${WEB_BUCKET}`)].id' \
|
--query 'DistributionList.Items[].{id:Id,a:Aliases.Items}[?contains(a,`${WEBSITE}`)].id' \
|
||||||
--output text)
|
--output text)
|
||||||
|
S3_SYNC=s3 sync --sse "AES256" public/ s3://${WEBSITE}
|
||||||
|
CLOUDFRONT_INVALIDATE=cloudfront create-invalidation --distribution-id ${DISTRIBUTION_ID} --paths '/*'
|
||||||
|
|
||||||
ifdef DRYRUN
|
# Default target for make (<=3.80)
|
||||||
S3_DRYRUN=--dryrun
|
default:
|
||||||
endif
|
-hugo server
|
||||||
ifdef DELETE
|
.PHONY: default
|
||||||
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
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
$(DOCKER_RUN) ${HUGO_IMAGE}
|
-hugo build
|
||||||
.PHONY: 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:
|
||||||
@# Clean up existing generated site
|
rm -rfv public/
|
||||||
rm -rf public/ resources/
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
static-clean:
|
|
||||||
if [ -d "${STATIC_DIR}/static" ]; then rm -rfv static/
|
|
||||||
.PHONY: static-clean
|
|
||||||
|
|
||||||
deploy: clean build
|
deploy: clean build
|
||||||
@# Upload files to S3
|
@# Upload files to S3
|
||||||
@$(DOCKER_RUN) ${AWS_ENV} ${AWS_IMAGE} ${S3_CMD_WEB}
|
${AWS} ${S3_SYNC}
|
||||||
.PHONY: deploy
|
.PHONY: deploy
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
@# Invalidate caches
|
@# Invalidate caches
|
||||||
@$(DOCKER_RUN) ${AWS_ENV} ${AWS_IMAGE} ${CLOUDFRONT_CMD}
|
${AWS} ${CLOUDFRONT_INVALIDATE}
|
||||||
.PHONY: cache
|
.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%;
|
||||||
|
}
|
||||||
197
config.yaml
197
config.yaml
@@ -1,12 +1,12 @@
|
|||||||
# core
|
# core
|
||||||
baseURL: "https://bdebyl.net/"
|
baseURL: https://debyl.io/
|
||||||
title: "Collection of useful, and useless information"
|
title: debyl.io
|
||||||
theme: "even"
|
theme: papermod
|
||||||
|
enableEmoji: true
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
paginate: 5
|
defaultContentLanguage: en
|
||||||
defaultContentLanguage: "en"
|
languageCode: en
|
||||||
languageCode: "en"
|
|
||||||
buildDrafts: false
|
buildDrafts: false
|
||||||
canonifyURLs: true
|
canonifyURLs: true
|
||||||
enableRobotsTXT: true
|
enableRobotsTXT: true
|
||||||
@@ -15,10 +15,17 @@ markup:
|
|||||||
goldmark:
|
goldmark:
|
||||||
renderer:
|
renderer:
|
||||||
unsafe: true
|
unsafe: true
|
||||||
|
highlight:
|
||||||
|
noClasses: false
|
||||||
|
# anchorLineNos: true
|
||||||
|
# codeFences: true
|
||||||
|
# guessSyntax: true
|
||||||
|
# lineNos: true
|
||||||
|
# style: monokai
|
||||||
|
|
||||||
# google analytics
|
# google analytics
|
||||||
googleAnalytics: "UA-163975086-1"
|
googleAnalytics: UA-163975086-1
|
||||||
googleVerification: ""
|
googleVerification:
|
||||||
|
|
||||||
# See https://gohugo.io/about/hugo-and-gdpr/
|
# See https://gohugo.io/about/hugo-and-gdpr/
|
||||||
privacy:
|
privacy:
|
||||||
@@ -30,63 +37,135 @@ privacy:
|
|||||||
# https://gohugo.io/content-management/syntax-highlighting/
|
# https://gohugo.io/content-management/syntax-highlighting/
|
||||||
pygmentsCodefences: true
|
pygmentsCodefences: true
|
||||||
pygmentsCodefencesGuessSyntax: true
|
pygmentsCodefencesGuessSyntax: true
|
||||||
pygmentsOptions: ""
|
pygmentsOptions:
|
||||||
pygmentsUseClasses: true
|
pygmentsUseClasses: true
|
||||||
|
|
||||||
author:
|
|
||||||
name: "Bastian de Byl"
|
|
||||||
|
|
||||||
sitemap:
|
sitemap:
|
||||||
changefreq: "weekly"
|
changefreq: weekly
|
||||||
filename: "sitemap.xml"
|
filename: sitemap.xml
|
||||||
priority: 0.5
|
priority: 0.5
|
||||||
|
|
||||||
menu:
|
outputs:
|
||||||
main:
|
home:
|
||||||
- name: "Home"
|
- HTML
|
||||||
weight: 10
|
- RSS
|
||||||
identifier: "home"
|
- JSON
|
||||||
url: "/"
|
|
||||||
- name: "About"
|
languages:
|
||||||
weight: 20
|
en:
|
||||||
identifier: "about"
|
languageName: English
|
||||||
url: "/about"
|
weight: 1
|
||||||
- name: "Archives"
|
taxonomies:
|
||||||
weight: 30
|
category: categories
|
||||||
identifier: "archives"
|
tag: tags
|
||||||
url: "/post/"
|
series: series
|
||||||
- name: "Tags"
|
menu:
|
||||||
weight: 40
|
main:
|
||||||
identifier: "tags"
|
- name: Archive
|
||||||
url: "/tags/"
|
url: archives
|
||||||
|
weight: 5
|
||||||
|
- name: Search
|
||||||
|
url: search/
|
||||||
|
weight: 10
|
||||||
|
- name: Tags
|
||||||
|
url: tags/
|
||||||
|
weight: 10
|
||||||
|
|
||||||
params:
|
params:
|
||||||
favicon: "/static/img/favicon.ico"
|
env: production # to enable google analytics, opengraph, twitter-cards and schema.
|
||||||
since: "2017"
|
description: Theme PaperMod - https://github.com/adityatelange/hugo-PaperMod
|
||||||
logoImage: "/static/img/logo.png"
|
author: Bastian de Byl
|
||||||
images:
|
# author: [Me, You] # multiple authors
|
||||||
- "/static/img/logo-prev.png"
|
|
||||||
logoTitle: "bdebyl"
|
|
||||||
keywords: ["bastian", "de byl", "bdebyl", "bastian de byl"]
|
|
||||||
description: "A random assortment of my personal projects."
|
|
||||||
|
|
||||||
# paginate of archives, tags and categories
|
ShowAllPagesInArchive: true
|
||||||
archivePaginate: 20
|
ShowBreadCrumbs: true
|
||||||
# show 'xx Posts In Total' in archive page
|
ShowCodeCopyButtons: true
|
||||||
showArchiveCount: true
|
ShowPageNums: true
|
||||||
# The date format to use; for a list of valid formats, see https://gohugo.io/functions/format/
|
ShowPostNavLinks: true
|
||||||
dateFormatToUse: "2006-01-02"
|
ShowReadingTime: true
|
||||||
# show word count and read time
|
ShowRssButtonInSectionTermList: true
|
||||||
moreMeta: true
|
ShowShareButtons: true
|
||||||
# show "read more" link on post summary
|
ShowToc: false
|
||||||
readMoreEnabled: false
|
comments: false
|
||||||
postMetaInFooter: true # contain author, lastMod, markdown link, license
|
defaultTheme: dark
|
||||||
linkToMarkDown: true # Only effective when hugo will output .md files.
|
disableSpecial1stPost: false
|
||||||
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>'
|
disableThemeToggle: true
|
||||||
|
displayFullLangName: true
|
||||||
|
images: [images/papermod-cover.png]
|
||||||
|
|
||||||
social:
|
profileMode:
|
||||||
a-email: "mailto:bastian@bdebyl.net"
|
enabled: false
|
||||||
g-github: "https://github.com/bdebyl"
|
|
||||||
m-instagram: "https://instagram.com/bastian.remi"
|
homeInfoParams:
|
||||||
n-gitlab: "https://gitlab.com/bdebyl"
|
Title: >
|
||||||
e-linkedin: "https://www.linkedin.com/in/bastian-de-byl-90171b187"
|
: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]
|
`70A4 AA02 555D BD55 9189 B4E0 F32B E05E ADAA 54FC`[^2]
|
||||||
|
|
||||||
{{< sub >}}[**Public Key**](/static/pubkey.txt){{< /sub >}}
|
[**Public Key**](/static/pubkey.txt)
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
## Donations
|
## 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
|
lastmod: 2019-02-11
|
||||||
categories: ["Blog"]
|
categories: ["Blog"]
|
||||||
tags: ["photography"]
|
tags: ["photography"]
|
||||||
images:
|
cover:
|
||||||
- "/static/img/aperture-study/f17-f40-comp.jpg"
|
image: /static/img/aperture-study/f17-f40-comp.jpg
|
||||||
---
|
---
|
||||||
I found out recently that using the maximum aperture for a lens can have
|
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
|
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`
|
## Partitioning with `fdisk`
|
||||||
|
|
||||||
{{% admonition warning Warning %}}
|
|
||||||
This operation will destroy any data on the device, please ensure to back up
|
This operation will destroy any data on the device, please ensure to back up
|
||||||
any data desired prior to this operation!
|
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`).
|
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`,
|
References specific to partitions will be stated as such (e.g. `/dev/sdN1`,
|
||||||
`/dev/sdN2`)
|
`/dev/sdN2`)
|
||||||
{{% /admonition %}}
|
|
||||||
|
|
||||||
1. Remove any existing partitions on the drive:
|
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
|
date: 2023-10-14
|
||||||
lastmod: 2023-10-14
|
lastmod: 2025-12-21
|
||||||
categories: ["Tutorial"]
|
categories: ["Tutorial"]
|
||||||
tags: ["linux","windows","bluetooth"]
|
tags: ["linux","windows","bluetooth"]
|
||||||
contentCopyright: true
|
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.
|
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-->
|
<!--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**
|
1. Pair your Bluetooth device(s) with Linux **first**
|
||||||
2. Reboot into Windows, then re-pair the devices with Windows
|
2. Reboot into Windows, then re-pair the devices with Windows
|
||||||
3. Run `regedit` **as Administrator**
|
3. Run `regedit` **as Administrator**
|
||||||
4. Navigate to:
|
4. Navigate to:
|
||||||
```
|
|
||||||
|
```text
|
||||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys
|
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.
|
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
|
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`_)
|
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.
|
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**
|
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:
|
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)©§
|
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`_
|
_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.
|
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"]
|
categories: ["Tutorial"]
|
||||||
contentCopyright: true
|
contentCopyright: true
|
||||||
hideHeaderAndFooter: false
|
hideHeaderAndFooter: false
|
||||||
images:
|
cover:
|
||||||
- "/static/img/emacs-clang-libopencm3/header-completion.png"
|
image: /static/img/emacs-clang-libopencm3/header-completion.png
|
||||||
---
|
---
|
||||||
With some minor dependencies, it's fairly straightforward in setting up your
|
With some minor dependencies, it's fairly straightforward in setting up your
|
||||||
Emacs workflow to include IntelliSense-like auto-completion!
|
Emacs workflow to include IntelliSense-like auto-completion!
|
||||||
@@ -114,13 +114,11 @@ The above assumes that `libopencm3` is also places within the project
|
|||||||
directory
|
directory
|
||||||
{{< /sub >}}
|
{{< /sub >}}
|
||||||
|
|
||||||
{{< admonition warning Note >}}
|
|
||||||
There is a strange issue that is encountered with non-working completion for new
|
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
|
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
|
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
|
restart itself after a completion request is triggered via `TAB` so this is a
|
||||||
fairly uninvolved workaround.
|
fairly uninvolved workaround.
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
@@ -92,43 +92,34 @@ this via:
|
|||||||
- **ArchLinux:** `sudo update-ca-trust`
|
- **ArchLinux:** `sudo update-ca-trust`
|
||||||
- **Debian/Ubuntu, RHEL:** `sudo update-ca-certificates`
|
- **Debian/Ubuntu, RHEL:** `sudo update-ca-certificates`
|
||||||
|
|
||||||
{{< admonition tip "CA Path" >}}
|
|
||||||
On my system the full path to the CA certs is:
|
On my system the full path to the CA certs is:
|
||||||
|
|
||||||
- `/etc/ca-certificates/extracted/cadir/sks-keyservers.net_CA.pem`
|
- `/etc/ca-certificates/extracted/cadir/sks-keyservers.net_CA.pem`
|
||||||
|
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
Two following parameters should be added to your `~/.gnupg` configuration files:
|
Two following parameters should be added to your `~/.gnupg` configuration files:
|
||||||
|
|
||||||
### GnuPG Versions >2.1
|
### GnuPG Versions >2.1
|
||||||
|
|
||||||
{{< admonition note "gpg.conf" >}}
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
keyserver hkps://hkps.pool.sks-keyservers.net
|
keyserver hkps://hkps.pool.sks-keyservers.net
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
{{< admonition note "dirmngr.conf" >}}
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
hkp-cacert /etc/ca-certificates/path/to/CA.pem
|
hkp-cacert /etc/ca-certificates/path/to/CA.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
### GnuPG Versions <2.1
|
### GnuPG Versions <2.1
|
||||||
|
|
||||||
{{< admonition note "gpg.conf" >}}
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
keyserver hkps://hkps.pool.sks-keyservers.net
|
keyserver hkps://hkps.pool.sks-keyservers.net
|
||||||
keyserver-options ca-cert-file=/path/to/CA/sks-keyservers.netCA.pem
|
keyserver-options ca-cert-file=/path/to/CA/sks-keyservers.netCA.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
## *Optional* - Ensure keys refreshed through keyserver
|
## *Optional* - Ensure keys refreshed through keyserver
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ date: 2018-01-11
|
|||||||
lastmod: 2019-01-16
|
lastmod: 2019-01-16
|
||||||
categories: ["Blog"]
|
categories: ["Blog"]
|
||||||
tags: ["electronics"]
|
tags: ["electronics"]
|
||||||
images:
|
cover:
|
||||||
- "/static/img/headphone-fix/IMG_7505.jpg"
|
image: /static/img/headphone-fix/IMG_7505.jpg
|
||||||
---
|
---
|
||||||
A colleague offered a pair of Bern Bluetooth drop-in headphones to me fore free,
|
A colleague offered a pair of Bern Bluetooth drop-in headphones to me fore free,
|
||||||
with the catch being: _I had to fix them_
|
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
|
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
|
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
|
it, carefully, with a pair of tweezers. I worked my way around the edge and
|
||||||
wedged the mesh upwards.
|
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)
|
in [the following datasheet](http://www.ti.com/lit/ds/symlink/tpa6132a2.pdf)
|
||||||
which verified that to be the case.
|
which verified that to be the case.
|
||||||
|
|
||||||
<center></center>
|

|
||||||
|
|
||||||
**Bingo!** Now knowing the pinout, I could use my trusty multimeter (_a Fluke
|
**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
|
115_) to test continuity of the circuit from the known-good and the now
|
||||||
|
|||||||
@@ -14,11 +14,9 @@ from WordPress)
|
|||||||
<!--more-->
|
<!--more-->
|
||||||
# Disclaimer
|
# Disclaimer
|
||||||
|
|
||||||
{{< admonition warning "Out of Date" >}}
|
|
||||||
The information in this article is **out-of-date**. I am, and have been, using my
|
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
|
own fork of the [hugo-even-theme](https://gitlab.com/bdebyl/hugo-theme-even) on
|
||||||
my [GitLab](https://gitlab.com/bdebyl) profile.
|
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**
|
being piped into `sha1sum`. I discovered incorrect `sha1sum` outputs **without**
|
||||||
`FNR==1` resulting in a useless password check!
|
`FNR==1` resulting in a useless password check!
|
||||||
|
|
||||||
{{< admonition note Note >}}
|
|
||||||
`IFS=` would not have fixed the above newline issue, as the problem stems
|
`IFS=` would not have fixed the above newline issue, as the problem stems
|
||||||
from the output of `pass "$p"` and **not** the filenames.
|
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
|
That takes care of gathering our passwords, but we'll revisit this again in the
|
||||||
next part.
|
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!**
|
**hooray!**
|
||||||
|
|
||||||
# Passwortstärke
|
# 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
|
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
|
strength though for my purposes it will be good enough (_I don't care to write
|
||||||
my own version of this, yet.._).
|
my own version of this, yet.._).
|
||||||
{{< admonition note Note >}}
|
|
||||||
I made this part of the script **optional**, as not every user would want to
|
I made this part of the script **optional**, as not every user would want to
|
||||||
install `cracklib` on their system.
|
install `cracklib` on their system.
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
This addition was made in the following order:
|
This addition was made in the following order:
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ tags: ["libopencm3", "stm32", "tutorial"]
|
|||||||
categories: ["Tutorial"]
|
categories: ["Tutorial"]
|
||||||
contentCopyright: true
|
contentCopyright: true
|
||||||
hideHeaderAndFooter: false
|
hideHeaderAndFooter: false
|
||||||
images:
|
cover:
|
||||||
- "/static/img/stm32-examples/part0/stm32-basic-gpio-leds.jpeg"
|
image: /static/img/stm32-examples/part0/stm32-basic-gpio-leds.jpeg
|
||||||
---
|
---
|
||||||
One of the simplest projects to get started with the STM32 microcontroller
|
One of the simplest projects to get started with the STM32 microcontroller
|
||||||
series: turn on the lights!
|
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"
|
{{< thumb src="/static/img/stm32-examples/part0/stm32-basic-gpio-leds.jpeg"
|
||||||
alt="Photo of STM32 discovery board with illuminated green and blue LEDs" >}}
|
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
|
# Straight to the Chase
|
||||||
|
|
||||||
For those that want to cut to the chase and save time, here is the full source
|
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:
|
code with friendly names to get you started:
|
||||||
|
|
||||||
{{< admonition note "Source Code" true >}}
|
|
||||||
|
|
||||||
```C
|
```C
|
||||||
#include <libopencm3/stm32/gpio.h>
|
#include <libopencm3/stm32/gpio.h>
|
||||||
#include <libopencm3/stm32/rcc.h>
|
#include <libopencm3/stm32/rcc.h>
|
||||||
@@ -50,8 +41,6 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
# Getting Started with libopencm3
|
# Getting Started with libopencm3
|
||||||
|
|
||||||
[libopencm3](https://github.com/libopencm3/libopencm3) is a very powerful,
|
[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
|
# Explanation
|
||||||
|
|
||||||
{{< admonition info "Naming Convention" >}}
|
|
||||||
As a note to the reader: below I will not refer to the GPIO port or pins using
|
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
|
the `#define` friendly names from above. This is purely for the sake
|
||||||
of clarity in hopes of avoiding confusion.
|
of clarity in hopes of avoiding confusion.
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
Although the source code is fairly simple, lets dive into it at least
|
Although the source code is fairly simple, lets dive into it at least
|
||||||
_somewhat_.
|
_somewhat_.
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ tags: ["libopencm3", "stm32", "tutorial"]
|
|||||||
categories: ["Tutorial"]
|
categories: ["Tutorial"]
|
||||||
contentCopyright: true
|
contentCopyright: true
|
||||||
hideHeaderAndFooter: false
|
hideHeaderAndFooter: false
|
||||||
images:
|
cover:
|
||||||
- "/static/img/stm32-examples/part1/blinky.gif"
|
image: /static/img/stm32-examples/part1/blinky.gif
|
||||||
---
|
---
|
||||||
After having reviewed [**Part 0**](/post/stm32-part0) of this series, we can now
|
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
|
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
|
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:
|
code with friendly names to get you started:
|
||||||
|
|
||||||
{{< admonition note "Source Code" true >}}
|
|
||||||
|
|
||||||
```C
|
```C
|
||||||
#include <libopencm3/stm32/gpio.h>
|
#include <libopencm3/stm32/gpio.h>
|
||||||
#include <libopencm3/stm32/rcc.h>
|
#include <libopencm3/stm32/rcc.h>
|
||||||
@@ -79,8 +77,6 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
# Set up the GPIO
|
# Set up the GPIO
|
||||||
|
|
||||||
Assuming the reader is either familiar with GPIO setup for the STM32F0, or has
|
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 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()`
|
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
|
Review the datasheet for the specific **STM32Fx** microcontroller being
|
||||||
programmed, as the Alternate Function mappings may be *significantly* different!
|
programmed, as the Alternate Function mappings may be _significantly_ different!
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
## GPIO Alternate Function Setup
|
## GPIO Alternate Function Setup
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ date: 2019-02-28
|
|||||||
lastmod: 2019-02-28
|
lastmod: 2019-02-28
|
||||||
categories: ["Blog"]
|
categories: ["Blog"]
|
||||||
tags: ["electronics"]
|
tags: ["electronics"]
|
||||||
images:
|
cover:
|
||||||
- "/static/img/thinkpad-usb-fix/DSC04781.jpg"
|
image: /static/img/thinkpad-usb-fix/DSC04781.jpg
|
||||||
---
|
---
|
||||||
From the moment that I first had my (_used_) ThinkPad X220, the bottom-right USB
|
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
|
port nearest to the SD card reader had been broken. The pad (_or bolster_) was
|
||||||
|
|||||||
@@ -13,10 +13,8 @@ is done!
|
|||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
{{< admonition info Info >}}
|
|
||||||
If the reader is unfamiliar with OpenPGP, it's suggested to check out the prior
|
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/)
|
write-up on this blog: [**OpenPGP Best Practices (and Git)**](/post/gpg_best_practices_and_git/)
|
||||||
{{< /admonition >}}
|
|
||||||
|
|
||||||
# Importing Secret Keys
|
# 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
|
Import it in OpenKeychain (_may require deletion in OpenKeychain first -- make
|
||||||
sure **not to revoke and delete!**_) and we're done!
|
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