<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>HM0008</title>
  <link>https://hm0008.hmiya.net</link>
  <description>Public website of HM0008</description>
  <atom:link href="https://hm0008.hmiya.net/feed.xml" rel="self" type="application/rss+xml"/>
  <lastBuildDate>Sun, 15 Feb 2026 12:58:57 GMT</lastBuildDate>
  <item>
    <title>HM0008 のホスティング</title>
    <link>https://hm0008.hmiya.net/20260215172908</link>
    <guid>https://hm0008.hmiya.net/20260215172908</guid>
    <pubDate>Sun, 15 Feb 2026 12:38:18 GMT</pubDate>
    <description>&lt;h1&gt;HM0008 のホスティング&lt;/h1&gt;
&lt;p&gt;#index #deployment&lt;/p&gt;
&lt;p&gt;このサイト (HM0008) は静的サイト (static site) として、家の SBC 上にホスティングされている。
このページでは、このシステムの技術的な要素について概観する。&lt;/p&gt;
&lt;h2&gt;技術的な要素&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;md-html コンパイラ&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本サイトのすべてのページの内容は markdown ファイルに記載している。
このため、 markdown ファイルを html ファイルに変換する必要がある。
そこで、この変換を行うコンパイラを書いた。&lt;/p&gt;
&lt;p&gt;生成された HTML を SBC にデプロイしている。これには以下の機能を利用する。&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;web サーバー: 今回は &lt;a href=&quot;https://static-web-server.net/&quot;&gt;static-web-server (sws)&lt;/a&gt; を利用した。 nginx などでも問題ない。&lt;/li&gt;
&lt;li&gt;git hook: 簡素な継続的デプロイメント (continuous deployment; CD) を実現するために利用した。&lt;/li&gt;
&lt;li&gt;cloudflare access: sws のポートを公開するために利用した。&lt;/li&gt;
&lt;li&gt;podman-systemd (quadlet): sws と cloudflared (cloudflare acess のクライアント) のコンテナを systemd サービス化するために利用した。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;各要素の詳細&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;./20260215180313.html&quot;&gt;Git hook (post-receive) による継続的デプロイメント&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;TODO: &lt;a href=&quot;&quot;&gt;podman-systemd による&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;TODO: &lt;a href=&quot;&quot;&gt;cloudflare access によるサービスの公開&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;TODO: &lt;a href=&quot;&quot;&gt;cloudflare access による公開サービスへのアクセス制限&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;TODO: &lt;a href=&quot;&quot;&gt;md-html コンパイラのデザイン&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Git hook (post-receive) による継続的デプロイメント</title>
    <link>https://hm0008.hmiya.net/20260215180313</link>
    <guid>https://hm0008.hmiya.net/20260215180313</guid>
    <pubDate>Sun, 15 Feb 2026 12:38:18 GMT</pubDate>
    <description>&lt;h1&gt;Git hook (post-receive) による継続的デプロイメント&lt;/h1&gt;
