← Позднее

Rss
28 июн. 2022
Человек слева толкает тележку с большим количеством коробок, на которых написаны названия популярных соцсетей. Человек справа несёт в руках одну коробку, на которой написано 'RSS'. Первый спрашивает: 'Это всё, что тебе нужно?` Второй отвечает: 'Да'.

RSS – это формат для описания новостной ленты того или иного сайта. Позволяет подписаться на новости с разных источников и читать их в одном месте.

Это что-то вроде подписки на изменения сайта. Технология была задолго до того, как появилась кнопка “следить” в социальных сетях. Хоть эта штука довольно старая, но всё ещё продолжает пользоваться спросом у некоторой когорты пользователей. Не нужно создавать никаких аккаунтов, регистрироваться или что-то типа того. Добавил RSS фид к себе в читалку и радуешься обновлениям.

В последнее время я прям подсел на сёрфинг Интернета в поиске интересных сайтов. Нахожу как и простенькие минималистичные блоги, так и сложные очень красивые личные страницы.

Как же я рад, что благодаря RSS могу подписаться на обновления любого из сайтов, которые предлагают новостной фид.

На компьютере я настроил консольную читалку newsboat
На телефоне стоит NetNewsWire

Но с помощью RSS можно подписываться не только на блоги и новостные ленты. Умершие несколько раз раньше и очень популярные сейчас подкасты работают именно с помощью RSS. Автор подкаста сам решает, где разместить свой подкаст:

и как это сделать:

Приложения а-ля Гугл или Эпл Подкасты и являются RSS читалками, но только для одного типа контента. С помощью читалок, которые я упомянул выше (и многих других) , можно подписываться и на подкасты тоже.

- А на что можно подписываться ещё?
- На всё, что угодно!

Через Nitter можно вытащить RSS ленту вашего любимого твиттерского. Раньше это можно было сделать и через твиттера, но в какой-то момент из него исчезли RSS ленты.

Через Invidious можно подписаться на ютюб канал и даже на отдельный плейлист. На ютюбе пока ещё существуют RSS ленты, но не факт, что их не постигнет твиттерская участь.

Nitter и Invidious – это альтернативные фронт-енды, которые убирают практически все трекеры и позволяют потреблять контент в куда более удобном и минималистичном формате. Мне, как человеку, который имел неосторожность назвать себя минималистом, факт наличия таких сервисов очень приятен. Да и Surveillance capitalism вот это всё

Не забываем и про Github. Здесь тоже можно подписаться на обновления коммитов и релизов, например. Правда, я не нашёл явного способа это сделать. Разве что в инструментах разработчика можно вбить в поиске .xml и наткнуться на RSS фид в исходном коде страницы. Такой хак работает и на других сайтах тоже. Например, я не сразу понял, что генератор статических сайтов Hugo, который я использую, может собирать RSS ленты :D

К чему я всё это? Благодаря RSS меняется то, как человек потребляет контент и вообще пользуется интернетом. С RSS больше не нужно открывать сайты в надежде на обновления. Не нужно прогружать тяжелые медленные страницы. Достаточно просто вытянуть обновления ленты в RSS читалке и наслаждаться только контентом без мишуры вокруг.

Если что, newsboat можно достать здесь https://newsboat.org


Обсуждение

foxy написал:

Некоторые клиенты умеют искать ленты на сайте. Я пользуюсь FeedBro в браузере и там можно тыкнуть, чтобы само нашло. Не всегда, но часто находит. Недавно нашёл Livemarks он оказывается лучше находит.

Плашки
27 июн. 2022

Вчера, бродя по интернету, я наткнулся на https://lukesmith.xyz/updates/bringing-back-oldschool-web-pins-and-buttons/. В этом посте Luke Smith вспоминает про такую штуку, как анимированные пины, которые были популярны в старом Интернете.

Сегодня же я захотел потыкаться в GIMP и сделал анимированный пин для Микоризы.

Выглядит он так.

