Bryan R Hinton
Linux memory , and meaning
Sonntag, 8. März 2026
Out of Deep Respect: 1700 Years of Jewish Life
Dienstag, 25. November 2025
RK3588 ARM Inbetriebnahme: U-Boot, Kernel und Signalintegrität
Der RK3588 SoC verfügt über eine Quad-Core Arm Cortex-A76/A55 CPU, eine Mali-G610 GPU und eine hochflexible I/O-Architektur, die ihn ideal für eingebettete Linux SBCs wie den Radxa Rock 5B+ macht.
Ich habe die Inbetriebnahme dieser Plattform erforscht und dokumentiert, einschließlich meiner Beiträge zu u-boot und dem Linux-Kernel, der Entwicklung des Device Trees sowie der Werkzeuge für reproduzierbare Builds und die Validierung der Signalintegrität. Der Großteil dieser Arbeit befindet sich noch in der aktiven Entwicklungsphase und der frühen Vorbereitungsphase für die Veröffentlichung im Upstream-Projekt.
Ich veröffentliche hier meine Notizen, Messungen und Inbetriebnahme-Artefakte im Laufe der Arbeit, während die aktive u-boot- und Kernelentwicklung einschließlich Patch-Iteration, Test-Builds und Branch-Historie in separaten Arbeits-Repositories gepflegt wird:
Signalanalyse / Bring-Up-Repository: https://github.com/brhinton/signal-analysis
Das Repository umfasst derzeit (und es werden ständig weitere hinzugefügt):
- Device-Tree-Quellen und Rock 5B+ Board-Aktivierung
- UART-Signalintegritätsmessungen mit 1,5 Mbit/s am SoC-Pad
- Anleitung zum Erstellen von Kernel, Bootloader und Debugging-Setup
- Frühe Patch-Workflows und Upstream-Vorbereitungsnotizen
Zusätzliche Arbeiten an U-Boot und dem Linux-Kernel, einschließlich Mainline-Test-Builds, Funktionsentwicklung, Rebase-Updates und laufenden Patch-Serien, werden in separaten Arbeits-Repositories verwaltet. Dieses Repository dient als zentraler Ort für Messungen, Dokumentation und Inbetriebnahmehinweise auf Boardebene.
Dies ist ein fortlaufendes, noch in Entwicklung befindliches technisches Projekt, und ich werde die Repositories aktualisieren, sobald zusätzliche Messungen, Boards und für die Upstream-Entwicklung geeignete Änderungen vorbereitet sind.
Sonntag, 4. August 2024
arch linux uefi with dm-crypt and uki
Arch Linux is known for its high level of customization, and configuring LUKS2 and LVM is a straightforward process. This guide provides a set of instructions for setting up an Arch Linux system with the following features:
- Root file system encryption using LUKS2.
- Logical Volume Management (LVM) for flexible storage management.
- Unified Kernel Image (UKI) bootable via UEFI.
- Optional: Detached LUKS header on external media for enhanced security.
Prerequisites
- A bootable Arch Linux ISO.
- An NVMe drive (e.g.,
/dev/nvme0n1). - (Optional) A microSD card or other external medium for the detached LUKS header.
Important Considerations
- Data Loss: The following procedure will erase all data on the target drive. Back up any important data before proceeding.
- Secure Boot: This guide assumes you may want to use hardware secure boot.
- Detached LUKS Header: Using a detached LUKS header on external media adds a significant layer of security. If you lose the external media, you will lose access to your encrypted data.
- Swap: This guide uses a swap file. You may also use a swap partition if desired.
Step-by-Step Instructions
-
Boot into the Arch Linux ISO:
Boot your system from the Arch Linux installation media.
-
Set the System Clock:
# timedatectl set-ntp true -
Prepare the Disk:
- Identify your NVMe drive (e.g.,
/dev/nvme0n1). Uselsblkto confirm. - Wipe the drive:
# wipefs --all /dev/nvme0n1 - Identify your NVMe drive (e.g.,
- Create an EFI System Partition (ESP):
- Create a partition for the encrypted volume:
-
Set up LUKS2 Encryption:
Encrypt the second partition using LUKS2. This example uses
aes-xts-plain64andserpent-xts-plainciphers, and SHA512 for the hash. Adjust as needed.# cryptsetup luksFormat --cipher aes-xts-plain64 \ --keyslot-cipher serpent-xts-plain --keyslot-key-size 512 \ --use-random -S 0 -h sha512 -i 4000 /dev/nvme0n1p2--cipher: Specifies the cipher for data encryption.--keyslot-cipher: Specifies the cipher used to encrypt the key.--keyslot-key-size: Specifies the size of the key slot.-S 0: Disables sparse headers.-h: Specifies the hash function.-i: Specifies the number of iterations.
Open the encrypted partition:
# cryptsetup open /dev/nvme0n1p2 root -
Create the File Systems and Mount:
Create an ext4 file system on the decrypted volume:
# mkfs.ext4 /dev/mapper/rootMount the root file system:
# mount /dev/mapper/root /mntCreate and mount the EFI System Partition:
# mkfs.fat -F32 /dev/nvme0n1p1 # mount --mkdir /dev/nvme0n1p1 /mnt/efiCreate and enable a swap file:
# dd if=/dev/zero of=/mnt/swapfile bs=1M count=8000 status=progress # chmod 600 /mnt/swapfile # mkswap /mnt/swapfile # swapon /mnt/swapfile -
Install the Base System:
Use
pacstrapto install the necessary packages:# pacstrap -K /mnt base base-devel linux linux-hardened \ linux-hardened-headers linux-firmware apparmor mesa \ xf86-video-intel vulkan-intel git vi vim ukify -
Generate the fstab File:
# genfstab -U /mnt >> /mnt/etc/fstab -
Chroot into the New System:
# arch-chroot /mnt -
Configure the System:
Set the timezone:
# ln -sf /usr/share/zoneinfo/UTC /etc/localtime # hwclock --systohcUncomment
en_US.UTF-8 UTF-8in/etc/locale.genand generate the locale:# sed -i 's/#'"en_US.UTF-8"' UTF-8/'"en_US.UTF-8"' UTF-8/g' /etc/locale.gen # locale-gen # echo 'LANG=en_US.UTF-8' > /etc/locale.conf # echo "KEYMAP=us" > /etc/vconsole.confSet the hostname:
# echo myhostname > /etc/hostname # cat <<EOT >> /etc/hosts 127.0.0.1 myhostname ::1 localhost 127.0.1.1 myhostname.localdomain myhostname EOTConfigure
mkinitcpio.confto include theencrypthook:# sed -i 's/HOOKS.*/HOOKS=(base udev autodetect modconf kms \ keyboard keymap consolefont block encrypt filesystems resume fsck)/' \ /etc/mkinitcpio.confCreate the initial ramdisk:
# mkinitcpio -PInstall the bootloader:
# bootctl installSet the root password:
# passwdInstall microcode and efibootmgr:
# pacman -S intel-ucode efibootmgrGet the swap offset:
# swapoffset=`filefrag -v /swapfile | awk '/\s+0:/ {print $4}' | \ sed -e 's/\.\.$//'`Get the UUID of the encrypted partition:
# blkid -s UUID -o value /dev/nvme0n1p2Create the EFI boot entry. Replace
<UUID OF CRYPTDEVICE>with the actual UUID:# efibootmgr --disk /dev/nvme0n1p1 --part 1 --create --label "Linux" \ --loader /vmlinuz-linux --unicode "cryptdevice=UUID=<UUID OF CRYPTDEVICE>:root \ root=/dev/mapper/root resume=/dev/mapper/root resume_offset=$swapoffset \ rw initrd=\intel-ucode.img initrd=\initramfs-linux.img" --verboseConfigure the UKI presets:
# cat <<EOT >> /etc/mkinitcpio.d/linux.preset ALL_kver="/boot/vmlinuz-linux" ALL_microcode=(/boot/*-ucode.img) PRESETS=('default' 'fallback') default_uki="/efi/EFI/Linux/arch-linux.efi" default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp" fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi" fallback_options="-S autodetect" EOTCreate the UKI directory:
# mkdir -p /efi/EFI/LinuxConfigure the kernel command line:
# cat <<EOT >> /etc/kernel/cmdline cryptdevice=UUID=<UUID OF CRYPTDEVICE>:root root=/dev/mapper/root \ resume=/dev/mapper/root resume_offset=51347456 rw EOTBuild the UKIs:
# mkinitcpio -p linuxConfigure the kernel install layout:
# echo "layout=uki" >> /etc/kernel/install.conf -
Configure Networking (Optional):
Create a systemd-networkd network configuration file:
# cat <<EOT >> /etc/systemd/network/nic0.network [Match] Name=nic0 [Network] DHCP=yes EOT -
Install a Desktop Environment (Optional):
Install Xorg, Xfce, LightDM, and related packages:
# pacman -Syu # pacman -S xorg xfce4 xfce4-goodies lightdm lightdm-gtk-greeter \ libva-intel-driver mesa xorg-server xorg-xinit sudo # systemctl enable lightdm # systemctl start lightdm -
Enable Network Services (Optional):
# systemctl enable systemd-resolved.service # systemctl enable systemd-networkd.service # systemctl start systemd-resolved.service # systemctl start systemd-networkd.service -
Create a User Account:
Create a user account and add it to the
wheelgroup:# useradd -m -g wheel -s /bin/bash myusername -
Reboot:
Exit the chroot environment and reboot your system:
# exit # umount -R /mnt # reboot
# sgdisk /dev/nvme0n1 -n 1::+512MiB -t 1:EF00
# sgdisk /dev/nvme0n1 -n 2 -t 2:8300
Samstag, 6. April 2024
Multidimensional arrays of function pointers in C
Mittwoch, 12. Januar 2022
Concurrency, Parallelism, and Barrier Synchronization - Multiprocess and Multithreaded Programming
When the currently executing process relinquishes the processor, either voluntarily or involuntarily, another process can execute its program code. This event is known as a context switch, which facilitates interleaved execution. Time-sliced, interleaved execution of program code within an address space is known as concurrency.
The Linux kernel is fully preemptive, which means that it can force a context switch for a higher priority process. When a context switch occurs, the state of a process is saved to its process control block, and another process resumes execution on the processor.
A UNIX process is considered heavyweight because it has its own address space, file descriptors, register state, and program counter. In Linux, this information is stored in the task_struct. However, when a process context switch occurs, this information must be saved, which is a computationally expensive operation.
Concurrency applies to both threads and processes. A thread is an independent sequence of execution within a UNIX process, and it is also considered a schedulable entity. Both threads and processes are scheduled for execution on a processor core, but thread context switching is lighter in weight than process context switching.
In UNIX, processes often have multiple threads of execution that share the process's memory space. When multiple threads of execution are running inside a process, they typically perform related tasks. The Linux user-space APIs for process and thread management abstract many details. However, the concurrency level can be adjusted to influence the time quantum so that the system throughput is affected by shorter and longer durations of schedulable entity execution time.
In the 1:1 model, one user-space thread is mapped to one kernel thread. This allows for true parallelism, as each thread can run on a separate processor core. However, creating and managing a large number of kernel threads can be expensive.
In the 1:N model, multiple user-space threads are mapped to a single kernel thread. This is more lightweight, as there are fewer kernel threads to create and manage. However, it does not allow for true parallelism, as only one thread can execute on a processor core at a time.
In the M:N model, N user-space threads are mapped to M kernel threads. This provides a balance between the 1:1 and 1:N models, as it allows for both true parallelism and lightweight thread creation and management. However, it can be complex to implement and can lead to issues with load balancing and resource allocation.
Parallelism on a time-sliced, preemptive operating system means the simultaneous execution of multiple schedulable entities over a time quantum. Both processes and threads can execute in parallel across multiple cores or processors. Concurrency and parallelism are at play on a multi-user system with preemptive time-slicing and multiple processor cores. Affinity scheduling refers to scheduling processes and threads across multiple cores so that their concurrent and parallel execution is close to optimal.
It's worth noting that affinity scheduling refers to the practice of assigning processes or threads to specific processors or cores to optimize their execution and minimize unnecessary context switching. This can improve overall system performance by reducing cache misses and increasing cache hits, among other benefits. In contrast, non-affinity scheduling allows processes and threads to be executed on any available processor or core, which can result in more frequent context switching and lower performance.Mittwoch, 24. Februar 2021
A hardware design for variable output frequency using an n-bit counter
As the switches are moved or the buttons are pressed, the seven-segment display is updated to reflect the numeric output frequency, and the output pin(s) are driven at the desired frequency. The onboard clock runs at 50MHz, and the signal on the output pins is set on the rising edge of the clock input signal (positive edge-triggered). At 50MHz, the output pins can be toggled at a maximum rate of 50 million cycles per second or 25 million rising edges of the clock per second. An LED attached to one of the output pins would blink 25 million times per second, not recognizable to the human eye. The persistence of vision, which is the time the human eye retains an image after it disappears from view, is approximately 1/16th of a second. Therefore, an LED blinking at 25 million times per second would appear as a continuous light to the human eye.
scaler <= compute_prescaler((to_integer(unsigned( SW )))*scaler_mlt);
gpiopulse_process : process(CLOCK_50, KEY(0))
begin
if (KEY(0) = '0') then -- async reset
count <= 0;
elsif rising_edge(CLOCK_50) then
if (count = scaler - 1) then
state <= not state;
count <= 0;
elsif (count = clk50divider) then -- auto reset
count <= 0;
else
count <= count + 1;
end if;
end if;
end process gpiopulse_process;The scaler signal is calculated using the compute_prescaler function, which takes the value of a switch (SW) as an input, multiplies it with a multiplier (scaler_mlt), and then converts it to an integer using to_integer. This scaler signal is used to control the frequency of the pulse signal generated on the output pin.It is important to note that concurrent statements within an architecture are executed concurrently, meaning that they are evaluated concurrently and in no particular order. However, the sequential statements within a process are executed sequentially, meaning that they are evaluated in order, one at a time. Processes themselves are executed concurrently with other processes, and each process has its own execution context.
Dienstag, 25. August 2020
Creating stronger keys for OpenSSH and GPG
Create Ed25519 SSH keypair (supported in OpenSSH 6.5+). Parameters are as follows:
-o save in new format-a 128 for 128 kdf (key derivation function) rounds
-t ed25519 for type of key
ssh-keygen -o -a 128 -t ed25519 -f .ssh/ed25519-$(date '+%m-%d-%Y') -C ed25519-$(date '+%m-%d-%Y')
Create Ed448-Goldilocks GPG master key and sub keys.# gpg --quick-generate-key ed448-master-key-$(date '+%m-%d-%Y') ed448 sign 0
# gpg --list-keys --with-colons "ed448-master-key-08-03-2021" | grep fpr
# gpg --quick-add-key "$fpr" cv448 encr 2y
# gpg --quick-add-key "$fpr" ed448 auth 2y
# gpg --quick-add-key "$fpr" ed448 sign 2y