&lt;p&gt;#git #deployment&lt;/p&gt;
&lt;p&gt;このページでは、 &lt;code&gt;post-receive&lt;/code&gt; の使い方を記載する。&lt;/p&gt;
&lt;h2&gt;Git hooks と &lt;code&gt;post-receive&lt;/code&gt; の概要&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks&quot;&gt;Git hooks&lt;/a&gt; (&lt;a href=&quot;https://git-scm.com/book/ja/v2/Git-%e3%81%ae%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%9e%e3%82%a4%e3%82%ba-Git-%e3%83%95%e3%83%83%e3%82%af&quot;&gt;日本語&lt;/a&gt; ) 機能を利用することで、いくつかの git 操作の前後にスクリプトを実行できる。
この &lt;code&gt;post-receive&lt;/code&gt; hook は &lt;code&gt;git push&lt;/code&gt; の受け取り (receive) が完了すると発火されるものである。
&lt;code&gt;post-receive&lt;/code&gt; にデプロイ処理を記述しておくことで、 &lt;code&gt;git push&lt;/code&gt; された内容を継続的にデプロイすることが可能である。&lt;/p&gt;
&lt;h2&gt;前提: &lt;code&gt;git push&lt;/code&gt; する側、される側の準備&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;git push&lt;/code&gt; する側&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;git push&lt;/code&gt; を行う remote repository の登録が必要。
ssh 経由で push する場合は以下:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;git remote add &amp;lt;remote name&amp;gt; ssh://&amp;lt;user&amp;gt;@&amp;lt;address&amp;gt;:&amp;lt;path to repository&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;git push&lt;/code&gt; される側 (受け取り側)&lt;/h3&gt;
&lt;p&gt;デプロイされる側も Git リポジトリが必要である。受け取り側のマシンで &lt;code&gt;git init&lt;/code&gt; しておく。
その後、 &lt;code&gt;.git/hooks/&lt;/code&gt; ディレクトリの配下に &lt;code&gt;post-receive&lt;/code&gt; ファイルを作成する。&lt;/p&gt;
&lt;p&gt;例:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;git init
$EDITOR .git/hooks/post-receive
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;例: HM0008 のデプロイにおける post-receive の利用&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;./20260215172908.html&quot;&gt;HM0008 のホスティング&lt;/a&gt; に関するリポジトリの &lt;code&gt;post-receive&lt;/code&gt; では以下を実施した。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;working tree の更新 (push された内容の checkout)&lt;/li&gt;
&lt;li&gt;必要なデプロイ操作: markdown ファイルを html ファイルへ変換、 systemd サービスのリロードなど&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;working tree の更新:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;unset GIT_DIR
unset GIT_WORK_TREE
unset GIT_INDEX_FILE
unset GIT_QUARANTINE_PATH

# ----------------------
# DEPLOY
# ----------------------

# checkout the latest states
echo &quot;Checking out latest default branch...&quot;
for dir in $SCRIPT_DIR $COMPILER_DIR $QUADLET_CONFIG_DIR  $MARKDOWN_DIR; do
  echo &quot;- $dir&quot;
  git -C $dir checkout -f default || exit 1
done
echo &quot;DONE&quot;
echo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;メモ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hook 実行時に、いくつか環境変数が設定される (&lt;code&gt;GIT_DIR&lt;/code&gt; など) 。 hook 内で git 操作をする場合には考慮が必要。
&lt;ul&gt;
&lt;li&gt;今回はそれらを &lt;code&gt;unset&lt;/code&gt; している&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;コンパイラや、 markdown ファイルのリポジトリに &lt;code&gt;git push&lt;/code&gt; された場合:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;  echo &quot;Building sinter...&quot;
  pushd $COMPILER_DIR
  cargo build --release --quiet || exit 1
  echo &quot;DONE&quot;
  echo

  # recreate target directory
  rm -r $HTML_TARGET_DIR
  mkdir -p $HTML_TARGET_DIR

  echo &quot;Compiling markdown files...&quot;
  # compile markdown files to html
  cargo run --release \
     --quiet \
     -- \
     --input $MARKDOWN_DIR \
     --output $HTML_TARGET_DIR \
     --templates $COMPILER_DIR/templates \
     --config $CONFIG_FILE || exit 1
  popd
  systemctl --user restart zettel-pod.service || exit 1
  echo &quot;DONE&quot;
  echo

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pod ファイルも &lt;code&gt;git push&lt;/code&gt; でデプロイしている:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;  echo &quot;Updating unit files...&quot;
  # copy unit files
  cp -v $QUADLET_CONFIG_DIR/*.pod $SYSTEMD_DIR || exit 1
  cp -v $QUADLET_CONFIG_DIR/*.container $SYSTEMD_DIR || exit 1
  echo &quot;DONE&quot;
  echo

  echo &quot;Reloading systemd services...&quot;
  # reload systemd
  systemctl --user daemon-reload || exit 1
  systemctl --user restart zettel-pod.service || exit 1
  echo &quot;DONE&quot;
  echo
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;メモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pre-receive&lt;/code&gt; を使うと、 push 前に CI に相当する操作もできそう&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pre-receive&lt;/code&gt; や &lt;code&gt;pre-commit&lt;/code&gt; では、 &lt;code&gt;exit 1&lt;/code&gt; (正確には、 0 以外の exit status でスクリプトを終了) することで、 push / commit を abort できるようだ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>ベランダの音 (2026-02-08)</title>
    <link>https://hm0008.hmiya.net/20260209121615</link>
    <guid>https://hm0008.hmiya.net/20260209121615</guid>
    <pubDate>Mon, 09 Feb 2026 08:50:59 GMT</pubDate>
    <description>&lt;h1&gt;ベランダの音 (2026-02-08)&lt;/h1&gt;
&lt;p&gt;#fieldrecording&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;日時: 2026-02-08 10時頃&lt;/li&gt;
&lt;li&gt;場所: 家のベランダ&lt;/li&gt;
&lt;li&gt;音:
&lt;ul&gt;
&lt;li&gt;雪融け水が落ちる音&lt;/li&gt;
&lt;li&gt;近所の音&lt;/li&gt;
&lt;li&gt;建物の先にある幹線道路の音&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コメント: 前日の夜から雪が降っていて、珍しく積もった&lt;/li&gt;
&lt;/ul&gt;
&lt;audio controls src=&quot;./assets/20260208110000.mp3&quot;&gt;
  Your browser does not support the audio element.
&lt;/audio&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20260208120346.jpg&quot; alt=&quot;ハンディレコーダーの写真&quot; /&gt;&lt;/p&gt;
&lt;p&gt;メモ: 音声加工の記録&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ffprobe -i 260208_0033.wav -show_entries format=duration -v quiet -of csv=&quot;p=0&quot;
3814.344000

&amp;gt; ffmpeg -i 260208_0033.wav -filter:a volumedetect -f null - 2&amp;gt;&amp;amp;1 | grep &quot;volume:&quot;
[Parsed_volumedetect_0 @ 0x7f06f4003dc0] mean_volume: -54.6 dB
[Parsed_volumedetect_0 @ 0x7f06f4003dc0] max_volume: -17.6 dB

&amp;gt; ffmpeg -i 260208_0033.wav -ss 30 -to 3600 -af &quot;volume=16.5dB,afade=t=in:st=30:d=5,afade=t=out:st=3595:d=5&quot; 260208_0033_processed.wav -y
ffmpeg version n8.0.1 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 15.2.1 (GCC) 20260103
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-frei0r --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libdav1d --enable-libdrm --enable-libdvdnav --enable-libdvdread --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgsm --enable-libharfbuzz --enable-libiec61883 --enable-libjack --enable-libjxl --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-librav1e --enable-librsvg --enable-librubberband --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpl --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-nvdec --enable-nvenc --enable-opencl --enable-opengl --enable-shared --enable-vapoursynth --enable-version3 --enable-vulkan
  libavutil      60.  8.100 / 60.  8.100
  libavcodec     62. 11.100 / 62. 11.100
  libavformat    62.  3.100 / 62.  3.100
  libavdevice    62.  1.100 / 62.  1.100
  libavfilter    11.  4.100 / 11.  4.100
  libswscale      9.  1.100 /  9.  1.100
  libswresample   6.  1.100 /  6.  1.100
[aist#0:0/pcm_f32le @ 0x55cd650d9f80] Guessed Channel Layout: stereo
Input #0, wav, from &apos;260208_0033.wav&apos;:
  Metadata:
    encoded_by      : TASCAM Portacapture X8
    date            : 2026-02-08
    creation_time   : 12:03:14
    time_reference  : 1899789696
    coding_history  : T=XRI 008c;XRI VER=0002;MAKER=TASCAM;MODEL=X8;FW VER=2.01;SOURCE=1:INT MIC,2:INT MIC;INPUT GAIN=1:HIGH,2:HIGH;LEVEL=1:29,2:29;AUTO_LEVEL=1:OFF,2:OFF;,
  Duration: 01:03:34.34, bitrate: 3072 kb/s
  Stream #0:0: Audio: pcm_f32le ([3][0][0][0] / 0x0003), 48000 Hz, stereo, flt, 3072 kb/s
Stream mapping:
  Stream #0:0 -&amp;gt; #0:0 (pcm_f32le (native) -&amp;gt; pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, wav, to &apos;260208_0033_processed.wav&apos;:
  Metadata:
    ITCH            : TASCAM Portacapture X8
    ICRD            : 2026-02-08
    coding_history  : T=XRI 008c;XRI VER=0002;MAKER=TASCAM;MODEL=X8;FW VER=2.01;SOURCE=1:INT MIC,2:INT MIC;INPUT GAIN=1:HIGH,2:HIGH;LEVEL=1:29,2:29;AUTO_LEVEL=1:OFF,2:OFF;,
    time_reference  : 1899789696
    ISFT            : Lavf62.3.100
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, stereo, s16, 1536 kb/s
    Metadata:
      encoder         : Lavc62.11.100 pcm_s16le
[out#0/wav @ 0x55cd650da1c0] video:0KiB audio:669375KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.000019%
size=  669375KiB time=00:59:30.00 bitrate=1536.0kbits/s speed=8.61e+03x elapsed=0:00:00.41

&amp;gt; ffmpeg -i 260208_0033_processed.wav -filter:a volumedetect -f null - 2&amp;gt;&amp;amp;1 | grep &quot;volume:&quot;
[Parsed_volumedetect_0 @ 0x7f3cd4003dc0] mean_volume: -38.3 dB
[Parsed_volumedetect_0 @ 0x7f3cd4003dc0] max_volume: -1.1 dB

&amp;gt; ffmpeg -i 260208_0033_processed.wav -codec:a libmp3lame -b:a 320k 260208_0033_processed.mp3 -y
ffmpeg version n8.0.1 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 15.2.1 (GCC) 20260103
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-frei0r --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libdav1d --enable-libdrm --enable-libdvdnav --enable-libdvdread --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgsm --enable-libharfbuzz --enable-libiec61883 --enable-libjack --enable-libjxl --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-librav1e --enable-librsvg --enable-librubberband --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpl --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-nvdec --enable-nvenc --enable-opencl --enable-opengl --enable-shared --enable-vapoursynth --enable-version3 --enable-vulkan
  libavutil      60.  8.100 / 60.  8.100
  libavcodec     62. 11.100 / 62. 11.100
  libavformat    62.  3.100 / 62.  3.100
  libavdevice    62.  1.100 / 62.  1.100
  libavfilter    11.  4.100 / 11.  4.100
  libswscale      9.  1.100 /  9.  1.100
  libswresample   6.  1.100 /  6.  1.100
Input #0, wav, from &apos;260208_0033_processed.wav&apos;:
  Metadata:
    date            : 2026-02-08
    encoder         : Lavf62.3.100
    encoded_by      : TASCAM Portacapture X8
  Duration: 00:59:30.00, bitrate: 6144 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 192000 Hz, stereo, s16, 6144 kb/s
Stream mapping:
  Stream #0:0 -&amp;gt; #0:0 (pcm_s16le (native) -&amp;gt; mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to &apos;260208_0033_processed.mp3&apos;:
  Metadata:
    TDRC            : 2026-02-08
    TENC            : TASCAM Portacapture X8
    TSSE            : Lavf62.3.100
  Stream #0:0: Audio: mp3, 48000 Hz, stereo, s16p, 320 kb/s
    Metadata:
      encoder         : Lavc62.11.100 libmp3lame
[out#0/mp3 @ 0x55af036ddbc0] video:0KiB audio:139454KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.000742%
size=  139455KiB time=00:59:30.00 bitrate= 320.0kbits/s speed= 114x elapsed=0:00:31.42  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>About</title>
    <link>https://hm0008.hmiya.net/19700101000002_about</link>
    <guid>https://hm0008.hmiya.net/19700101000002_about</guid>
    <pubDate>Sun, 08 Feb 2026 04:46:24 GMT</pubDate>
    <description>&lt;h1&gt;About&lt;/h1&gt;
&lt;h2&gt;HM0008 について&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;個人的な備忘録をまとめる場所です&lt;/li&gt;
&lt;li&gt;このサイトの内容はすべて人間によって書かれています
&lt;ul&gt;
&lt;li&gt;ただし、文章作成のサポートとして LLM との共同作業を実施する場合があります&lt;/li&gt;
&lt;li&gt;文章作成者の言葉選びの癖を残します&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;興味・関心&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;サイバネティクス&lt;/li&gt;
&lt;li&gt;フェリックス・ガタリ&lt;/li&gt;
&lt;li&gt;庭&lt;/li&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;generative art (not produced by Generative AI)&lt;/li&gt;
&lt;li&gt;アンビエント&lt;/li&gt;
&lt;li&gt;フィールドレコーディング&lt;/li&gt;
&lt;li&gt;かたちと機能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Index</title>
    <link>https://hm0008.hmiya.net/19700101000001_public_index</link>
    <guid>https://hm0008.hmiya.net/19700101000001_public_index</guid>
    <pubDate>Sun, 08 Feb 2026 04:45:55 GMT</pubDate>
    <description>&lt;h1&gt;Index&lt;/h1&gt;
&lt;p&gt;このサイトについては &lt;a href=&quot;./19700101000002_about.html&quot;&gt;About&lt;/a&gt; を参照のこと。&lt;/p&gt;
&lt;h2&gt;Pages&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;./20260215172908.html&quot;&gt;HM0008 のホスティングについて&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20260209121615.html&quot;&gt;ベランダの音 (2026-02-08)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20251203225032.html&quot;&gt;ベランダの音 (2025-12-03)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20251123222653.html&quot;&gt;公園の音 (2025-11-22)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20250729204126.html&quot;&gt;Linux の LRU リストについてのメモ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20250726062302.html&quot;&gt;x86 Linux の reboot 処理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20250602211607.html&quot;&gt;Landlock を使ってみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20250525195722.html&quot;&gt;Raspberry Pi 5 向け Arch Linux イメージの作成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20250514172702.html&quot;&gt;『アンチ・オイディプス』第一章 わからんメモ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./20250512213143.html&quot;&gt;Seed Xiao nRF52840 + ZMK firmware についての備忘録&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>ベランダの音 (2025-12-03)</title>
    <link>https://hm0008.hmiya.net/20251203225032</link>
    <guid>https://hm0008.hmiya.net/20251203225032</guid>
    <pubDate>Wed, 03 Dec 2025 13:50:32 GMT</pubDate>
    <description>&lt;h1&gt;ベランダの音 (2025-12-03)&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;日時: 2025-12-03 15時ごろ&lt;/li&gt;
&lt;li&gt;場所: 部屋のベランダ&lt;/li&gt;
&lt;li&gt;音:
&lt;ul&gt;
&lt;li&gt;隣の公園からヒヨドリをはじめとした鳥の鳴き声&lt;/li&gt;
&lt;li&gt;航空機の音&lt;/li&gt;
&lt;li&gt;建物をまたいだ先にある幹線道路から自動車の音&lt;/li&gt;
&lt;li&gt;近所の方のバイク、自転車、声&lt;/li&gt;
&lt;li&gt;16 時近くになると放送される蛍の光&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コメント: 寒くなってきました&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20251203145135.jpg&quot; alt=&quot;窓越しに見えるレコーダー&quot; /&gt;&lt;/p&gt;
&lt;audio controls src=&quot;./assets/20251204210232.mp3&quot;&gt;
  Your browser does not support the audio element.
&lt;/audio&gt;
&lt;h2&gt;メモ&lt;/h2&gt;
&lt;p&gt;加工に用いた ffmpeg コマンド&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Get duration
$ ffprobe -i 251203_0015.wav -show_entries format=duration -v quiet -of csv=&quot;p=0&quot;
4107.648000
# Normalization, trimming and fades
$ ffmpeg -i 251203_0015.wav -ss 20 -to 4087.648 -af &quot;loudnorm=I=-20:TP=-2:LRA=11,afade=t=in:st=20:d=5,afade=t=out:st=4082.648:d=5&quot; 251203_0015_processed.wav -y
# Convert to mp3
$ ffmpeg -i 251203_0015_processed.wav -codec:a libmp3lame -b:a 320k 251203_0015_processed.mp3 -y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>公園の音 (2025-11-22)</title>
    <link>https://hm0008.hmiya.net/20251123222653</link>
    <guid>https://hm0008.hmiya.net/20251123222653</guid>
    <pubDate>Sun, 23 Nov 2025 13:26:53 GMT</pubDate>
    <description>&lt;h1&gt;公園の音 (2025-11-22)&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;録音日時: 2025-11-22 11時ごろ&lt;/li&gt;
&lt;li&gt;場所: 近所の公園&lt;/li&gt;
&lt;li&gt;コメント: 比較的大きな公園で、近くには鉄道が走っています。たまに落ち葉の落ちる音が聞こえるかもしれません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20251123223444.jpg&quot; alt=&quot;青空を背景に黄色の葉をつけた木&quot; /&gt;&lt;/p&gt;
&lt;audio controls src=&quot;./assets/20251123223103.mp3&quot;&gt;
  Your browser does not support the audio element.
&lt;/audio&gt;
&lt;h2&gt;メモ&lt;/h2&gt;
&lt;p&gt;フェードイン/アウト、音量調整、 mp3 出力をするスクリプト:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import os
import argparse
from pydub import AudioSegment


def add_fade(source: AudioSegment, in_ms: int, out_ms: int) -&amp;gt; AudioSegment:
    faded_audio = source.fade_in(in_ms).fade_out(out_ms)

    return faded_audio

def change_volume_by(source: AudioSegment, change_db: int) -&amp;gt; AudioSegment:
    return source + change_db

def export_wav(source: AudioSegment, file_name: str):
    source.export(file_name + &quot;.wav&quot;, format=&quot;wav&quot;)

def export_mp3(source: AudioSegment, file_name: str):
    source.export(file_name + &quot;.mp3&quot;, format=&quot;mp3&quot;)

def main():
    fade_duration = 2000  # 2 secconds

    parser = argparse.ArgumentParser()
    parser.add_argument(&quot;file_paths&quot;, nargs=&apos;+&apos;, help=&quot;File paths&quot;)

    args = parser.parse_args()
    filenames = args.file_paths

    for filename in filenames:
        try:
            print(f&quot;Processing {filename}...&quot;)
            audio = AudioSegment.from_wav(filename)

            audio = add_fade(audio, fade_duration, fade_duration)
            audio = change_volume_by(audio, 16)

            output_filename = f&quot;{os.path.splitext(filename)[0]}_processed&quot;
            export_mp3(audio, output_filename)
            
        except Exception as e:
            print(f&quot;Error processing {filename}: {e}&quot;)

if __name__ == &quot;__main__&quot;:
    main()

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Linux の LRU リストについてのメモ</title>
    <link>https://hm0008.hmiya.net/20250729204126</link>
    <guid>https://hm0008.hmiya.net/20250729204126</guid>
    <pubDate>Tue, 29 Jul 2025 11:41:26 GMT</pubDate>
    <description>&lt;h1&gt;Linux の LRU リストについてのメモ&lt;/h1&gt;
&lt;h2&gt;前提: Reclaimation&lt;/h2&gt;
&lt;p&gt;メモリは階層的に管理される。ページキャッシュは多くの場合 CPU キャッシュ (L1/L2/L3)、 RAM 、ディスク (の swap 領域) に保存される可能性がある。この階層は、上位の媒体ほど高速だが容量が小さく、下位ほど低速で容量が大きいという特徴がある。
頻繁に利用されるページキャッシュに高速でアクセスできるよう、 CPU キャッシュや RAM で保持したい。逆に、メモリが不足する場合は、アクセスしないページキャッシュをディスクに追い出す (evict) ことも必要となる。&lt;/p&gt;
&lt;h2&gt;Traditional Linux LRU lists&lt;/h2&gt;
&lt;p&gt;従来の kswapd は 2つの LRU リストを持つ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;active_list: すべてのプロセスの active なページキャッシュのリスト&lt;/li&gt;
&lt;li&gt;inactive_list: reclaim の候補となるページキャッシュのリスト&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ページキャッシュは allocate されると inactive_list に繋がれる。アクセスが発生すると active_list に移動される。 active_list の末尾の要素が inactive_list に移動することで reclaim の対象となる。
なお、 active_list -&amp;gt; inactive_list 移動の対象となったページキャッシュは、その参照などもチェックされ、たとえば対象ページへの参照があれば active_list に戻されたりするようだ。
単純な LRU リストではなく active_list / inactive_list の 2つのリストを使用している理由は、 reclaim してはならないページキャッシュと可能なそれを分けるためだと思われる。&lt;/p&gt;
&lt;p&gt;LRU-like な方法でうまくいかない場合があるとのこと。例えば:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;inactive_list にあるページが anonymous pages の場合。 anonymous ページを RAM からディスクへ swap するのはコピーする時間がかかる。もともとディスクにデータがある (例えば、プログラムコード) ページ (file-backed page) ではこの作業が必要ない。&lt;/li&gt;
&lt;li&gt;一つのプロセスが大量の file-backed page に書き込みを行った場合。書き込まれたページ (dirty page) の内容は、swap の前に本体のファイルに書き込まれる必要がある。その間にまたページへの書き込みが行われ、 active_list に戻ったりする。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;参考:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kernel.org/doc/gorman/html/understand/understand013.html&quot;&gt;Page Frame Reclamation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;次&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Multi-Gen LRU (MGLRU)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>カーネルコード探検: kmalloc()</title>
    <link>https://hm0008.hmiya.net/20250624211242</link>
    <guid>https://hm0008.hmiya.net/20250624211242</guid>
    <pubDate>Tue, 24 Jun 2025 12:12:42 GMT</pubDate>
    <description>&lt;h1&gt;カーネルコード探検: kmalloc()&lt;/h1&gt;
&lt;p&gt;Linux 6.12.y のソースを使う&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; git describe --contains
v6.12.34^0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;まず、 &lt;code&gt;kmalloc()&lt;/code&gt; の定義は &lt;code&gt;include/linux/slab.h&lt;/code&gt; にある:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;/**
 * kmalloc - allocate kernel memory
 * @size: how many bytes of memory are required.
 * @flags: describe the allocation context
 *
 * kmalloc is the normal method of allocating memory
 * for objects smaller than page size in the kernel.
 *
 * The allocated object address is aligned to at least ARCH_KMALLOC_MINALIGN
 * bytes. For @size of power of two bytes, the alignment is also guaranteed
 * to be at least to the size. For other sizes, the alignment is guaranteed to
 * be at least the largest power-of-two divisor of @size.
 *
 * The @flags argument may be one of the GFP flags defined at
 * include/linux/gfp_types.h and described at
 * :ref:`Documentation/core-api/mm-api.rst &amp;lt;mm-api-gfp-flags&amp;gt;`
 *
 * The recommended usage of the @flags is described at
 * :ref:`Documentation/core-api/memory-allocation.rst &amp;lt;memory_allocation&amp;gt;`
 *
 * Below is a brief outline of the most useful GFP flags
 *
 * %GFP_KERNEL
 *	Allocate normal kernel ram. May sleep.
 *
 * %GFP_NOWAIT
 *	Allocation will not sleep.
 *
 * %GFP_ATOMIC
 *	Allocation will not sleep.  May use emergency pools.
 *
 * Also it is possible to set different flags by OR&apos;ing
 * in one or more of the following additional @flags:
 *
 * %__GFP_ZERO
 *	Zero the allocated memory before returning. Also see kzalloc().
 *
 * %__GFP_HIGH
 *	This allocation has high priority and may use emergency pools.
 *
 * %__GFP_NOFAIL
 *	Indicate that this allocation is in no way allowed to fail
 *	(think twice before using).
 *
 * %__GFP_NORETRY
 *	If memory is not immediately available,
 *	then give up at once.
 *
 * %__GFP_NOWARN
 *	If allocation fails, don&apos;t issue any warnings.
 *
 * %__GFP_RETRY_MAYFAIL
 *	Try really hard to succeed the allocation but fail
 *	eventually.
 */
static __always_inline __alloc_size(1) void *kmalloc_noprof(size_t size, gfp_t flags)
{
	if (__builtin_constant_p(size) &amp;amp;&amp;amp; size) { // コンパイル時に size が判明しているか?
		unsigned int index;

		if (size &amp;gt; KMALLOC_MAX_CACHE_SIZE) // KMALLOC_MAX_CACHE_SIZE よりも大きい場合は、 slab cache で対応できないため
			return __kmalloc_large_noprof(size, flags); // さらに大きいサイズを確保できる内部関数へ

		// KMALLOC_MAX_CACHE_SIZE よりも小さく、つまり用意されている slab cache のサイズで対応できる場合は、
		index = kmalloc_index(size); // どのサイズの slab cache を使うか決める
		return __kmalloc_cache_noprof(
				kmalloc_caches[kmalloc_type(flags, _RET_IP_)][index],
				flags, size); // kmalloc_caches の 
	}

	// コンパイル時に確保するサイズが定まっていない場合
	return __kmalloc_noprof(size, flags);
}
#define kmalloc(...)				alloc_hooks(kmalloc_noprof(__VA_ARGS__)) // alloc_hooks については一旦保留
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;alloc_hooks()&lt;/code&gt; はデバッグ向けの機能を色々提供していそう。いったん飛ばす。&lt;/p&gt;
&lt;p&gt;最終的には &lt;code&gt;kmalloc_noprof(__VA_ARGS__)&lt;/code&gt; が呼ばれるようだ。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;kmalloc_noprof&lt;/code&gt; から呼び出される関数は、 3つに分岐する&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;__kmalloc_large_noprof&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__kmalloc_cache_noprof&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__kmalloc_noprof&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;__kmalloc_large_noprof&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;簡単に呼び出しグラフをまとめると、以下の通り:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mm/slab.c: __kmalloc_large_noprof()
    mm/slab.c: __kmalloc_large_node()
        mm/slab.c: __kmmaloc_large_node()
            get_order(size)
            alloc_pages_node_noprof() (inline)
                __alloc_pages_node_noprof() (inline)
                    __alloc_pages_noprof() // ページ確保の関数
            folio_address() // 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最終的には、ページアロケーションに用いられる &lt;code&gt;__alloc_pages_noprof&lt;/code&gt; にたどり着く。&lt;/p&gt;
&lt;p&gt;参考: ページアロケーションに用いられる API (&lt;code&gt;include/linux/gfp.h&lt;/code&gt; より):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#define alloc_pages(...)			alloc_hooks(alloc_pages_noprof(__VA_ARGS__))
#define alloc_pages_mpol(...)			alloc_hooks(alloc_pages_mpol_noprof(__VA_ARGS__))
#define folio_alloc(...)			alloc_hooks(folio_alloc_noprof(__VA_ARGS__))
#define folio_alloc_mpol(...)			alloc_hooks(folio_alloc_mpol_noprof(__VA_ARGS__))
#define vma_alloc_folio(...)			alloc_hooks(vma_alloc_folio_noprof(__VA_ARGS__))

#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ここでは触れないが、道中では以下のことも行っていた&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;trace_kmalloc()&lt;/code&gt;: デバッグ用の何か?&lt;/li&gt;
&lt;li&gt;NUMA のためのノード選択処理&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kasan_kmalloc_large()&lt;/code&gt;: KASAN の設定?&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kmemleak_alloc()&lt;/code&gt;: kmemleak のフック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kmsan_kmalloc_large()&lt;/code&gt;: KMSAN の設定?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;mm/slab.c&lt;/code&gt; より:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;/*
 * To avoid unnecessary overhead, we pass through large allocation requests
 * directly to the page allocator. We use __GFP_COMP, because we will need to
 * know the allocation order to free the pages properly in kfree.
 */
static void *___kmalloc_large_node(size_t size, gfp_t flags, int node)
{
	struct folio *folio;
	void *ptr = NULL;
	unsigned int order = get_order(size); // size を order に変換している (include/asm-generic/getorder.h 参照)

	if (unlikely(flags &amp;amp; GFP_SLAB_BUG_MASK))
		flags = kmalloc_fix_flags(flags);

	flags |= __GFP_COMP;
	folio = (struct folio *)alloc_pages_node_noprof(node, flags, order); // ページの確保
	if (folio) { // 確保できれば
		ptr = folio_address(folio); // folio からベースとなるアドレスを取得する
		lruvec_stat_mod_folio(folio, NR_SLAB_UNRECLAIMABLE_B,
				      PAGE_SIZE &amp;lt;&amp;lt; order);
	} // ページが確保できなければ ptr == NULL

	ptr = kasan_kmalloc_large(ptr, size, flags); // KASAN 向けの設定
	/* As ptr might get tagged, call kmemleak hook after KASAN. */
	kmemleak_alloc(ptr, size, 1, flags);
	kmsan_kmalloc_large(ptr, size, flags);

	return ptr;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GFP フラグの処理、メモリセキュリティ上の設定については無視すると、行っているのは以下:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;まず &lt;code&gt;get_order(size)&lt;/code&gt; で確保したいサイズを order (&lt;code&gt;2^(order) &amp;gt;= size&lt;/code&gt; となるような最も小さい値) に変換する。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alloc_pages_node_noprof()&lt;/code&gt; を呼び出す。この先でページの確保が走る。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;folio_address()&lt;/code&gt; で確保された領域のポインタを返す。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;alloc_pages_node_noprof()&lt;/code&gt; を追いかけると、 &lt;code&gt;__alloc_pages_noprof()&lt;/code&gt; にたどり着く&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mm/page_alloc.c&lt;/code&gt; より:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;/*
 * This is the &apos;heart&apos; of the zoned buddy allocator.
 */
struct page *__alloc_pages_noprof(gfp_t gfp, unsigned int order,
				      int preferred_nid, nodemask_t *nodemask)
{
	struct page *page;
	unsigned int alloc_flags = ALLOC_WMARK_LOW;
	gfp_t alloc_gfp; /* The gfp_t that was actually used for allocation */
	struct alloc_context ac = { };

	/*
	 * There are several places where we assume that the order value is sane
	 * so bail out early if the request is out of bound.
	 */
	if (WARN_ON_ONCE_GFP(order &amp;gt; MAX_PAGE_ORDER, gfp)) // 要求されるオーダーが MAX_PAGE_ORDER (一般的には 11) を超える場合は
		return NULL; // NULL を返す

	// [...]

	/* First allocation attempt */
	page = get_page_from_freelist(alloc_gfp, order, alloc_flags, &amp;amp;ac); // 一度目の要求
	if (likely(page))
		goto out;

	// [...]

	page = __alloc_pages_slowpath(alloc_gfp, order, &amp;amp;ac);

out:
	if (memcg_kmem_online() &amp;amp;&amp;amp; (gfp &amp;amp; __GFP_ACCOUNT) &amp;amp;&amp;amp; page &amp;amp;&amp;amp;
	    unlikely(__memcg_kmem_charge_page(page, gfp, order) != 0)) {
		__free_pages(page, order);
		page = NULL;
	}

	trace_mm_page_alloc(page, order, alloc_gfp, ac.migratetype);
	kmsan_alloc_page(page, order, alloc_gfp);

	return page;
}
EXPORT_SYMBOL(__alloc_pages_noprof);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コメントにもある通り、 zoned buddy allocator の心臓部。つまり &lt;code&gt;alloc_pages&lt;/code&gt; などのページアロケーション API の先で呼ばれる関数が、で呼ばれている。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get_page_from_freelist()&lt;/code&gt; が呼ばれ、失敗した場合は &lt;code&gt;__alloc_pages_slowpath()&lt;/code&gt; が呼ばれる。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get_page_from_freelist()&lt;/code&gt; もページ確保先のメモリゾーンの選定や、 watermark (ページを確保する余裕があるか否か) の検査などを行った後、実際にページを確保する。つまり zone ごとにある freelist から、 2^order サイズの page を取得する。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mm/page_alloc.c&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;/*
 * get_page_from_freelist goes through the zonelist trying to allocate
 * a page.
 */
static struct page *
get_page_from_freelist(gfp_t gfp_mask, unsigned int order, int alloc_flags,
						const struct alloc_context *ac)
{
	struct zoneref *z;
	struct zone *zone;
	struct pglist_data *last_pgdat = NULL;
	bool last_pgdat_dirty_ok = false;
	bool no_fallback;

	// [...]

	/*
	 * Scan zonelist, looking for a zone with enough free.
	 * See also cpuset_node_allowed() comment in kernel/cgroup/cpuset.c.
	 */
	// [...]
	for_next_zone_zonelist_nodemask(zone, z, ac-&amp;gt;highest_zoneidx,
					ac-&amp;gt;nodemask) { // ゾーンのリストを巡って、ページを確保しようとする

		// [...] // メモリのゾーン、 wartermark の検査

try_this_zone: // 問題なければ、ここにくる
		page = rmqueue(zonelist_zone(ac-&amp;gt;preferred_zoneref), zone, order,
				gfp_mask, alloc_flags, ac-&amp;gt;migratetype); // freelist から 2^order サイズの page を取得
		if (page) {
			prep_new_page(page, order, gfp_mask, alloc_flags); // ページの初期化

			// [...]

			return page; // ページを返す
		} else {
			// [...]
		}

		// [...]

	}

	return NULL; // ページを確保できない場合は、 NULL を返す
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;__alloc_pages_slowpath()&lt;/code&gt; でも何度かリトライする。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GFP フラグを調整する&lt;/li&gt;
&lt;li&gt;ひとつ大きい order を分割して、必要としている order の領域を作る&lt;/li&gt;
&lt;li&gt;メモリを reclaim する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は、 buddy allocator の標準的な方法である、&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;static inline struct page *
__alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
						struct alloc_context *ac)
{
	bool can_direct_reclaim = gfp_mask &amp;amp; __GFP_DIRECT_RECLAIM;
	bool can_compact = gfp_compaction_allowed(gfp_mask);
	bool nofail = gfp_mask &amp;amp; __GFP_NOFAIL;
	const bool costly_order = order &amp;gt; PAGE_ALLOC_COSTLY_ORDER;
	struct page *page = NULL;
	unsigned int alloc_flags;
	unsigned long did_some_progress;
	enum compact_priority compact_priority;
	enum compact_result compact_result;
	int compaction_retries;
	int no_progress_loops;
	unsigned int cpuset_mems_cookie;
	unsigned int zonelist_iter_cookie;
	int reserve_flags;

	// [...]

restart:

	// [...]

	/*
	 * For costly allocations, try direct compaction first, as it&apos;s likely
	 * that we have enough base pages and don&apos;t need to reclaim. For non-
	 * movable high-order allocations, do that as well, as compaction will
	 * try prevent permanent fragmentation by migrating from blocks of the
	 * same migratetype.
	 * Don&apos;t try this for allocations that are allowed to ignore
	 * watermarks, as the ALLOC_NO_WATERMARKS attempt didn&apos;t yet happen.
	 */
	if (can_direct_reclaim &amp;amp;&amp;amp; can_compact &amp;amp;&amp;amp;
			(costly_order ||
			   (order &amp;gt; 0 &amp;amp;&amp;amp; ac-&amp;gt;migratetype != MIGRATE_MOVABLE))
			&amp;amp;&amp;amp; !gfp_pfmemalloc_allowed(gfp_mask)) {
		page = __alloc_pages_direct_compact(gfp_mask, order,
						alloc_flags, ac,
						INIT_COMPACT_PRIORITY,
						&amp;amp;compact_result);
		if (page)
			goto got_pg;

		// [...]

	}

	// [...]

got_pg:
	return page;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Landlock を使ってみる</title>
    <link>https://hm0008.hmiya.net/20250602211607</link>
    <guid>https://hm0008.hmiya.net/20250602211607</guid>
    <pubDate>Mon, 02 Jun 2025 12:16:07 GMT</pubDate>
    <description>&lt;h1&gt;Landlock を使ってみる&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://landlock.io/&quot;&gt;Landlock&lt;/a&gt; はカーネルのセキュリティ機構。非特権でも、プロセスがアクセス可能なファイルパスや TCP ポートを制限できる。&lt;/p&gt;
&lt;p&gt;今回は、 Landlock を使って簡単な sandbox を作ってみた。&lt;/p&gt;
&lt;h2&gt;簡単なコードで試してみる&lt;/h2&gt;
&lt;p&gt;リポジトリ: &lt;a href=&quot;https://github.com/nohopium/smolock&quot;&gt;nohopium/smolock&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;読み取り権限のみ付与していることやネットワークの隔離に対応していないなど制限はあるが、とりあえず動くものができた。&lt;/p&gt;
&lt;h3&gt;テスト&lt;/h3&gt;
&lt;p&gt;例1: &lt;code&gt;/etc&lt;/code&gt; への権限を与えていないため、 &lt;code&gt;/etc&lt;/code&gt; への読み取りが拒否される&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ./target/debug/smolock -p /home/ ls -la /etc
ls: cannot open directory &apos;/etc&apos;: Permission denied
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例1: &lt;code&gt;/home&lt;/code&gt; への権限を与えると、問題なく実行できる&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ./target/debug/smolock -p /home/ ls -la /home
total 0
drwxr-xr-x 1    0    0   12 Dec 13  2023 .
drwxr-xr-x 1    0    0  138 May 15 11:06 ..
drwx--x--x 1 1000 1000 1226 Jun  6 08:21 hopium
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例2: 同じように、権限がなく拒否される&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ./target/debug/smolock head ./src/main.rs 
head: cannot open &apos;./src/main.rs&apos; for reading: Permission denied
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例2: 権限を付与すると、実行できる&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ./target/debug/smolock -p ./src/ head ./src/main.rs 
use std::{os::unix::process::CommandExt, path::PathBuf, process::Command};

use anyhow::Result;
use clap::Parser;
use which::which;

#[derive(Parser, Debug)]
struct Args {
    #[arg(short, long)]
    paths: Vec&amp;lt;PathBuf&amp;gt;,
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;いくつか備考&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;コマンド (実行ファイル) 実行時に要求されるファイル、例えば実行ファイルに動的リンクされる共有オブジェクトファイル、への読み取り権限がないと。
&lt;ul&gt;
&lt;li&gt;ワークアラウンドとして &lt;code&gt;/usr/lib&lt;/code&gt; に読み取り権限を与えている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; で指定されたパスに対して読み取り権限しか与えていないため、書き込み権限を要する場合は拒否される。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ./target/debug/smolock -p ./src/ rm ./src/main.rs 
rm: cannot remove &apos;./src/main.rs&apos;: Permission denied
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://landlock.io/&quot;&gt;Landlock の公式サイト&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;開発者による講演: &lt;a href=&quot;https://osseu2024.sched.com/event/1ej3a&quot;&gt;Linux Sandboxing with Landlock - OSS Europe 2024&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://landlock.io/talks/2024-09-17_landlock-oss.pdf&quot;&gt;スライド&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>Raspberry Pi 5 向け Arch Linux イメージの作成</title>
    <link>https://hm0008.hmiya.net/20250525195722</link>
    <guid>https://hm0008.hmiya.net/20250525195722</guid>
    <pubDate>Sun, 25 May 2025 10:57:22 GMT</pubDate>
    <description>&lt;h1&gt;Raspberry Pi 5 向け Arch Linux イメージの作成&lt;/h1&gt;
&lt;p&gt;Raspberry Pi 5 (RPi5) に Arch Linux ARM (ALARM) をインストールしたので、その手順を残す。&lt;/p&gt;
&lt;p&gt;ALARM は RPi5 に対応しておらず、 ALARM イメージをそのまま利用しても RPi5 はブートできない。今回は x86_64 のマシン上で ALARM イメージに chroot し、必要な設定を行うことでこれに対処する。&lt;/p&gt;
&lt;h2&gt;用意したもの&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ホスト: ブートメディアを作成するマシン。アーキテクチャは x86_64. ディストリビューションは Arch Linux (for x86_64).
&lt;ul&gt;
&lt;li&gt;必要であれば、 SD カードの読み書きができるデバイスも用意する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Raspberry Pi 5 (RPi5): 今回のターゲット環境。アーキテクチャは arm64.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ALARM の入手&lt;/h2&gt;
&lt;p&gt;Arch Linux ARM のページから入手可能&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ホストへのパッケージ追加&lt;/h2&gt;
&lt;p&gt;arm64 向けのイメージに chroot する際に利用するパッケージをインストールする。&lt;/p&gt;
&lt;p&gt;まずは、 aarch64 向けバイナリを動作させるのに必要なパッケージ。
binfmt によって aarch64 向けの実行バイナリが QEMU の aarch64 エミュレーション環境上で実行されるようになる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo pacman -S qemu-user-static qemu-user-static-binfmt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;systemd-binfmt サービスを動かしておく。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo systemctl start systemd-binfmt.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;arch-install-scripits も入れておく。 chroot の wrapper である arch-chroot を提供するパッケージで、 chroot の操作に加えて /etc/resolv.conf の bind mount を行う。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo pacman -S arch-install-scripts 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;SD カードパーティションの作成&lt;/h2&gt;
&lt;p&gt;fdisk を使って、 SD カード (今回は &lt;code&gt;/dev/sda&lt;/code&gt;) に boot パーティションと rootfs パーティションを作成する。&lt;/p&gt;
&lt;p&gt;fdisk では以下の設定をした:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;boot パーティションを 512MB で確保し、パーティションタイプを &lt;code&gt;W95 FAT32 (LBA)&lt;/code&gt; へ変更。&lt;/li&gt;
&lt;li&gt;残りのパーティションを rootfs 用に確保する。パーティションタイプの変更はなし。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下は、作業時のログ:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo fdisk /dev/sda
[...]
Command (m for help): o
Created a new DOS (MBR) disklabel with disk identifier 0x84c3e00f.
The device contains &apos;dos&apos; signature and it will be removed by a write command. See fdisk(8) man page and --wipe option for more details.

Command (m for help): p

Disk /dev/sda: 29.72 GiB, 31914983424 bytes, 62333952 sectors
Disk model: Multi-Card      
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x84c3e00f

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): 

Using default response p.
Partition number (1-4, default 1): 
First sector (2048-62333951, default 2048): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-62333951, default 62333951): +512M

Created a new partition 1 of type &apos;Linux&apos; and of size 512 MiB.

Command (m for help): t
Selected partition 1
Hex code or alias (type L to list all): c
Changed type of partition &apos;Linux&apos; to &apos;W95 FAT32 (LBA)&apos;.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 
First sector (1050624-62333951, default 1050624): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1050624-62333951, default 62333951): 

Created a new partition 2 of type &apos;Linux&apos; and of size 29.2 GiB.

Command (m for help): p
Disk /dev/sda: 29.72 GiB, 31914983424 bytes, 62333952 sectors
Disk model: Multi-Card      
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x84c3e00f

Device     Boot   Start      End  Sectors  Size Id Type
/dev/sda1          2048  1050623  1048576  512M  c W95 FAT32 (LBA)
/dev/sda2       1050624 62333951 61283328 29.2G 83 Linux

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ファイルシステムの作成&lt;/h2&gt;
&lt;p&gt;作成したパーティションのそれぞれに対して、 &lt;code&gt;mkfs&lt;/code&gt; でファイルシステムを作成する。&lt;/p&gt;
&lt;p&gt;boot 用に確保した &lt;code&gt;/dev/sda1&lt;/code&gt; には &lt;code&gt;mkfs.vfat&lt;/code&gt; 、 rootfs 用に確保した &lt;code&gt;/dev/sda2&lt;/code&gt; には &lt;code&gt;mkfs.ext4&lt;/code&gt; を用いた。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo mkfs.vfat /dev/sda1
&amp;gt; sudo mkfs.ext4 /dev/sda2
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;マウント&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/dev/sda1&lt;/code&gt;, &lt;code&gt;/dev/sda2&lt;/code&gt; を適当な場所にマウントする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; mkdir -p ./mount/root ./mount/boot

&amp;gt; sudo mount /dev/sda1 ./mount/boot/
&amp;gt; sudo mount /dev/sda2 ./mount/root/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ALARM イメージの書き込み&lt;/h2&gt;
&lt;p&gt;ダウンロードした ALARM イメージを、マウントされた rootfs 領域に書き込む。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo su
# tar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C ./mount/root/
tar: Ignoring unknown extended header keyword &apos;LIBARCHIVE.xattr.security.capability&apos;
tar: Ignoring unknown extended header keyword &apos;LIBARCHIVE.xattr.security.capability&apos;
# exit
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;chroot&lt;/h2&gt;
&lt;p&gt;マウントした rootfs に chroot する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo arch-chroot ./mount/root /bin/bash
[root@machine /]# 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pacman の初期化とパッケージ群のアップデートを行う。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# pacman-key --init
# pacman-key --populate archlinuxarm
# pacman -Syuu --noconfirm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;タイムアウトしたため、いくつかのミラーを有効化すると改善した。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-diff&quot;&gt;# diff -u /etc/pacman.d/mirrorlist.orig /etc/pacman.d/mirrorlist
--- /etc/pacman.d/mirrorlist.orig	2025-05-20 23:27:04.851321391 +0000
+++ /etc/pacman.d/mirrorlist	2025-05-20 23:29:27.156214459 +0000
@@ -33,16 +33,16 @@
 
 ### Japan
 ## Tokyo
-# Server = http://jp.mirror.archlinuxarm.org/$arch/$repo
+Server = http://jp.mirror.archlinuxarm.org/$arch/$repo
 
 ### Singapore
 # Server = http://sg.mirror.archlinuxarm.org/$arch/$repo
 
 ### Taiwan
 ## Hsinchu
-# Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo
+Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo
 ## New Taipei City
-# Server = http://tw.mirror.archlinuxarm.org/$arch/$repo
+Server = http://tw.mirror.archlinuxarm.org/$arch/$repo
 
 ### United Kingdom
 ## London
@@ -50,7 +50,7 @@
 
 ### United States
 ## California
-# Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo
+Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo
 ## Florida
 # Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo
 ## New Jersey
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;linux-rpi をインストールし、既存の linux-aarch64 を置き換える。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# pacman -Sy linux-rpi rpi5-eeprom --disable-sandbox
[...]
:: linux-rpi-6.12.28-1 and linux-aarch64-6.14.6-1 are in conflict (linux). Remove linux-aarch64? [y/N] y
[...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;RPi5 の boot に必要な .dtb が存在することを確認:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ls /boot/bcm2712-rpi-5-b.dtb 
/boot/bcm2712-rpi-5-b.dtb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;chroot を終了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# exit
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;boot パーティションの準備&lt;/h2&gt;
&lt;p&gt;rootfs の &lt;code&gt;/boot/&lt;/code&gt; ディレクトリの内容を boot パーティションにコピーする。
RPi5 は このパーティション (&lt;code&gt;/dev/sda1&lt;/code&gt;) を見てカーネル等をロードする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo cp -vr ./mount/root/boot/* ./mount/boot/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;アンマウント&lt;/h2&gt;
&lt;p&gt;SD カードのパーティションをアンマウントする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo sync
&amp;gt; sudo umount ./mount/root/ ./mount/boot/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで SD カードブートメディアの準備は完了となる。RPi5 に SD カードを挿して起動する。&lt;/p&gt;
&lt;h2&gt;参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-4&quot;&gt;Raspberry Pi 4 | Arch Linux ARM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/literatesnow/pi-5-archlinux-arm-encrypted-root&quot;&gt;Raspberry Pi 5 with Arch Linux ARM and Encrypted Root&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kiljan.org/2023/11/24/arch-linux-arm-on-a-raspberry-pi-5-model-b/&quot;&gt;Arch Linux ARM on a Raspberry Pi 5 Model B&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.vidalinux.org/index.php/Howto_install_archlinuxarm_raspberrypi5&quot;&gt;Howto install archlinuxarm raspberrypi5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/QEMU#Chrooting_into_arm/arm64_environment_from_x86_64&quot;&gt;Chrooting into arm/arm64 environment from x86_64 | ArchWiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>『アンチ・オイディプス』第一章 わからんメモ</title>
    <link>https://hm0008.hmiya.net/20250514172702</link>
    <guid>https://hm0008.hmiya.net/20250514172702</guid>
    <pubDate>Wed, 14 May 2025 08:27:02 GMT</pubDate>
    <description>&lt;h1&gt;『アンチ・オイディプス』第一章 わからんメモ&lt;/h1&gt;
&lt;p&gt;一か月ほど第一章を彷徨っているので、整理する。&lt;/p&gt;
&lt;h2&gt;第一節: 欲望的生産&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;連接や接続をともなう様々な機械がある。器官機械が源泉機械につながれる。ある機械は流れを発生させ、別の機械は流れを切断する。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;常に流れと切断がある。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;自然であれ社会であれ、そこには機械がある。機械は流れを発生させ、また切断を行う。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;葉緑素機械あるいは光合成機械であること、少なくとも、このような機械の中に自分の身体をひとつの部品として滑り込ませること。レンツは、人間と自然が区別される以前に、あるいはこの区別を条件とするあらゆる指標以前に身をおいたのだ。彼は自然を自然としてだけではなく、生産のプロセスとして生きる。もはや、ここには人間もなければ、自然もなく、ただ一方を他方の中で生産し、もろもろの機械を連結するプロセスだけがある。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;ある機械は別の機械によって生産される。それを連結する。そういうプロセスだけがある。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;自然 - 人間、自然 - 産業、自然 - 社会というこの弁別的関係は、社会の中にさえも「生産」「分配」「消費」と呼ばれる相対的に自律的な領域の区別を存在させる条件となっている。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;自然 - X の二項対立が存在することを条件として、「生産」「分配」「消費」の区別が存在する。
&lt;ul&gt;
&lt;li&gt;ここまでの話から、こうした区別が存在しないと主張したいことがわかる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;すなわち、生産はそのまま消費であり、登録なのである。登録と消費は直接に生産を規定しているが、しかも生産そのものの真っ只中で生産を規定している。だから、すべては生産なのだ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;はい。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;ここに存在するのは、生産の生産、つまり能動と受動の生産であり、登録の生産、つまり分配と指標の生産であり、消費の生産、享楽と不安と苦痛の生産なのである。すべてはまさに生産であるから、登録はただちに消費され消尽され、この消費は直接に再生産される。これがプロセスという言葉の第一の意味である。すなわち、登録と消費を生産そのものの中に組み込むこと、登録と消費を、同じひとつの過程の中の生産とみなすことである。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;生産の要素
&lt;ul&gt;
&lt;li&gt;生産の生産 = 能動と受動の生産&lt;/li&gt;
&lt;li&gt;登録の生産 = 分配と指標の生産&lt;/li&gt;
&lt;li&gt;消費の生産 = 享楽と不安と苦痛の生産&lt;/li&gt;
&lt;li&gt;プロセス = 生産-登録-消費 の生産&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;第二に、ここでは自然 - 人間の区別も存在しない。 … 因果や包含や表現などといった関係 (原因 - 結果、主観 - 客観) において捉えられるとしても、自然と人間は、相互に対面する二項のようなものではなく、むしろ唯一の同じ本質的な実在であり、生産するものと生産されるものは一体をなしているのだ。プロセスとしての生産は、あらゆる観念的カテゴリーをはみだすものであり、欲望を内在的原理としてひとつのサイクルを形成している。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;note: プロセスでは 自然 - X の二項対立が存在しない。プロセスでは生産するものと生産されるものを一体=サイクルとして捉える。そして欲望がプロセスの内在的原理となる。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;プロセスは、目標や目的と考えられてはならないし、プロセス自身を無限に継続することと混同されてもならない。プロセスの目的化、あるいはプロセスの無限の継続は、厳密にいえば、そのプロセスの早すぎる無謀な停止と同じことであり、 …&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;上はプロセスの第三の意味&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プロセスは終極であってはならない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;プロセスの条件:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生産-登録-消費の区別を行わない すべては生産&lt;/li&gt;
&lt;li&gt;生産者と生産物のサイクルで構成される&lt;/li&gt;
&lt;li&gt;プロセスが終極状態であってはならない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;分裂症的な特性とか、その臨床実体とかいったものは、何ら存在しない。分裂症とは生産し再生産する欲望機械の宇宙であり、「人間と自然をなす本質的実在」としての根源的な普遍的生産である。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;「欲望機械」が出てきた。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;「人間と自然をなす本質的実在」 = 根源的な普遍的生産&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;これは上で触れているプロセスと同じ?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;分裂症 = 生産し再生産する欲望機械の宇宙 = 根源的な普遍的生産&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;欲望機械は二項機械であり、二項的規則、あるいは連合的体制をそなえた機械である。ひとつの機械は常に他の機械と連結している。生産的総合すなわち、生産の生産は、「そして」 et 「そして次に」 et pruis… という接続的な形態をもっている。つまり、ここには常に流れを生産する機械と、この機械に接続されてこの流れを切断し採取する働きをするもうひとつの機械が存在する (…)。そしてまた、今度は第一の機械が別の機械に接続され、これに対して第一の機械が切断あるいは採取の行動をする。したがって、二項系列はあらゆる方向に線型状にのびてゆく。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;欲望機械 = et, et pruis で機械をつなぐ二項機械&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;あらゆる「対象」は流れの連続を前提とし、あらゆる流れは対象の断片化を前提としている。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;圏論みたい。 IIRC, 圏は対象と射から定義される
&lt;ul&gt;
&lt;li&gt;対象は射を前提とし、射は対象を前提とする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;おそらく、それぞれの〈器官機械〉は、自分自身の流れにしたがって、自分自身から流れ出すエネルギーにしたがって、世界全体を解釈する。眼はあらゆることを、 … 見るという言葉で解釈する。しかし、他の機械との間には、いつも接続の関係が、ある横断線によって設定される。この横断線を通じて、ひとつの機械は他の機械の流れを切断し、あるいは自分の流れが他の機械によって切断されるのを「見る」のである。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;機械への入力だけで、知覚する。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;それゆえ、〈流れ - 部分対象〉という接続的総合による連結は、また〈生産物 - 生産する働き〉という別の形態をもつことになる。生産する働きは、常に生産されるものに接木される。だからこそ、あらゆる機械が機械の機械であるように、欲望的生産は生産の生産なのだ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;あらゆる機械は機械の機械。&lt;/li&gt;
&lt;li&gt;欲望的生産は生産の生産。欲望機械は、機械を接続する。流れを生産する流れ。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;ここには、生産の働きとその生産物を区別する余地がない。少なくとも生産されたものは、自分自身の現場を新しい生産の働きの中にたずさえている。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;ここ = 分裂症者の机&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;レヴィ=ストロースは器用仕事を規定するとき、緊密に結びついた諸特性の総体としてそれを提案している。すなわち、多数のチグハグな、限られたストックやコードを具えていること、もろもろの断片を、たえず新しい断片化に導く能力をもつこと。したがって生産する働きと生産物は区別されず、用いる道具の全体と、実現すべき仕事の全体も区別されない。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;「器用仕事」には「ブリコラージュ」のルビあり&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bricolage c.f. 設計 design&lt;/li&gt;
&lt;li&gt;bricoleur: 利用可能なもので問題を解決するひと&lt;/li&gt;
&lt;li&gt;『野生の思考』&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;緊密に結びついた諸特性の総体&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多数のチグハグな、限られたストックやコードを具えている
&lt;ul&gt;
&lt;li&gt;ストック、コード?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;断片を、新しい断片化に導く
&lt;ul&gt;
&lt;li&gt;断片から別の断片をつくる&lt;/li&gt;
&lt;li&gt;かならずしもある断片をさらにちいさな断片に分解するものではない?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;用いる道具の全体と、実現すべき仕事の全体が区別されない
&lt;ul&gt;
&lt;li&gt;生産されたものが、次の生産のための道具になる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;たえず生産の働きを生産し、この生産の働きを生産物に接木してゆくという規則こそが、欲望機械、あるいは根源的な生産の特性なのである。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;欲望機械の特性 = 生産の働きを生産する。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;〈生産する働き〉〈生産物〉〈生産物と生産する働きの同一性〉……。この第三の同一性がまさに、線型状の系列の中に第三項を構成することになる。これは、未分化の巨大な対象である。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;〈生産物と生産する働きの同一性〉 = 生産されたものが、時間的に続く生産を行う
&lt;ul&gt;
&lt;li&gt;生産物は生産を行うというだけでいいのか、生産という trait なのか。それとも、生産物と生産する働きの型が一致するものなのか。よくわからない。特に指定がないかつここまでの文脈から、前者だと思っている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;〈生産物と生産する働きの同一性〉 = 「未分化の巨大な対象」。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;生産物と生産する働きの同一性:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;生産物は、すなわち生産する働きを持つ。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;trait Producer {
    fn produce() -&amp;gt; impl Producer {
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;生産物は、同じ型を生産する働きを持つ。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;struct ProductFoo {
}

impl ProductFoo {
    fn produce() -&amp;gt; Self {
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1 は普遍的に成り立ちそう
2 はいわゆる reproduction.&lt;/p&gt;
&lt;p&gt;わかった。「この第三の同一性がまさに、線型状の系列の中に第三項を構成することになる。これは、未分化の巨大な対象である。」はつまり、生産物はすなわち生産する働きとなる特性は、流れの生産-切断に、第三 (あるいはさらに第四, …) の項を繋いでいく役割を果たす。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ある純粋な流体が、自由状態で、途切れることなく、ひとつの充実身体の上を滑走しているのだ。欲望機械は、私たちに有機体を与える。ところが、この生産の真っ只中で、この生産そのものにおいて、身体は、組織される〔有機化される〕ことに苦しみ、つまり別の組織を持たないことを苦しんでいる。こうして過程の最中に、第三の契機として「不可解な、直立状態の停止」がやってくる。 … もろもろの自動機械装置は停止して、それらが分節していた非有機体的な塊を出現させる。この器官なき充実身体は、非生産的なもの、不毛なものであり、発生してきたものではなくて始めからあったもの、消費しえないものである。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;線形状の系列をなさない (生産/採取のない) 何かがある。それが器官なき身体。それは、自動機械装置が分節していた非有機体的な塊。&lt;br /&gt;
器官なき身体は、非生産的なもの (= 線形状の系列をなさない、生産過程に属しない) 不毛なもの (= 生産の働きをもたない)、発生してきたもの (= 生産物?) ではなくて始めからあったもの、消費しえないもの (= 切断-採取できないもの)&lt;/p&gt;
&lt;p&gt;この世のものはすべて関数だと思っている節が私にあるが、それは違うらしい。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;死の本能、これがこの身体の名前である。この死には、モデルがないわけではない。実際、欲望はこれもまた、死をもまた欲望するのである。なぜなら死の充実身体は、みずからは動かずして欲望を動かすものであるから。ちょうど生のもろもろの器官が作動する機械 working machine であるからこそ、欲望が生を欲望することになるように。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;生の器官が作動する機械であるから、欲望が生を欲望する。
死の充実身体は欲望を動かす、つまり、死は、複数の機械を 生産-採取の関係によって接続する。死そのものは何も生み出さないが、具体的な死は、流れを生み出すということ?
「生のもろもろの器官が作動する機械である」がわからない。生の機械とは?&lt;/p&gt;
&lt;p&gt;器官なき身体 = 死の本能 = 死そのもの = 死の概念?&lt;/p&gt;
&lt;h2&gt;第二節: 器官なき身体&lt;/h2&gt;
&lt;h2&gt;第三節: 主体と享受&lt;/h2&gt;
&lt;h2&gt;第四節: 唯物論的精神医学&lt;/h2&gt;
&lt;h2&gt;第五節: 欲望機械&lt;/h2&gt;
&lt;h2&gt;第六節: 全体と諸部分&lt;/h2&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
  <item>
    <title>nRF52840 + ZMK firmware の備忘録</title>
    <link>https://hm0008.hmiya.net/20250512213143</link>
    <guid>https://hm0008.hmiya.net/20250512213143</guid>
    <pubDate>Mon, 12 May 2025 12:31:43 GMT</pubDate>
    <description>&lt;h1&gt;nRF52840 + ZMK firmware の備忘録&lt;/h1&gt;
&lt;p&gt;nRF52840 + ZMK ファームウェアキーボードの習作として HM0011a を設計した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250509124935.jpg&quot; alt=&quot;HM0011a の写真&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;特徴&lt;/h2&gt;
&lt;p&gt;主な特徴は以下の通り:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;36 キー オーソリニア配列&lt;/li&gt;
&lt;li&gt;Seeed Xiao nRF52840 + ZMK firmware による無線化&lt;/li&gt;
&lt;li&gt;ドングルによるキーボード側の省力化&lt;/li&gt;
&lt;li&gt;リバーシブル基板によるコスト削減&lt;/li&gt;
&lt;li&gt;ケース厚 10mm, 全高 20mm&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設計時資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;KiCad&lt;/li&gt;
&lt;li&gt;参考キーボード
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/GEIGEIGEIST/TOTEM&quot;&gt;TOTEM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/carrefinho/forager&quot;&gt;forager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dilshod/36-choc-key-ortholinear-split&quot;&gt;1984 - 36 ortholinear split keyboard&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;リバーシブル基板での回路設計&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;バッテリー持続時間の目安
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zmk.dev/power-profiler&quot;&gt;Power Profiler&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;nice!nano v2 が nRF52840 搭載のボードなので、目安として使える&lt;/li&gt;
&lt;li&gt;ドングル仕様の場合には、キーボード側は peripheral となる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Seeed Xiao nRF52840
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.seeedstudio.com/XIAO_BLE/&quot;&gt;Getting Started with Seeed Studio XIAO nRF52840 Series&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ZMK firmware
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zmk.dev/docs&quot;&gt;Documentation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;ZMK はドキュメントが充実しているので、必要なことはだいたい書いてある。
&lt;ul&gt;
&lt;li&gt;例: 新しいボードの追加、ドングルの設定方法、キーマップの設定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ただし、 Zephyr についてはあまり書いていない。 Zephyr 由来の Kconfig や devicetree の概念も説明が薄い気がする。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/caksoylar/zmk-config&quot;&gt;caksoylar/zmk-config&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;ZMK 開発者の zmk-config&lt;/li&gt;
&lt;li&gt;参考として有用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/caksoylar/zmk-rgbled-widget&quot;&gt;caksoylar/zmk-rgbled-widget&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;同開発者の out-of-tree な LED ドライバモジュール&lt;/li&gt;
&lt;li&gt;ドライバ開発時に役立つかもしれない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/caksoylar/zmk-smart-toggle&quot;&gt;caksoylar/zmk-smart-toggle&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;同開発者の out-of-tree な behavior モジュール&lt;/li&gt;
&lt;li&gt;behavior の実装時に役立つかもしれない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ハードウェア設計時の工夫&lt;/h2&gt;
&lt;p&gt;当初の設計方針としては以下があった。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;分割無線&lt;/li&gt;
&lt;li&gt;36-key オーソリニア&lt;/li&gt;
&lt;li&gt;リバーシブル基板&lt;/li&gt;
&lt;li&gt;アクリル積層サンドイッチケース&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;XIAO nRF52840 を採用&lt;/h3&gt;
&lt;p&gt;分割無線方式を採用したキーボードの設計は経験がなかったため、これを実現するためのハードウェア・ソフトウェアスタックで冒険するつもりはなかった。&lt;/p&gt;
&lt;h3&gt;リバーシブル基板&lt;/h3&gt;
&lt;p&gt;また、リバーシブル基板を採用した。リバーシブル基板により、一枚の基板の表裏を入れ替えることで左手用の基板としても右手用のそれとしても使用できる。&lt;/p&gt;
&lt;p&gt;利点としては製造費用の低減があり、小ロットでは左右で2種の別デザイン基板を製造するよりも安上がりになる。&lt;/p&gt;
&lt;p&gt;欠点としては複雑性の増加がある。今回の設計では、 XIAO nRF52840 のピン配置とキーボード基板のパッドの対応関係に注意する必要があった。 XIAO nRF52840 を左手側にはんだ付けする場合でも、右手側にはんだ付けする場合でも、 デジタル IO ピンが Col/Row へ接続されるよう設計した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;assets/20250514072746.png&quot; alt=&quot;XIAO nRF52840 周りの schematic&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;アクリルプレート&lt;/h3&gt;
&lt;p&gt;アクリル層も KiCad で設計した。アクリルプレートは Kicad で設計すると 基板との整合性を取りやすい。最終的に KiCad 内で DXF と PDF に変換して発注した。&lt;/p&gt;
&lt;p&gt;トッププレート:
&lt;img src=&quot;./assets/20250514123511.png&quot; alt=&quot;トッププレート&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ミドルプレート:
&lt;img src=&quot;./assets/20250514123419.png&quot; alt=&quot;ミドルプレート&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ボトムプレート:
&lt;img src=&quot;./assets/20250514123446.png&quot; alt=&quot;ボトムプレート&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ZMK 設定時の工夫&lt;/h2&gt;
&lt;p&gt;特徴的な部分は多くないが、あえて挙げるのであれば、ドングルを採用した点にある。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://zmk.dev/docs/development/hardware-integration/dongle&quot;&gt;Keyboard Dongle&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;次回のアイデアメモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;有線 / 無線切り替え
&lt;ul&gt;
&lt;li&gt;有線は type-c&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;電池容量の削減
&lt;ul&gt;
&lt;li&gt;Power profiler 上では 200mAh で 5ヶ月になるので、十分すぎる
&lt;ul&gt;
&lt;li&gt;100mAh でも 3ヶ月&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HM0002 配列への回帰?&lt;/li&gt;
&lt;li&gt;hotswap ソケット対応&lt;/li&gt;
&lt;li&gt;choc v2 系スイッチ対応&lt;/li&gt;
&lt;li&gt;発売されていれば, Xiao nRF52840 Plus 対応&lt;/li&gt;
&lt;li&gt;3Dプリンタを導入していれば、3Dプリンタケース&lt;/li&gt;
&lt;li&gt;OLED 付きドングル&lt;/li&gt;
&lt;li&gt;XIAO nRF52840 用のパッドを、表面実装を利用して裏表で別のアサインにすれば、ソフトウェア側がややこしいことにならずに済みそう
&lt;ul&gt;
&lt;li&gt;左右有線接続時の UART pin も共通化できる&lt;/li&gt;
&lt;li&gt;欠点: はんだ付け時の固定が大変かも&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#public&lt;/p&gt;
</description>
  </item>
</channel>
</rss>