Нужен ли блокчейн?
15 июн. 2022

Нет.

Ортовремя
26 апр. 2022

Когда-то я наткнулся на статью от @bouncepaw про ортовремя.

Описание

Чтобы различать стандартную систему времени, использую приставку шайзе для текущей системы, орто для моей новой системы.

В ортовремени сутки начинаются в 0 часов. Сутки делятся на 24 часа для совместимости.

0 орточасов соответствуют 6 шайзечасам, то есть времени, когда просыпаются самые ранние жаворонки. Для сравнения, в день написания статьи я встал в 1 орточас, а за день до этого — в 2 орточаса._

У большинства людей работа начинается где-то в 3 орточаса, то есть в 9 шайзечасов. Допустим, работа длится 8 часов, до 11 орточасов. Час на дорогу, часы бьют 12 орточасов — вы дома. Прошла ровно половина суток. Всё остальное время — ваше. Делайте что хотите, можете поспать даже. А когда проснётесь, новые сутки только-только начнутся!

Как это было

Я загорелся идеей и решил попробовать, да и недавно стал носить наручные
не смарт-часы со стрелками.

Сначала это выглядело примерно так:

Кошка смотрит на часы на стене
Я пытаюсь не запутаться

Я постоянно считал, сколько сейчас шайзе-времени, вместо того, чтобы жить по орто-.
“Не тру, не канон”, - подумал я.

Решил эту проблему довольно просто. Перевёл время не только на наручных часах, но и вообще везде, где только можно, на 6 часов назад (в случае часов со стрелками + или - значения не имеют). Автоматически перенеслись все события в календаре в новые, теперь правильные, места. Стало удобно, ведь я уже не тратил усилия, чтобы переключиться с орто- на шайзе- и наоборот.

Единственное, что меня беспокоило – не все интернет-приложения работают по времени устройства (что логично из-за соображения безопасности и чего-то там ещё, но не укладывается в концепцию ортовремени). Когда ждал доставку, чуть не перепутал время и не подставил курьера, ведь: “Ну, я поменял время на телефоне, значит поменялось везде”.


прошло какое-то время спустя вышенаписанных строк

Ещё заметил, что мне, на самом деле, не так важно, сколько времени сейчас, но сколько времени до какого-либо события.
Например:
Не “мне нужно выйти из дома в 10:00”,
а “мне нужно выйти из дома через 30 минут”.

И так со мной было всегда, я просто никогда об этом раньше не задумывался.


Ещё один плюс

Тот, который я нашёл помимо тех, которые были упомянуты в статье Баунса.

Кажется, что концепция ортовремени не обязывает других ей придерживаться, чтобы перестать путаться и спокойно существовать в обществе. А вот с концепцией самого удобного в мире календаря риски ошибиться сутками или даже неделей куда критичнее, чем перепутать орто- и шайзе-часы.

13 месяцев * 28 дней * 364 дня. Первый день месяца - всегда воскресенье, последний день месяца - всегда суббота, один оставшийся день - Новый год

Как я собирал ядро
19 февр. 2022

У меня было 2 сисколла, 40 свободных гигов для виртуалки, 12 потоков,
Linux Kernel 5.8.1 и множество статей, инструкций и документаций всех сортов и расцветок, а также Ubuntu 20.04 LTS, vim и мои нервы. Не то что бы это был необходимый запас для сборки. Но если начал собирать ядро, становится трудно остановиться. Единственное что вызывало у меня опасение – это кернелспейс.
Нет ничего более беспомощного, безответственного и испорченного, чем студент, пытающийся разобраться в ядре Linux. Я знал, что рано или поздно закончу собирать эту дрянь.

Начинаем путешествие

Копаться в ядре стоит прежде всего на виртуальной машине. Иначе, если что-то сломается, операционная система может просто не взлететь. Ставим образ Убунты на виртуальную машину. Я делал через Boxes, ибо так проще всего.

Запускаем виртуалку и полностью её обновляем

sudo apt update && sudo apt upgrade

Скачиваем нужные пакеты для сборки ядра

sudo apt install build-essential libncurses-dev libssl-dev
 libelf-dev bison flex

Устанавливаем архив ядра

wget -P ~/Downloads/ 
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.8.1.tar.xz

Распаковываем архив ядра в домашнюю директорию

tar -xvf ~/Downloads/linux-5.8.1.tar.xz -C ~/

Пишем системный вызов

В системном вызове мне нужно достучаться до структуры pci_dev, достав любое pci-устройство, и вывести поля device и vendor в пространство пользователя.

Переходим в директорию ядра

cd ~/linux-5.8.1/

Создаём директорию с именем эквивалентному нашему системному вызову.

В моём случае нужно достать поля из структуры pci_dev. Так и назовём директорию.

mkdir pci_dev

Создаём C файл и записываем код системного вызова в него

vim pci_dev/pci_dev.c
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/pci.h>
#include <linux/uaccess.h>

// Структура, которую будем передавать в пространство пользователя
struct pci_device_info {
	unsigned short vendor_id;
	unsigned short device_id;
};

/* Объявление системного вызова (запятые в аргументах правильные).
 info: указатель на эту же структуру, но в пространстве пользователя.
*/
SYSCALL_DEFINE1(pci_dev, struct pci_device_info *, info)
{
	struct pci_dev *dev = NULL;
	struct pci_device_info dev_info;

	dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
	dev_info.device_id = dev->device;
	dev_info.vendor_id = dev->vendor;

    // Печатаем информацию о структуре в пространство ядра
	printk(KERN_INFO "pci vendor id [%d]\n", dev_info.vendor_id);
	printk(KERN_INFO "pci device id [%d]\n", dev_info.device_id);

    // Передаём структуру в пространство пользователя
	copy_to_user(info, &dev_info, sizeof(struct pci_device_info));

	return 0;
}

Сохраняем изменения и выходим из vim`а.

В той же директории создаём Makefile

vim pci_dev/Makefile

Пишем это в Makefile нашего системного вызова.

obj-y := pci_dev.o

Открываем Makefile ядра

vim Makefile

Здесь нам нужна строчка core-y с перечислением директорий а-ля kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/

Дописываем здесь директорию с нашим системным вызовом.
Должно получиться так: kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ pci_dev/

Добавляем прототип функции нашего системного вызова и структуру в заголовочный файл системных вызовов

vim include/linux/syscalls.h

В самый конец над #endif добавляем

struct pci_device_info;
asmlinkage long sys_pci_dev(struct pci_device_info *);

Добавляем запись о нашем системном вызове в таблицу системных вызовов

vim arch/x86/entry/syscalls/syscall_64.tbl

В самый конец таблицы с 64-битным системными вызовами пишем следующее.

440     common  pci_dev                sys_pci_dev

Важно соблюдать нумерацию и табы.

Установка и сборка ядра

Конфигурируем ядро

Здесь нам нужна стандартная конфигурация.

make menuconfig

Тыкаем в Save, а потом в Exit.

Узнаём, сколько у нас логических ядер

nproc

У меня их 12. Это нужно, чтобы задействовать все ядра процессора для сборки ядра операционной системы (беды с терминологией ).

Собираем ядро

make -j12

-j - с помощью этого флага указываем, сколько задач будет исполняться одновременно

Собираем модули для установки ядра

sudo make modules_install -j12

Устанавливаем ядро

sudo make install -j12

Обновляем загрузчик, чтобы запуститься с новым ядром

sudo update-grub

Перезагружаемся

reboot

Пишем программу в user-space

Теперь напишем программу, которая будет делать системный вызов и выводить в стандартный поток информацию о структуре.

Создаём C программу

vim pci_dev_user.c
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

// Определяем системный вызов для простоты
#define __NR_pci_dev 440

// Наша пользовательская структура, 
// которую будем заполнять с помощью системного вызова
struct pci_device_info {
	unsigned short vendor_id;
	unsigned short device_id;
};

// Определение функции для системного вызова
long pci_dev_syscall(struct pci_device_info *ptr)
{
	return syscall(__NR_pci_dev, ptr);
}

int main()
{
    // Инициализируем структуру для заполнения
	struct pci_device_info result = { 0 };

    // Исполняем системный вызов, в аргумент которого помещаем 
    // указатель на пользовательскую структуру
	pci_dev_syscall(&result);

    // Выводим поля структуры в стандартный поток
	printf("vendor_id: %hu\n", result.vendor_id);
	printf("device_id: %d\n", result.device_id);

	return 0;
}

Собираем программу

gcc -o pci_dev_user pci_dev_user.c

Запускаем программу

./pci_dev_user

> vendor_id: 32902
> device_id: 10688

Смотрим вывод ядра

dmesg

> [   38.604541] pci vendor id [32902]
> [   38.604544] pci device id [10688]

Работает!

То же самое, но для структуры syscall_info

Буду более краток, ибо процесс по сборке и написанию идентичный. Однако, чтобы достать структуру пришлось много потеть и прыгать от одной структуры к другой.

Системный вызов

#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/sched/task_stack.h>
#include <linux/export.h>
#include <linux/types.h>

// Здесь структура очень маленькая, 
// так что просто передаём её напрямую пользователю, 
// используя определение из ptrace.h

SYSCALL_DEFINE2(syscall_info, int, pid_input, 
                struct syscall_info *, info)
{
	printk(KERN_INFO "process's pid: %d\n", pid_input);
    
	struct pid *pid_task = NULL;
	pid_task = find_get_pid(pid_input);

	struct task_struct *task = NULL;
	task = get_pid_task(pid_task, PIDTYPE_PID);

	struct syscall_info sys_info;
	task_current_syscall(task, &sys_info);

	printk(KERN_INFO "user_sp: %llu", sys_info.sp);

	copy_to_user(info, &sys_info, sizeof (struct syscall_info));

	return 0;
}

Клиентская программа

#include <linux/kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define __NR_syscall_info 441

// Задаём описание структуры

struct seccomp_data {
	int nr;
	__u32 arch;
	__u64 instruction_pointer;
	__u64 args[6];
};

struct syscall_info {
	__u64 sp;
	struct seccomp_data data;
};

long syscall_info_syscall(int pid_input, struct syscall_info *ptr)
{
	return syscall(__NR_syscall_info, pid_input, ptr);
}

int main(int argc, char **argv)
{
	char *a = argv[1];
	int pid_id = atoi(a);

	printf("Pid_id: %d\n", pid_id);

	struct syscall_info result;

	syscall_info_syscall(pid_id, &result);

	printf("Syscall_number: %d\n", result.data.nr);
	printf("User Stack Pointer: %lld\n", result.sp);

	return 0;
}

Запускаем программу

Pid_id: 958
Syscall_number: 7
User Stack Pointer: 140726335318048

Смотрим вывод ядра

[   21.342638] user_sp: 140726335318048

Указатели стека идентичны, значит, структура передана верно!

Проблемы и решения

Не работает “sudo update-grub”

Изменяем конфигурацию загрузчика, чтобы загрузиться с нужным ядром

vim /etc/default/grub

Строки ниже должны быть следующими:

GRUB_DEFAULT=0
GRUB_TIMEOUT=-1 # Чтобы была возможность выбрать нужную версию ядра
GRUB_HIDDEN_TIMEOUT=0

Что-то там с сертификатами и доверенными ключами

Изменяем конфигурацию ядра.

scripts/config --disable SYSTEM_TRUSTED_KEYS

или

scripts/config --set-str SYSTEM_TRUSTED_KEYS ""

BTF: .tmp_vmlinux.btf: pahole (pahole) is not available

sudo apt install dwarves
Ранее →