<?xml version="1.0" encoding="utf-8"?>

<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:cc="http://web.resource.org/cc/"
  xmlns="http://purl.org/rss/1.0/">

<channel rdf:about="http://aimingoff.way-nifty.com/blog/">
<title>Aiming Off のブログ</title>
<link>http://aimingoff.way-nifty.com/blog/</link>
<description>オッサンの IT ライフ</description>
<dc:language>ja-JP</dc:language>
<dc:creator></dc:creator>
<dc:date>2026-02-11T18:49:10+09:00</dc:date>


<items>
<rdf:Seq><rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2026/02/post-0e91a3.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2023/03/post-f8ede5.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2023/03/post-11b9d6.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2022/10/post-1de1cf.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2022/09/post-824044.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2022/02/post-93e534.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2021/10/post-d5c437.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2021/06/post-880af6.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2020/05/post-180834.html" />
<rdf:li rdf:resource="http://aimingoff.way-nifty.com/blog/2019/12/post-498553.html" />
</rdf:Seq>
</items>

</channel>

<item rdf:about="http://aimingoff.way-nifty.com/blog/2026/02/post-0e91a3.html">
<title>Docker で AMD GPU を使う</title>
<link>http://aimingoff.way-nifty.com/blog/2026/02/post-0e91a3.html</link>
<description>AMD GPU 環境で Docker を使い大規模言語モデル (LLM) を実行する方法</description>
<content:encoded><![CDATA[<p>2022 年に <a href="/blog/2022/10/post-1de1cf.html">コンテナで GUI / GPU を使う</a> という記事を書いたが、その後だいぶ状況は変わってきている <br />
当時は AMD GPU でできることが限られていたが、現在は <a href="https://rocm.docs.amd.com/">ROCm</a> のレベルが上がってきており NVIDIA じゃなければダメ…とは言えなくなってきている <br />
改めて現時点で AMD GPU でできることをおさらいしておく
（今 GPU やメモリが高騰しているしね…）</p>

<p>ここでは以下のような環境を前提にしている。</p>

<ul>
<li>ホスト OS: Debian 13 (trixie)</li>
<li>Kernal: 6.18.5 (trixie-backports)</li>
</ul>

<p>参考: <a href="https://dev.classmethod.jp/articles/local-llm-guide-2026/">2026年のローカルLLM事情を整理してみた</a></p>
]]><![CDATA[<h4>Ollama</h4>

<p><a href="https://ollama.com/">Ollama</a> は手軽にオープンソース大規模言語モデル（LLM）を起動・管理できるプラットフォーム</p>

<p><a href="https://hub.docker.com/r/ollama/ollama">オフィシャルの Docker image</a> を使ってもいいし
GitHub に置いた <a href="https://github.com/aimoff/ollama-docker">ollama-docker</a> を使ってもいい</p>

<p>私は <a href="https://glmocr.com/">GLM-OCR</a> を試すために Ollama を使ってみたが、非常に簡単に使うことができた <br />
<a href="https://github.com/aimoff/ollama-docker">ollama-docker</a> を使うならば以下のようにすればすぐに使える</p>

<pre><code>$ docker compose exec ollama ollama run glm-ocr</code></pre>

<h4>llama.cpp</h4>

<p><a href="https://github.com/ggml-org/llama.cpp">llama.cpp</a> は Ollama よりは使い勝手が良くないが、
チューニングをすることで Ollama よりも高速にオープンソース大規模言語モデル（LLM）を実行できる</p>

<p><a href="https://github.com/ggml-org/llama.cpp/blob/master/docs/docker.md">オフィシャルの Docker image</a> に ROCm 版があるのでそのまま使うこともできるが、
多少使い勝手を改善したものを GitHub の <a href="https://github.com/aimoff/llama-cpp-docker">llama-cpp-docker</a> に置いた</p>

<p>Ollama では GPU の VRAM 容量により実行できるモデルに制限を受けるが、
llama.cpp は CPU MeE Offloading により限られた VRAM でも大規模 MoE モデルを実用的な速度で動かすことができる <br />
<a href="https://zenn.dev/ftl/articles/ed44841ab4f644">ローカルLLMを試す</a> に NVIDIA GPU を使った例が出ている</p>

<p>私も同様のことを試したが、自分の環境は APU と dGPU の両方が搭載されており、ちょっと違う状況がになった</p>

<p>元々 APU は VRAM ではなく CPU 側のメモリを扱えるようになっているため、
<code>--cpu-moe</code> や <code>--n-cpu-moe</code> を指定するとかえって効率が落ちてしまう結果となった <br />
<code>--split-mode</code> を <code>none</code> にして dGPU だけで処理するようにすると想定した動きをしているように見える</p>

<p>試行回数が少ないので性能的なところははっきりしないが、
MoE を使わず遅い APU 側の負荷が大きくなっても遜色ない性能が出ているようには見える <br />
ここで試したモデルは gpt-oss-20b なので、もっと大容量の VRAM を必要とするモデルならば差が出てくるかもしれない</p>

<h5>MoE 関連パラメタ無し</h5>

<pre><code>[ Prompt: 188.9 t/s | Generation: 25.1 t/s ]

| memory breakdown [MiB] | total    free     self   model   context   compute       unaccounted |
|   - ROCm0 (RX 6600M)   |  8176 =  2118 + ( 5760 =  3454 +    1030 +    1276) +            297 |
|   - ROCm1 (680M)       | 15683 = 12867 + (10491 =  7495 +    2060 +     935) + 17592186036740 |
|   - Host               |                   1628 =   586 +       0 +    1041                   |
</code></pre>

<h5><code>--cpu-moe</code> (<code>LLAMA_ARG_CPU_MOE=1</code>)</h5>

<pre><code>[ Prompt: 105.9 t/s | Generation: 17.9 t/s ]

| memory breakdown [MiB] | total    free     self   model   context   compute       unaccounted |
|   - ROCm0 (RX 6600M)   |  8176 =  6146 + ( 1734 =   245 +    1031 +     456) +            295 |
|   - ROCm1 (680M)       | 15683 = 18944 + ( 3453 =   996 +    2058 +     398) + 17592186037701 |
|   - Host               |                  11218 = 10949 +       0 +     268                   |
</code></pre>

<h5><code>--n-cpu-moe 12</code> (<code>LLAMA_ARG_N_CPU_MOE=12</code>)</h5>

<pre><code>[ Prompt: 99.6 t/s | Generation: 19.7 t/s ]

| memory breakdown [MiB] | total    free    self   model   context   compute       unaccounted |
|   - ROCm0 (RX 6600M)   |  8176 =  6174 + (1705 =   218 +    1030 +     456) +            296 |
|   - ROCm1 (680M)       | 15683 = 16112 + (8335 =  5877 +    2060 +     398) + 17592186035651 |
|   - Host               |                  6036 =  5768 +       0 +     268                   |
</code></pre>

<h5><code>--split-mode none --main-gpu 0 --n-cpu-moe 12</code><br /> (<code>LLAMA_ARG_SPLIT_MODE=none LLAMA_ARG_MAIN_GPU=0 LLAMA_ARG_N_CPU_MOE=12</code>)</h5>

<pre><code>[ Prompt: 198.3 t/s | Generation: 29.9 t/s ]

| memory breakdown [MiB] | total   free    self   model   context   compute    unaccounted |
|   - ROCm0 (RX 6600M)   |  8176 =  930 + (6950 =  6095 +     456 +     398) +         295 |
|   - Host               |                 5817 =  5768 +       0 +      49                |
</code></pre>

<h5>追試</h5>

<p>やはりモデルによっては圧倒的に dGPU で MoE を使った方が速い</p>

<p>最初に試した Qwen3-30B-A3B:Q8_0 では:</p>

<ul>
<li>MoE 無し: モデルロード時にエラー</li>
<li><code>--cpu-moe</code> : モデルロードには成功するが、プロンプト入力後システムが激重になって動作不能 <br />
恐らく MoE も APU も同じメモリ資源をピンポンしていて swap 出まくりになったと思われる (<code>--cpu-moe</code> を調べる価値は無さそう)</li>
</ul>

<pre><code>     model      |                   no MoE                     | --split-mode none --main-gpu 0 --n-cpu-moe 12
Qwen3-8B:Q8_0   | [ Prompt: 215.1 t/s | Generation:  9.0 t/s ] |          モデルロード時にエラー
Qwen3-8B:Q4_K_M | [ Prompt: 196.7 t/s | Generation: 13.2 t/s ] | [ Prompt: 427.8 t/s | Generation: 34.5 t/s ]
Qwen3-4B:Q8_0   | [ Prompt: 266.6 t/s | Generation: 16.3 t/s ] | [ Prompt: 864.0 t/s | Generation: 40.5 t/s ]
</code></pre>

<h4>PyTorch on ROCm</h4>

<p><a href="https://pytorch.org/">pyTorch</a> もオフィシャルで <a href="https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/3rd-party/pytorch-install.html">ROCm 対応</a> が進んでいるので、割といろんなものが動かせるようになっている</p>

<p><a href="https://hub.docker.com/r/rocm/pytorch">オフィシャルの Docker image</a> を使う手もあるが、
このイメージでは pyTorch が <code>/opt/venv</code> という扱いにくい場所にインストールされている（pip で Python パッケージを追加インストールする際にも Docker インスタンス内の <code>/opt/venv</code> 配下に入れることになる）ため、
以前書いた <a href="https://github.com/aimoff/ROCm-docker">ROCm-docker</a> 上で pyTorch をインストールする方がベター</p>

<p>ROCm-docker を使う場合には以下のようにして pyTorch をインストールする</p>

<pre><code>$ docker compose run --rm devterm</code></pre>

<pre><code>$ ROCM_VER=7.1
$ GFX_ARCH=gfx103X-dgpu
$ python3 -m venv torch
$ . torch/bin/activate
(torch) $ pip install uv
(torch) $ uv pip install torch torchvision torchaudio \
        --index-url https://download.pytorch.org/whl/rocm${ROCM_VER} \
        --extra-index-url https://rocm.nightlies.amd.com/v2/${GFX_ARCH}
</code></pre>

<p>【追記】
現在の私の <a href="https://github.com/aimoff/ROCm-docker">ROCm-docker</a> はマルチステージ Dockerfile に変更するとともに <a href="https://docs.astral.sh/uv/">uv</a> コマンドを devterm service のコンテナイメージに含めている <br />
uv を使う場合には以下のようにすればいい</p>

<pre><code>$ ROCM_VER=7.1
$ GFX_ARCH=gfx103X-dgpu
$ uv venv torch
$ . torch/bin/activate
(torch) $ uv pip install torch torchvision torchaudio \
        --index-url https://download.pytorch.org/whl/rocm${ROCM_VER} \
        --extra-index-url https://rocm.nightlies.amd.com/v2/${GFX_ARCH}
</code></pre>

<p><code>ROCM_VER</code> と <code>GFX_ARCH</code> はバージョンや環境に合わせて変更する <br />
<code>GFX_ARCH</code> はオフィシャルの pyTorch でサポートしていない GPU のために追加するコンポーネントであり、
どういう種類のものがあるかは <a href="https://rocm.nightlies.amd.com/v2/">https://rocm.nightlies.amd.com/v2/</a> を参照 <br />
自分の環境の AMD GPU のアーキが何であるかは <code>rocminfo</code> コマンドで確認できる</p>

<pre><code>$ rocminfo | grep gfx
  Name:                    gfx1031                            
      Name:                    amdgcn-amd-amdhsa--gfx1031       
</code></pre>

<p>オフィシャルの pyTorch でサポートしている GPU アーキであれば <code>GFX_ARCH</code> の指定や <code>--extra-index-url</code> の指定は必要ない <br />
そうでない場合は表示されたものに近い GPU アーキのものを指定する</p>
]]></content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>
<dc:subject>Linux</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2026-02-11T18:49:10+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2023/03/post-f8ede5.html">
<title>FreeDOS で SATA 接続 CD/DVD が利用可能に</title>
<link>http://aimingoff.way-nifty.com/blog/2023/03/post-f8ede5.html</link>
<description>Jemm がアップデートされ Jemm Loadable Module (JLM) という 32bit protected-mode のデバイスドライバや TSR を拡張メモリにロードできるようになり、 FreeDOS でも SATA 接続 CD/DVD ドライブが使えるようになった。</description>
<content:encoded><![CDATA[<p><a href="http://www.freedos.org/">FreeDOS</a> で拡張メモリを使うために必要な重要コンポーネントの <a href="https://github.com/Baron-von-Riedesel/Jemm">Jemm</a> が昨年 12 月 v5.83 にアップデートされた。
実はこのバージョンで大きな機能追加がされていることに今更ながら気づいた。</p>

<p>Jemm Loadable Module (JLM) という 32bit protected-mode のデバイスドライバや TSR を拡張メモリにロードできるようになった。
この JLM 実装の例として CD/DVD ドライバが同梱された。
今まで SATA 接続の CD/DVD ドライブ用ドライバは安定的に動くものがほとんど無く、特に私のような AMD の Chipset で動くものは皆無だった。
そこに新たに JLM 版の AHCICD ドライバが登場したことで、ようやく安定的に SATA 接続 CD/DVD にアクセスできるようになった。</p>

<p><a href="https://aimingoff.way-nifty.com/.shared/image.html?/photos/uncategorized/jlmcdrom.png" class="mb"><img border="0" alt="JLM-CDROM" title="JLM-CDROM" style="display: block; margin: auto;" src="https://aimingoff.way-nifty.com/blog/images/jlmcdrom.png" width="300" height="223"></a></p>

<p>例によって修正後の自分の FreeDOS/V 環境を晒しておく。</p>
]]><![CDATA[<h4>FreeDOS/V 起動フロッピーイメージ</h4>

<p><a href="/blog/2022/02/post-93e534.html">FreeDOS 1.3 リリースに関する記事</a> や <a href="/blog/2021/06/post-880af6.html">kernel と FreeCOM アップデートの記事</a> から少し構成を変更し、
<code>\FDOS\JP</code> ディレクトリへ DBCS 版 FreeCOM 以外に日本語関連のドライバ (<code>FDCONFIG.SYS</code> の中から呼ぶもの) を入れるようにした。
本当は <code>FDCONFIG.SYS</code> から呼ぶドライバは全部 <code>\FDOS\BIN</code> から別のディレクトリに移したかったが、とりあえず他はそのまま。</p>

<p><a href="https://github.com/Baron-von-Riedesel/Jemm/releases">Jemm Releases</a> の v5.83 に同梱されている <code>AHCICD.DLL</code> と <code>XCDROM32.DLL</code> を <code>\FDOS\JLM</code> ディレクトリに格納。</p>

<pre><code>A:\
|  KERNEL.SYS
|  COMMAND.COM
|  AUTOEXEC.BAT
|  FDCONFIG.SYS
|  
\--FDOS
   +--BIN
   |  ...
   |     
   +--XMSSWAP
   |     COMMAND.COM
   |     
   +--JP
   |     COMMAND.COM
   |     FONTN.INI
   |     FONTNX.EXE
   |     04GZN16X.FNT
   |     GURI16X.FNT
   |     GURI19X.FNT
   |     PANSI.SYS
   |     
   \--JLM
         AHCICD.DLL
         XCDROM32.DLL
</code></pre>

<p>ディスクスペースに余裕が無くなってきたため <code>DISPVB.EXE</code> 等いくつかファイルを削っている。</p>

<pre><code> Directory of A:\FDOS\BIN

[.]            [..]           ATTRIB.COM     CHEJ.EXE       CHKDSK.EXE     
COUNTRY.SYS    CP437UNI.TBL   CP932UNI.TBL   CPUID.EXE      CPUSTAT.EXE    
CWSDPMI.EXE    DELTREE.COM    DEVLOAD.COM    DISPV.EXE      DISPVA.EXE     
DOSLFN.COM     DSP4U.COM      DSPVV.COM      EIDL.COM       EMSSTAT.EXE    
FDAPM.COM      FDISK.EXE      FDISK.INI      FDISKPT.INI    FORMAT.EXE     
JEMMEX.EXE     JLOAD.EXE      KEYB.EXE       KEYBOARD.SYS   LABEL.EXE      
MEM.EXE        MEMSTAT.EXE    MI.COM         MODE.COM       MORE.EXE       
MOVE.EXE       MOVEXBDA.EXE   NANSI.SYS      SETVER.SYS     SHSUCDX.COM    
SYS.COM        TREE.COM       UMBM.EXE       V.COM          VASK.COM       
VCHKBOX.COM    VCHOICE.COM    VCLS.COM       VCPI.EXE       VCURSOR.COM    
VDELAY.COM     VDELETE.COM    VEACH.COM      VECHO.COM      VERRLVL.COM    
VFDUTIL.COM    VFONT.COM      VFRAME.COM     VGOTOXY.COM    VINFO.COM      
VINSERT.COM    VLINE.COM      VMATH.COM      VMODE.COM      VPAUSE.COM     
VPCSPKR.COM    VPROGRES.COM   VREADKEY.COM   VSTR.COM       VVER.COM       
VVIEW.COM      XCOPY.EXE      XMSSTAT.EXE    
        71 file(s)        669,028 bytes
         2 dir(s)          48,128 bytes free
</code></pre>

<h4><code>FDCONFIG.SYS</code></h4>

<p>ディレクトリ構成変更に追従して若干変更。
JEMMEX 使用を前提として <code>UMBPCI.SYS</code> は完全に外す。</p>

<pre><code>;!SWITCHES=/F
!COUNTRY=081,,\FDOS\BIN\COUNTRY.SYS
!LASTDRIVE=Z
!BUFFERS=20
!FILES=40

!MENUCOLOR=7,1
MENU  FreeDOS
MENU ----------------------------------------------------------------------
MENU   0 - Safe Mode (don't load any drivers)
MENU   1 - XMS
MENU   2 - XMS + EMS
MENU   3 - Japanese + XMS
MENU   4 - Japanese + XMS + EMS
MENU   5 - Japanese + XMS + DPMI
MENU ----------------------------------------------------------------------
MENUDEFAULT=3,10

0? ECHO Warning: basic stuff only!

12345? DOS=HIGH
12345? DOS=UMB
12345? DOSDATA=UMB
135? DEVICE=\FDOS\BIN\JEMMEX.EXE NOEMS X=TEST I=TEST
24?  DEVICE=\FDOS\BIN\JEMMEX.EXE X=TEST I=TEST
345? DEVICEHIGH=\FDOS\JP\FONTNX.EXE
;12?  DEVICEHIGH=\FDOS\BIN\NANSI.SYS /S
;345? DEVICEHIGH=\FDOS\JP\PANSI.SYS
0?   SHELL=A:\COMMAND.COM A:\ /E:1024 /P=A:\AUTOEXEC.BAT
12?  SHELLHIGH=A:\FDOS\XMSSWAP\COMMAND.COM A:\FDOS\XMSSWAP /E:1024 /P=A:\AUTOEXEC.BAT
345? SHELLHIGH=A:\FDOS\JP\COMMAND.COM A:\FDOS\JP /E:1024 /P=A:\AUTOEXEC.BAT
</code></pre>

<h4><code>AUTOEXEC.BAT</code></h4>

<p>Safe mode 以外ではどの CD/DVD ドライバを使うかを選択するように変更。
SATA 接続の場合には AHCICD を、仮想マシンも含め ATA/IDE 接続する場合には XCDROM を選択する。
日本語ディスプレイドライバの選択とは異なり、実際にドライバをロードしてみてエラーしたら再度 CD/DVD ドライバ選択画面に戻る。</p>

<pre><code>@echo off
SET LANG=
SET TZ=JST-9

SET DOSDIR=A:\FDOS
SET PATH=%DOSDIR%\BIN
if not exist C:\FDOS\BIN\HELP.EXE goto FDONLY
SET DOSDIR=C:\FDOS
SET PATH=%DOSDIR%\BIN;%PATH%

if exist %DOSDIR%\NLS\CHOICE.EN SET NLSPATH=%DOSDIR%\NLS
if exist %DOSDIR%\HELP\COMMAND.EN SET HELPPATH=%DOSDIR%\HELP
SET TEMP=%DOSDIR%\TEMP
SET TMP=%TEMP%
:FDONLY

if "%CONFIG%"=="0" goto END

loadhigh FDAPM ADV:REG
loadhigh KEYB JP,932,%DOSDIR%\BIN\KEYBOARD.SYS

if "%CONFIG%"=="1" goto CDROM
if "%CONFIG%"=="2" goto CDROM
if not "%CONFIG%"=="5" goto JP

:DPMI
loadhigh CWSDPMI -p
if exist %DOSDIR%\djgpp\bin\cat.exe SET PATH=%PATH%;%DOSDIR%\djgpp\bin

:JP
vframe /x14 /y8 /h10 /w52 /fBlack /bGray Single Shadow
vecho
vecho /fBlue "  Which driver do you want to use for Japanese?"
vline hidden
vecho "  V: DSPVV"
vecho "  D: DISPV"
vecho "  A: DISPVA"
vecho "  No display driver to load for now."
vchoice /fLightGreen /bBlack /t10 /d1
set choice=%errorlevel%
vgotoxy eot
verrlvl %choice%
set choice=
if errorlevel 4 goto CDROM
if errorlevel 3 goto DISPVA
if errorlevel 2 goto DISPV

:DSPVV
loadhigh DSPVV
goto JP2

:DISPV
loadhigh DISPV /HS=on
goto JP2

:DISPVA
loadhigh DISPVA /HS=on
goto JP2

:JP2
CHEJ JP
rem loadhigh DSP4U /VD=71

:CDROM
if not exist %DOSDIR%\BIN\JLOAD.EXE goto COMMON
if not exist %DOSDIR%\BIN\SHSUCDX.COM goto COMMON
vframe /x14 /y8 /h9 /w52 /fBlack /bGray Hidden Shadow
vecho
vecho /fBlue "  Which driver do you want to use for CD/DVD?"
vline hidden
vecho "  A: AHCICD"
vecho "  X: XCDROM"
vecho "  No CD/DVD driver to load for now."
vchoice /fLightGreen /bBlack /t10 /d3
set choice=%errorlevel%
cls
verrlvl %choice%
set choice=
if errorlevel 3 goto COMMON
if errorlevel 2 goto XCDROM32

:AHCICD
if not exist %DOSDIR%\JLM\AHCICD.DLL goto CDROM
DEVLOAD /H /Q %DOSDIR%\BIN\JLOAD.EXE %DOSDIR%\JLM\AHCICD.DLL /D:AHCICD$$ /R
if errorlevel 1 goto CDROM
goto CDLETTER

:XCDROM32
if not exist %DOSDIR%\JLM\XCDROM32.DLL goto CDROM
DEVLOAD /H /Q %DOSDIR%\BIN\JLOAD.EXE %DOSDIR%\JLM\XCDROM32.DLL /D:XCDROM$$
if errorlevel 1 goto CDROM

:CDLETTER
rem SHSUCDX /QQ /D3
SHSUCDX /QQ /~ /D:?AHCICD$$,Q /D:?XCDROM$$,Q

:COMMON
rem loadhigh DOSLFN
rem loadhigh RDISK /S80 /:R
rem loadhigh CTMOUSE

:END
SET DIRCMD=/P /OGN /Y
rem SET COPYCMD=/-Y
alias reboot=fdapm warmboot
alias reset=fdisk /reboot
alias halt=fdapm acpioff
alias shutdown=fdapm acpioff
</code></pre>

<p>なお、ドキュメント上は <code>XCDROM32.DLL</code> のドライバ名のディフォルトは <code>XCDROM$$</code> と書かれているが、実際には <code>/D:</code> で指定しないとドライバがロードされずエラーとなる。</p>
]]></content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>
<dc:subject>DOS</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2023-03-22T00:09:14+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2023/03/post-11b9d6.html">
<title>Debian Linux を Secure Boot 環境で使う</title>
<link>http://aimingoff.way-nifty.com/blog/2023/03/post-11b9d6.html</link>
<description>Debian Linux を Secure boot 環境で使うためのノウハウ</description>
<content:encoded><![CDATA[<p>以前から Windows と Linux のデュアルブート (実際には別ディスク上の Ubuntu も入れてトリプルブート) 環境で使用している。
Windows 11 ではセキュアブートが必須との話もあり、今のうちに Secure Boot 環境でも Linux が使えるようにしておく。</p>
]]><![CDATA[<h4>Linux のインストール</h4>

<p>これは今のディストリビューション (Debian bullseye や Ubuntu 22.04 LTS など) ならば問題ないはず。
非セキュアブート状態で EFI インストールし、後からセキュアブートに変えても起動する。</p>

<h4>DKMS ドライバ</h4>

<p><a href="/blog/2019/06/post-4a8e8e.html">以前の記事</a> でも書いたようにディストリビューション側で用意していない (センサー等の) ドライバを <a href="https://debian-handbook.info/browse/ja-JP/stable/sect.kernel-compilation.html#sect.modules-build">DKMS</a> でインストールすることがある。
DKMS でインストールされるモジュールは自環境でコンパイルするためそのままでは署名はされておらず、セキュアブート環境ではロードされない。</p>

<p>参考</p>

<ul>
<li><a href="https://wiki.debian.org/SecureBoot">debian Wiki SecureBoot</a></li>
<li><a href="https://blog.germancoding.com/2022/08/20/uefi-secure-boot-debian-dkms-and-the-r8125b/">UEFI Secure Boot, Debian, DKMS and the R8125B</a></li>
<li><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1019425">Debian Bug #1019425</a></li>
<li><a href="https://kledgeb.blogspot.com/2020/06/ubuntu-2004-74-ubuntuuefi.html">Ubuntu 20.04 その74 - UbuntuとUEFIセキュアブート</a></li>
<li><a href="https://wiki.ubuntu.com/UEFI/SecureBoot/Signing">How to sign your own UEFI binaries for Secure Boot</a></li>
</ul>

<p>MOK (Machine Owner Key) というマシンの所有者用のキーを作成して UEFI に登録することで、そのキーを使って署名したカーネルモジュール（ドライバ）はセキュアブート環境でも使えるようになる。</p>

<p>大筋は決まっているものの、セキュアブート自体が比較的新しいものということもあり、ディストリビューションによってやり方は異なる。
まずは共通の手順として (まだインストールしていなければ) dkms パッケージをインストールする。</p>

<pre><code>$ sudo apt install dkms
</code></pre>

<h5>Debian 11 (bullseye)</h5>

<p>bullseye の dkms はセキュアブートに関してはあまりやってくれないので、ほとんど手作業で…</p>

<h6>MOK の作成</h6>

<p>適当な作業ディレクトリで OpenSSL を使用して MOK を作成する</p>

<pre><code>$ openssl req -new -x509 -nodes -days 36500 -subj "/CN=DKMS module signing key" -newkey rsa:2048 -keyout mok.priv -outform DER -out mok.der
</code></pre>

<p>bullseye の dkms では <code>/root</code> 配下に MOK が置かれていることを想定しているので移動してパーミッションを変更する</p>

<pre><code>$ sudo mv mok.priv mok.der /root
$ sudo chown root:root /root/mok.priv /root/mok.der
</code></pre>

<h6>DKMS の設定</h6>

<p>DKMS でモジュールをインストールする際に自動的に証明する際には <code>/etc/dkms/sign_helper.sh</code> が使われる。
ただし、デフォルトでは自動署名処理は有効となっていないため設定を変更する。</p>

<p><code>/etc/dkms/framework.conf</code> の一番下のコメントを外して有効にする。</p>

<pre><code>## Script to sign modules during build, script is called with kernel version
## and module name
sign_tool="/etc/dkms/sign_helper.sh"    <I><span style="color:#cc0000;">&#x2605; コメントを外す</span></I>
</code></pre>

<p>これを見てもわかるように、もし <code>/etc/dkms/sign_helper.sh</code> のやり方が気に入らない (MOK を <code>/root</code> に置くのがイヤ等) ならば、自前でツールを書いてそのツールの場所を指定してもいい。 <sup>[<A HREF="#sign_tool">1</A>]</sup> </p>

<p>この後に DKMS でカーネルモジュールをインストールすればあとは自動的にモジュールが署名される。</p>

<h6><A NAME="MOK">MOK の UEFI への登録</A></h6>

<p>MOK の UEFI への登録方法にはいくつかあるが mokutil を使用するのが一番簡単。</p>

<pre><code>$ sudo mokutil --import /root/mok.der
input password:          <I><span style="color:#cc0000;">&#x2605; 実際に MOK を Enroll する際に使う一過性のパスワードを指定</span></I>
input password again:
$ sudo mokutil --list-new
[key 1]
SHA1 Fingerprint: xx:xx:....
Certificate:
    Data:
...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=DKMS module signing key
        Validity
            Not Before: Mar  5 09:42:50 2023 GMT
            Not After : Feb  9 09:42:50 2123 GMT
        Subject: CN=DKMS module signing key
...
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
...
</code></pre>

<p>次回 PC の再起動時に実際の MOK を UEFI に登録する画面が表示されるので <code>Enroll MOK</code> を選択し、先程入力したパスワードを入れれば登録される。
具体的な画面は PC により異なるが <a href="https://kledgeb.blogspot.com/2022/04/ubuntu-2204-lts-7-uefi-mok.html">Ubuntu の例</a> を参考に…</p>

<p>再起動後に <code>mokutil --list-enrolled</code> コマンドを実行すると登録済みの MOK が表示され <code>sudo mokutil --list-new</code> では何も表示されなくなる。</p>

<h5>Debian 12 (bookworm) 以降</h5>

<p>dkms のアップストリームに合わせてやり方が変わっている。</p>

<ul>
<li>事前に MOK を作成する必要はなく、その時点で MOK が存在しなければ DKMS が MOK を自動的に作成</li>
<li>MOK はデフォルトでは <code>/var/lib/dkms/</code> 配下に作成 <br />
※ <code>/etc/dkms/framework.conf</code> か <code>/etc/dkms/framework.conf.d/</code> 配下のファイルで <code>mok_signing_key</code> や <code>mok_certificate</code> を設定すれば変更可</li>
<li>特に設定をしなくても DKMS が自動的にモジュールを署名</li>
</ul>

<p>ただし MOK を UEFI に登録するところまではやってくれないので bullseye と同様に <code>mokutil</code> で enroll してやる必要がある。</p>

<pre><code>$ sudo mokutil --import /var/lib/dkms/mok.pub
input password:
input password again:
</code></pre>

<p>なお、 bullseye からのアップグレードで既に作成済みの MOK をそのまま流用する場合には、上記のように新しい MOK を登録せずに以下のように旧 MOK を移動した方がいいかもしれない。
ただし、アップグレードの際に既に DKMS の管理下になっていたモジュールは dkms により自動的に作成された MOK で署名されている可能性があるので、その場合には dkms でモジュールを再インストールする必要がある。</p>

<pre><code>$ sudo mv /root/mok.der /var/lib/dkms/mok.pub
$ sudo mv /root/mok.priv /var/lib/dkms/mok.key
</code></pre>

<h5>Ubuntu</h5>

<p>Ubuntu (20.04 以降？) では Debian とは異なる独自のやり方をしている。
(恐らく Debian より先行してセキュアブートに取り組んでいたため)
Ubuntu では <code>kmodsign</code> というコマンドを使いカーネルモジュールを署名するようになっているが、 Debian にはそのようなコマンドは無い。
また <code>update-secureboot-policy</code> というコマンドは Debian にも Ubuntu にも存在するが、できることが全く異なり別物と考えたほうが良い。</p>

<p>Ubuntu では DKMS でカーネルモジュールをインストールする際に以下のことをする。</p>

<ul>
<li>(MOK が存在しなければ) <code>update-secureboot-policy --new-key</code> により MOK を <code>/var/lib/shim-signed/mok/</code> 配下に生成</li>
<li>(MOK が登録されていなければ) <code>update-secureboot-policy --enroll-key</code> コマンドで MOK を UEFI に登録</li>
<li><code>kmodsign</code> コマンドでモジュールを署名</li>
</ul>

<p>以降は DKMS でモジュールがインストールされる度に自動的に署名してくれる。</p>

<h4>VMware</h4>

<p>Windows とのデュアルブート環境とはいえ、実際に Windows 側を立ち上げるのは GPU 等のハードリソースを使うケースに限られ、単に Windows のソフトを使いたい場合には VMware Player を使って Windows VM を立ち上げている。 <br />
VMware を動かす際に <code>vmmon.ko</code> と <code>vmnet.ko</code> という２つのドライバが必要となるが、これらは署名されていないためにセキュアブート観葉ではロードされない。 これらのドライバに対しても署名してやる必要がある。</p>

<p>MOK は前述の DKMS 用に作成したものを使う。</p>

<ul>
<li>Debian 11 (bullseye)<pre><code>$ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /root/mok.priv /root/mok.der $(sudo modinfo -n vmmon)
$ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /root/mok.priv /root/mok.der $(sudo modinfo -n vmnet)
</code></pre></li>
<li>Debian 12 (bookworm)<pre><code>$ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /var/lib/dkms/mok.key /var/lib/dkms/mok.pub $(sudo modinfo -n vmmon)
$ sudo /lib/modules/$(uname -r)/build/scripts/sign-file sha512 /var/lib/dkms/mok.key /var/lib/dkms/mok.pub $(sudo modinfo -n vmnet)
</code></pre></li>
<li>Ubuntu<pre><code>$ sudo kmodsign sha512 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der $(sudo modinfo -n vmmon)
$ sudo kmodsign sha512 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der $(sudo modinfo -n vmnet)
</code></pre></li>
</ul>

<p>DKMS とは違って新しい Kernel がインストールされる度に自動でやってくれることはないので、 VMware や kernel のアップデートの度にこの作業をする必要がある。</p>

<p>参考</p>

<ul>
<li><a href="https://kb.vmware.com/s/article/2146460">VMware KB #2146460</a></li>
</ul>

<h4>rEFInd</h4>

<h5>Debian 13 (trixie) 【2025/08/14追記】</h5>

<p>Debian trixie ではパッケージの rEFInd を使っても問題がなくなった。
既に次項の bookworm で rEFInd をインストールした環境からのアップグレードなら <a href="http://www.rodsbooks.com/refind/installing.html#uinst_linux">Uninstalling rEFInd from Linux</a> で既存の rEFInd を削除後にパッケージをインストールする。</p>

<p>その後以下のようにして MOK をインポートする。</p>

<pre><code>$ sudo mokutil --import /boot/efi/EFI/refind/keys/refind_local.cer
</code></pre>

<p>あとは <A HREF="#MOK">MOK の UEFI への登録</A> を参照。</p>

<h5>Debian 12 (bookworm)</h5>

<p>実はこれが一番厄介な代物で、この記事を書こうと思ったのもこのため。
結論から言うと Debian や Ubuntu のリポジトリにあるパッケージは使うな。
パッケージの rEFInd を使う限りはうまくいかない。 <br />
※ これはたまたま rEFInd の新しい版数 0.14.0 がリリースされ、問題が解決しただけかもしれないが…</p>

<p>まずは、カスタマイズ済みの <code>/boot/efi/EFI/refind/refind.conf</code> を退避したら、パッケージをアンインストールして <code>/boot/efi/EFI/refind</code> ディレクトリごとバッサリ削除する。
ただし rEFInd で必要なパッケージ (<code>sbsigntool</code>) はインストールしたままにしておくこと。</p>

<p>次に <a href="http://www.rodsbooks.com/refind/">rEFInd のサイト</a> からダウンロードした binary zip ファイルを適当な作業ディレクトリに展開し、そのディレクトリに移動する。</p>

<pre><code>$ unzip refind-bin-0.14.0.zip
$ cd refind-bin-0.14.0
</code></pre>

<p>続いてインストール済みの <a href="https://github.com/rhboot/shim">shim</a> をディレクトリごとワークディレクトリ下にコピーし、署名されたバイナリを扱うように削除・リネームする。</p>

<pre><code>$ cp -a /usr/lib/shim .
$ cd shim
$ rm fbx64.efi mmx64.efi shimx64.efi
$ mv fbx64.efi.signed fbx64.efi
$ mv mmx64.efi.signed mmx64.efi
$ mv shimx64.efi.signed shimx64.efi
$ cd ..
</code></pre>

<p>先程コピーした署名付き shim を指定して rEFInd をインストールする。</p>

<pre><code>$ sudo ./refind-install --shim shim/shimx64.efi
</code></pre>

<p>これで rEFInd の MOK の import も済んでいるので、再起動時に MOK の Enroll をすれば rEFInd がブートローダとして動くようになる。</p>

<p><code>/boot/efi/EFI/refind/refind.conf</code> をカスタマイズしていた場合には、再起動前に新たにインストールされた <code>refind.conf</code> にカスタマイズ内容を反映させることを忘れずに。</p>

<p>参考</p>

<ul>
<li><a href="https://dev.to/hollowman6/a-solution-to-refind-unable-to-load-using-shim-when-secure-boot-is-enabled-1e8l">A solution to rEFInd unable to load using shim when Secure Boot is enabled</a></li>
</ul>

<hr />

<p><span style="font-size:x-small;"><A NAME="sign_tool">[1]</A>: 個人的には bookworm と同じディレクトリ構成にしたスクリプトに変更することをお薦めする。その方がアップグレードに伴うトラブルが少ない。</span></p>
]]></content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>
<dc:subject>Linux</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2023-03-06T00:37:10+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2022/10/post-1de1cf.html">
<title>コンテナで GUI / GPU を使う</title>
<link>http://aimingoff.way-nifty.com/blog/2022/10/post-1de1cf.html</link>
<description>Docker や LXD のようなコンテナ上で GPU を扱ったり X11 アプリを動かしたりする方法</description>
<content:encoded><![CDATA[<p>最近 <a href="https://github.com/CompVis/stable-diffusion">Stable Diffusion</a> 等 AI 関連のオープンソースソフトが数多く出現しており、いろいろ試してみたくなっている。
多くは Linux でも動くので魅力ではあるが、残念ながら動作環境が限定されていることが多く、普段遣いの OS 環境をそれに合わせ込むのも好ましくない。
そこで、個々のアプリ環境はコンテナで構築して分離しておくのが楽だ。</p>

<p>しかしながら AI 関連ソフトは GPU を使うものが多く、コンテナ上で GPU を扱ったり GUI (X アプリ) を使えるようにするには工夫が必要なのでここにメモしておく。</p>

<p>なお、ここでは以下のような環境を前提にしている。</p>

<ul>
<li>ホスト OS: Debian 11 (bullseye)</li>
<li>Kernel: 5.18.16 (bullseye-backports)</li>
<li>コンテナイメージベース OS: Ubuntu 18.04 or 20.04 or 22.04</li>
</ul>

<p>他の OS 環境でもある程度参考にはなるでしょう。</p>
]]><![CDATA[<h4>LXD</h4>

<p>LXD はコンテナといっても Kernel 以外の OS 環境を構築する軽量 VM のようなもののため単に GUI を使うだけならあまり困らない。
xrdp と任意のデスクトップパッケージをインストールすればリモートデスクトップクライアントを使って GUI は表示できる。
ここではそのようなやり方ではなく、 GPU を使ったり vulkan のようにホスト OS 上の X server にアクセスすることを想定する。</p>

<p>LXD の環境構築 (<code>lxd</code> グループに所属する等) については他のサイトでも詳しく書かれているのでここでは触れない。
以下 Ubuntu 20.04 のコンテナを作成して動かすものとし、コンテナ名を ubuntu2004 と仮定する。
バージョンやコンテナ名については適宜読み替えて欲しい。</p>

<h5>コンテナの作成</h5>

<p>タグに Ubuntu のバージョン <code>20.04</code> を指定し <code>ubuntu2004</code> という名のコンテナを立ち上げる</p>

<pre><code>host$ lxc launch ubuntu:20.04 <i>ubuntu2004</i></code></pre>

<p>続いてコンテナ内で shell を起動し必要なパッケージをインストールして GUI を使える状態にする</p>

<pre><code>host$ lxc exec <i>ubuntu2004</i> -- bash</code></pre>

<p>以下はインストールするパッケージの一例 (実際にインストールパッケージはお好きなように…)</p>

<pre><code>root@<i>ubuntu2004</i># apt update
root@<i>ubuntu2004</i># apt install x11-apps dbus-x11
root@<i>ubuntu2004</i># exit
</code></pre>

<h5>コンテナ内ユーザとホストユーザのマッピング</h5>

<p>Ubuntu のコンテナイメージにはデフォルトで <code>ubuntu</code> というユーザが <code>UID=1000</code> で定義されているので、これをホスト側のユーザ ID とマップする</p>

<pre><code>host$ lxc config set <i>ubuntu2004</i> raw.idmap "both ${UID} 1000"</code></pre>

<p>これはホスト側で <code>GID=UID</code> のユーザの GID/UID 両方をコンテナ内の <code>UID=GID=1000</code> としてマップすることを示す <br />
複数の ID をマップする必要がある場合 (例えば <code>src</code> グループをコンテナ内でも継承する場合) には以下のように改行で区切って指定する</p>

<pre><code>host$ echo -en "both ${UID} 1000\ngid 40 40" | lxc config set <i>ubuntu2004</i> raw.idmap -</code></pre>

<p>こうすることでコンテナ内でもホスト側のファイルを共用してアクセスしても問題なくなる</p>

<h5>コンテナ内から GPU をアクセスできるようにする</h5>

<p>GPU をコンテナ内からアクセスできるようにする方法は <a href="https://lxd-ja.readthedocs.io/ja/latest/instances/#gpu">LXD のドキュメント</a> に書かれている通り</p>

<pre><code>host$ lxc config device add <i>ubuntu2004</i> gpu gpu gid=$(getent group video | cut -d: -f3)</code></pre>

<p>デフォルトでは GPU のコンテナ内 GID が 0 (root) に設定されてしまうので ubuntu ユーザでもアクセス可能な <code>video</code> グループの GID を割り振る</p>

<h5>コンテナ内からホストの X サーバにアクセスできるようにする</h5>

<p>ホスト側の <code>/tmp/.X11-unix/</code> 配下のソケットをコンテナにも見えるようにすればいいのだが、実はこれが厄介。
通常であればコンテナの設定でディレクトリをマウントさせればいいが、 LXD コンテナ起動時のマウント後にコンテナ内の X11 の初期化が行われることによりクリアされてしまう。
このため、ひとまずコンテナ内の別の場所にマウントさせ、実際にコンテナ内で使う際に <code>/tmp/.X11-unix/</code> にシンボリックリンクさせることにする。
ここでは X11 ソケットをコンテナ内の <code>/mnt/x11/</code> 配下にマウントする。</p>

<pre><code>host$ lxc config device add <i>ubuntu2004</i> x11 disk source=/tmp/.X11-unix path=/mnt/x11</code></pre>

<p>コンテナ内のシンボリックリンクについては後述</p>

<h5>コンテナ内の ubuntu ユーザのログインスクリプトを変更</h5>

<p>ログインスクリプトを一部変更することで GUI が使えるようにする。
一旦以下のように ubuntu ユーザでログインしてログインスクリプトを書き換える。</p>

<pre><code>host$ lxc exec <i>ubuntu2004</i> -- sudo --user=ubuntu --login bash</code></pre>

<p>スクリプトの意図は:</p>

<ul>
<li>同じコンテナを GUI を使わないで使用する場合には余計なことをしない</li>
<li>ホスト側の X11 ソケットの番号は固定とは限らないため config に埋め込まずに shell 起動時に DISPLAY 環境変数で指定する</li>
<li>dbus を使う GUI アプリも多いので dbus が扱えるようにしておく</li>
</ul>

<h6><code>~/.profile</code></h6>

<pre><code class="sh">...
if [ -r "$HOME/.profile-x11" ]; then
    . "$HOME/.profile-x11"
fi
</code></pre>

<p>次項の <code>~/.profile-x11</code> ファイルがあればそれを読み込むようにする</p>

<h6><code>~/.profile-x11</code></h6>

<pre><code class="sh">[ -n "$DISPLAY" -a -z "$XDG_RUNTIME_DIR" ] || return

setup_x11 ()
{
    local xsock_dir x_id x
    xsock_dir=/mnt/x11
    [ -d $xsock_dir ] || return
    x_id=
    x=${DISPLAY#:}
    for f in ${xsock_dir}/X*; do
        if [ -O "$f" -a "${f##${xsock_dir}/X}" = "$x" ]; then
            x_id=$x
        fi
    done
    [ -n "$x_id" ] || return
    if [ ! -h /tmp/.X11-unix/X${x_id} ]; then
        ln -s ${xsock_dir}/X${x_id} /tmp/.X11-unix/
    fi

    export XDG_RUNTIME_DIR=/run/user/${UID}
    if [ ! -d ${XDG_RUNTIME_DIR} ]; then
        sudo mkdir -p ${XDG_RUNTIME_DIR}
        sudo chown ${UID}:$(id -g) ${XDG_RUNTIME_DIR}
        sudo chmod 700 ${XDG_RUNTIME_DIR}
    fi

    exec dbus-launch --exit-with-session bash
}

setup_x11
unset setup_x11
</code></pre>

<p>ちょっと複雑なため少し解説</p>

<ul>
<li><code>DISPLAY</code> 環境変数が設定されていない場合や既にこの処理が済んでいる場合には何もせず抜ける</li>
<li><code>/mnt/x11/</code> 配下にあるソケットの中から <code>DISPLAY</code> 環境変数の番号と一致するものを探してそれが <code>ubuntu</code> の UID と同じ場合に <code>/tmp/.X11-unix/</code> 配下にシンボリックリンクする</li>
<li>dbus 環境を設定してサブシェルを起動する</li>
<li>何らかのエラーでサブシェルを起動できなかった場合は <code>setup_x11</code> 関数定義自体を消して後始末をする</li>
</ul>

<h5>コンテナへのログイン</h5>

<p>LXD コンテナに ubuntu ユーザでログインする</p>

<pre><code>host$ lxc exec <i>ubuntu2004</i> -- sh -c "DISPLAY=$DISPLAY exec sudo --user=ubuntu --login bash"</code></pre>

<p>このシェルから X アプリを実行すればホスト上のデスクトップに表示されるはず</p>

<pre><code>ubuntu@<i>ubuntu2004</i>$ xeyes &amp;</code></pre>

<h5>参考</h5>

<ul>
<li><a href="https://gihyo.jp/admin/serial/01/ubuntu-recipe/0532">LXDのコンテナからGPUを利用する</a></li>
<li><a href="https://gihyo.jp/admin/serial/01/ubuntu-recipe/0479">LXDコンテナとホストの間でファイルを共有する方法</a></li>
<li><a href="https://qiita.com/yoshi10ryu1/items/a720f9e664e5948c4e31">LXD で作る仮想化 GUI 環境 - Ubuntu 22.04 LTS 版</a></li>
<li><a href="https://github.com/lxc/lxd/issues/4540">Bindmount for .X11-unix only works when done if container is running</a></li>
</ul>

<h4>Docker</h4>

<p>Docker は LXD と違ってアプリケーションコンテナであり、基本的には単一のアプリを実行するための環境を作成する。
このため systemd や init のような初期化ルーチンが走るわけではないので LXD のようなすれ違い (X11 ソケットの初期化等) が起こらない点は楽になる。
しかしながら逆に systemd や init により自動的に起動される初期化ルーチンや daemon が無いため、必要なものは全て自前で整えなければいけない。</p>

<p>正直なところ GUI を動かすには LXD の方が確実だが <a href="/blog/2022/09/post-824044.html">LXD には面倒なところがあり</a> あまり多くのバリエーションのコンテナを用意するのは難しい。
Docker でも GPU を扱うのは比較的容易であり、ある程度なら GUI も動かせるのでその方法を示す。</p>

<p>元々 AMD の <a href="https://rocm.docs.amd.com/">ROCm</a> を動かす環境を用意しその上で <a href="https://github.com/upscayl/upscayl">Upscayl</a> のような GUI も動かせたら…という目論見で試行錯誤したもの <sup>[<A HREF="#upscayl">1</A>]</sup> なので、その詳細は Git Hub の <a href="https://github.com/aimoff/ROCm-docker">ROCm-docker</a> の方を参照されたい。
ここではエッセンスのみ示す。
基本線は LXD で示したこととほぼ同じ。
ただし LXD は UID/GID のマッピングを行うのに対し Docker では ID マッピングせずにそのままコンテナに見せている点に注意。</p>

<p>【2024/07/01 追記】 <br />
このあたりのことがオフィシャルドキュメントの <a href="https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html">Running ROCm Docker containers</a> にも書かれるようになった。
ただし X サーバへのアクセスについては触れられていないので以下の内容はまだ有意義。</p>

<h5>Dockerfile</h5>

<p>Docker コンテナイメージを build するための Dockerfile を用意する</p>

<pre><code>FROM ubuntu:20.04
ARG UID
ARG RENDER_GID

RUN UID_ADD=; [ -z "$UID" ] || UID_ADD="-u $UID"; \
    if [ -z "$RENDER_GID" ]; then \
      useradd --create-home $UID_ADD -G sudo,video --shell /bin/bash docker-user; \
    else \
      groupadd -g $RENDER_GID render; \
      useradd --create-home $UID_ADD -G sudo,video,render --shell /bin/bash docker-user; \
    fi

RUN apt-get update \
  &amp;&amp; DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends apt-utils \
  &amp;&amp; DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
  x11-apps \
  dbus-x11
RUN apt-get clean \
  &amp;&amp; rm -rf /var/lib/apt/lists/*

COPY start-dbus.sh /usr/local/bin
RUN chmod +x /usr/local/bin/start-dbus.sh

USER docker-user
WORKDIR /home/docker-user

CMD ["/bin/sh", "/usr/local/bin/start-dbus.sh" ]
</code></pre>

<ul>
<li>ホスト OS のユーザと同じ UID のユーザを作成する</li>
<li>ホスト OS で <code>/dev/dri/render*</code> デバイスのグループが <code>render</code> である場合には同じ GID の <code>render</code> グループを作成し、前述で作成したユーザもそのグループに入れる <br />
オリジナルの <a href="https://github.com/RadeonOpenCompute/ROCm-docker">ROCm-docker</a> はコンテナの OS が Ubuntu 20.04 以降の場合に <code>render</code> グループを決め打ちの GID で設定しているが、実際にはホスト OS 側のデバイスのパーミッションがそのまま見えるためホスト側の GID を継承する必要がある</li>
<li>コンテナイメージに含めるパッケージはご随意に…</li>
<li>スタートアップスクリプトを <code>/usr/local/bin</code> 配下にコピーし、コンテナ起動時には前述で作成したユーザ権限でそのスクリプトを実行するようにする</li>
</ul>

<h5>スタートアップスクリプト</h5>

<p>LXD のログインスクリプトと同じような処理をする。
LXD と違うのは <code>/tmp/.X11-unix/</code> 配下の X11 ソケットは起動時には使える状態になっているため特別な対処が不要という点。</p>

<pre><code>#!/bin/sh

UID=${UID:-$(id -u)}
GID=$(id -g)
export XDG_RUNTIME_DIR=/run/user/${UID}
[ -d ${XDG_RUNTIME_DIR} ] || sudo mkdir -p ${XDG_RUNTIME_DIR} \
    &amp;&amp; sudo chown ${UID}:${GID} ${XDG_RUNTIME_DIR} \
    &amp;&amp; sudo chmod 700 ${XDG_RUNTIME_DIR}
exec dbus-launch --exit-with-session bash -l
</code></pre>

<h5>docker-compose.yml</h5>

<p>docker コマンドに引数を指定して build / 実行することも可能だが docker-compose を使うことで面倒な引数を指定せずに定型処理ができる</p>

<pre><code class="yaml">version: '3'

services:
  xshell:
    image: ubuntu-20.04-xshell
    build:
      context: .
      dockerfile: Dockerfile
      args:
        UID: ${UID}
        RENDER_GID: ${RENDER_GID}
    environment:
      - DISPLAY
    cap_add:
      - SYS_ADMIN
    security_opt:
      - apparmor:unconfined
    devices:
      - /dev/kfd
      - /dev/dri
      - /dev/fuse
    tmpfs:
      - /tmp
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix
      - ~:/home/docker-user/host-home
</code></pre>

<ul>
<li>前述の Dockerfile を使って build する</li>
<li><code>UID</code> や <code>RENDER_GID</code> はホスト側の値を環境変数で渡す</li>
<li>GUI / GPU を扱う場合に必要なセキュリティ関連の指定 (<code>cap_add</code> / <code>security_opt</code>) をする</li>
<li>ホスト側の X11 や GPU へのアクセスに必要なデバイスやディレクトリをコンテナから見えるようにする</li>
</ul>

<h5>.env</h5>

<p>build の際に引き渡す環境変数を以下のようにして <code>.env</code> ファイルに格納する</p>

<pre><code>$ cat &gt;.env &lt;&lt;EOF
UID=${UID:-$(id -u)}
RENDER_GID=$(getent group render | cut --delimiter ':' --fields 3)
EOF
</code></pre>

<h5>build</h5>

<pre><code>$ docker-compose build xshell</code></pre>

<h5>実行</h5>

<pre><code>$ docker-compose run --rm xshell</code></pre>

<p>このシェルから X アプリを実行すればホスト上のデスクトップに表示されるはず</p>

<pre><code>docker-user@<i>xxxxxxxxxxxx</i>$ xeyes &amp;</code></pre>

<h5>参考</h5>

<ul>
<li><a href="https://qiita.com/Spritaro/items/f907a9b52cb78e4fbec0">DockerでGUIを表示するときの仕組みについて</a></li>
<li><a href="https://zenn.dev/ysuito/articles/fdc4a49d83614a">Dockerコンテナ上でGUIアプリを表示する</a></li>
<li><a href="https://qiita.com/muddydixon/items/d2982ab0846002bf3ea8">Docker privileged オプションについて</a></li>
<li><a href="https://9to5tutorial.com/docker-xrdp-ubuntu-image-with-japanese-input-also-compatible-with-raspberry-pi-3-and-later">(docker) XRDP + Ubuntu image with Japanese input</a></li>
<li><a href="https://stackoverflow.com/questions/67890283/the-mount-bind-command-fail-in-docker-container-on-ubuntu">The mount --bind command fail in Docker container on Ubuntu</a></li>
</ul>

<hr />

<p><span style="font-size:x-small;"><A NAME="upscayl">[1]</A>: 実際には Upscayl はある程度までは動くが完全には動いていない</span></p>
]]></content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>
<dc:subject>Linux</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2022-10-19T23:49:52+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2022/09/post-824044.html">
<title>仮想環境のイメージ格納場所の移動</title>
<link>http://aimingoff.way-nifty.com/blog/2022/09/post-824044.html</link>
<description>仮想環境 (libvirt, Docker, LXD) のイメージが肥大化してストレージの空きを圧迫するようになってきた場合に空きのあるストレージに移動させる方法</description>
<content:encoded><![CDATA[<p>ここのところ、仕事上だけでなく自宅でも仮想環境を使うことが増えてきた。 <br />
仮想環境が増えてくるとそのイメージを保持するストレージも肥大化してくる。
ほとんどの仮想環境でデフォルトのイメージ格納先は <code>/var</code> 配下のディレクトリとなっているが、 OS のインストール当初にはこういうことを想定しておらず、仮想環境を使うにつれ <code>/var</code> が割り当てられているストレージの空き容量が圧迫される事態に陥りがちだ。 <br />
そんな時に仮想イメージ格納先を空きのあるストレージに移動する方法をまとめておく。</p>

<p>なお、以下はホスト環境として Debian (bullseye) や Ubuntu (22.04 LTS) を想定している。 <br />
空き容量のあるストレージが <code>/srv</code> 配下にマウントされていることを想定しているが、自身の環境に合わせて別のディレクトリ (<code>/home</code> 配下等) に読み替えて欲しい。</p>
]]><![CDATA[<h4>libvirt</h4>

<p>VM イメージは通常 default ストレージプール (<code>/var/lib/libvirt/images</code>) に作成される。この格納先を変更する。</p>

<h5>1. まずは全ての仮想マシンを停止</h5>

<h5>2. <code>default</code> ストレージプールを編集</h5>

<pre><code>$ sudo virsh pool-edit default</code>
<code class="xml">&lt;pool type='dir'&gt;
  &lt;name&gt;default&lt;/name&gt;
  &lt;uuid&gt;xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&lt;/uuid&gt;
  &lt;capacity unit='bytes'&gt;nnnnnnnnnnn&lt;/capacity&gt;
  &lt;allocation unit='bytes'&gt;mmmmmmmmmmm6&lt;/allocation&gt;
  &lt;available unit='bytes'&gt;aaaaaaaaaaa&lt;/available&gt;
  &lt;source&gt;
  &lt;/source&gt;
  &lt;target&gt;
    &lt;path&gt;<strong><span style="color:#cc0000;">/srv/libvirt/images</span></strong>&lt;/path&gt;
    &lt;permissions&gt;
      &lt;mode&gt;0711&lt;/mode&gt;
      &lt;owner&gt;0&lt;/owner&gt;
      &lt;group&gt;0&lt;/group&gt;
    &lt;/permissions&gt;
  &lt;/target&gt;
&lt;/pool&gt;
</code></pre>

<h5>3. libvirted サービスを停止</h5>

<pre><code>$ sudo systemctl stop libvirtd.service</code></pre>

<p>※ Warning が出るが気にしない</p>

<h5>4. 移行先ディレクトリを作成</h5>

<pre><code>$ sudo mkdir -p /srv/libvirt/images</code></pre>

<h5>5. libvirted サービスを開始</h5>

<pre><code>$ sudo systemctl start libvirtd.service</code></pre>

<h5>6. 各 VM イメージファイルを移行先ディレクトリに移動</h5>

<pre><code>$ sudo mv /var/lib/libvirt/images/<i>vm1.qcow2</i> /srv/libvirt/images</code></pre>

<h5>7. 各 VM ディスクイメージのパスを変更</h5>

<pre><code>$ sudo virsh edit <em>vm1</em>
...</code>
<code class="xml">  &lt;devices&gt;
    &lt;emulator&gt;/usr/bin/qemu-system-x86_64&lt;/emulator&gt;
    &lt;disk type='file' device='disk'&gt;
      &lt;driver name='qemu' type='qcow2'/&gt;
      &lt;source file='<strong><span style="color:#cc0000;">/srv/libvirt/images/</span></strong><em>vm1.qcow2</em>'/&gt;
      &lt;target dev='vda' bus='virtio'/&gt;
      &lt;address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/&gt;
    &lt;/disk&gt;
<code><code>...</code></pre>

<h5>8. libvirted サービスを再起動</h5>

<pre><code>$ sudo systemctl restart libvirtd.service</code></pre>

<p>多くの仮想マシンを作成した後での移動は面倒なので、やるなら早めにやっておいたほうがいい。</p>

<h4>Docker</h4>

<p>Docker コンテナイメージはデフォルトで <code>/var/lib/docker</code> 配下に格納される。</p>

<p>残念ながら現状のコンテナイメージやボリュームを保持したまま移動する方法はわかっていない。
<a href="https://matsuand.github.io/docs.docker.jp.onthefly/desktop/backup-and-restore/">コンテナイメージ</a> や <a href="https://matsuand.github.io/docs.docker.jp.onthefly/storage/volumes/#backup-restore-or-migrate-data-volumes">データボリューム</a> のバックアップ・リストア等によりデータを退避して移動する必要がある。</p>

<h5>1. 移行先ディレクトリを作成</h5>

<pre><code>$ sudo mkdir -p /srv/docker</code></pre>

<h5>2. Docker の設定ファイルを作成</h5>

<pre><code>$ sudo cat &gt;/etc/docker/daemon.json &lt;&lt;EOF
{
  "data-root": "<strong><span style="color:#cc0000;">/srv/docker</span></strong>"
}
EOF
</code></pre>

<p>※ 既に <code>/etc/docker/daemon.json</code> が存在する場合にはエディタで編集して <code>data-root</code> を設定する</p>

<h5>3. docker サービスを再起動</h5>

<pre><code>$ sudo systemctl restart docker.service</code></pre>

<p>新しい格納先にサブディレクトリが新規作成され、以降はこちらが使用される。</p>

<h4>LXD (+ snap)</h4>

<p>一番厄介なパターン。</p>

<p>LXD 導入時に <code>lxd init</code> コマンドでデフォルトのストレージプールを指定するが、ここで btrfs を選択することが多いと思う。
しかしながらこれに罠があり <a href="https://discuss.linuxcontainers.org/t/how-to-move-a-storage-to-other-places/7171">LXD の btrfs イメージファイルは <code>/var/snap/lxd/common/lxd/disks</code> 配下にしか置けない</a> という残念な制約がある。
別のストレージプールを作成しても btrfs イメージファイルを使う限りはこのディレクトリ配下の容量が圧迫されるという問題は避けられない。</p>

<p>…ということで、しかたがなく <code>/var/snap</code> ディレクトリ自体を空きのあるところに移し bind マウントすることに…</p>

<h5>1. LXD を停止</h5>

<pre><code>$ sudo snap stop lxd</code></pre>

<h5>2. snapd を停止</h5>

<pre><code>$ sudo systemctl stop snapd.service</code></pre>

<h5>3. 移行先ディレクトリを作成</h5>

<pre><code>$ sudo mkdir -p /srv/snap</code></pre>

<h5>4. snap 管理化のファイルを移行先ディレクトリに移動</h5>

<pre><code>$ sudo mv /var/snap/* /srv/snap</code></pre>

<h5>5. 移行先ディレクトリを移動元ディレクトリに bind マウントするよう <code>/etc/fstab</code> に追記</h5>

<pre><code>$ sudo vi /etc/fstab
...
<strong><span style="color:#cc0000;">/srv/snap</span></strong>       /var/snap   none        bind    0 0
</code></pre>

<h5>7. bind マウント</h5>

<pre><code>$ sudo mount /var/snap</code></pre>

<h5>8. snapd を起動</h5>

<pre><code>$ sudo systemctl stat snapd.service</code></pre>

<p>LXD のために snap もろとも移動するのはどうかとも思うが、 snap も肥大化を招く可能性のある仕組みのためこれでよしとする。</p>

<p>なお、移動しても btrfs のイメージサイズは以前のままなので、そのストレージプールの容量は以前と変わらない。
リサイズするには <a href="https://takuya-1st.hatenablog.jp/entry/2021/02/23/191245">LXC のストレージサイズ変更（拡張・縮小）する</a> 等のサイトを参照されたい。</p>

<p>大規模なシステム配下の業務サーバならば最初からデフォルトストレージプールとして ceph を選択するのがベストだが (そういうシステムでは普通 LXD ではなく Kubernetes 選択するはず)、どちらかというと LXD は小規模向けのコンテナシステムという認識であり btrfs は自然な選択なので、これは将来的にはなんとかして欲しいところ。</p>
]]></content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>
<dc:subject>Linux</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2022-09-10T23:58:33+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2022/02/post-93e534.html">
<title>FreeDOS 1.3 リリース</title>
<link>http://aimingoff.way-nifty.com/blog/2022/02/post-93e534.html</link>
<description>2月20日に [FreeDOS][] 1.3 が正式にリリースされた。  
大き...</description>
<content:encoded><![CDATA[<p>2月20日に <a href="http://www.freedos.org/">FreeDOS</a> 1.3 が正式にリリースされた。 <br />
大きな変更点は <a href="http://kernel.fdos.org/">kernel</a> と <a href="https://github.com/FDOS/FreeCom/">FreeCOM</a> (<code>COMMAND.COM</code>) なので <a href="/blog/2021/06/post-880af6.html">以前の記事</a> から目新しいことはほとんど無い。 <br />
この機会に <a href="https://github.com/lpproj/freecom_dbcs2/">FreeCOM DBCS edition</a> (日本語版 <code>COMMAND.COM</code>) を試しに入れてみる。</p>

<p><a href="https://aimingoff.way-nifty.com/.shared/image.html?/photos/uncategorized/freedos13.png" class="mb"><img border="0" alt="FreeDOS 1.3" title="FreeDOS 1.3" style="display: block; margin: auto;" src="https://aimingoff.way-nifty.com/blog/images/freedos13.png" width="322" height="263"></a></p>
]]><![CDATA[<h4>FreeCOM DBCS edition</h4>

<p><a href="https://github.com/lpproj/freecom_dbcs2/releases">FreeCOM DBCS edition releases</a> から入手。
最新の FreeCOM 0.85a ベースになっている。</p>

<p><code>\FDOS\JAPANESE</code> ディレクトリを作成して <code>freecom_dbcswip-20220117-bin.zip</code> 内の <code>ibmpc/japanese/command.com</code> を入れる。</p>

<pre><code>A:\
|  KERNEL.SYS
|  COMMAND.COM
|  AUTOEXEC.BAT
|  FDCONFIG.SYS
|  
\--FDOS
   +--BIN
   |  ...
   |     
   +--JAPANESE
   |     COMMAND.COM
   |     
   \--XMSSWAP
         COMMAND.COM
</code></pre>

<h4><code>FDCONFIG.SYS</code></h4>

<p>FreeCOM DBCS Edition を使うために若干変更する。  </p>

<pre><code>;!SWITCHES=/F
!COUNTRY=081,,\FDOS\BIN\COUNTRY.SYS
!LASTDRIVE=Z
!BUFFERS=20
!FILES=40

!MENUCOLOR=7,1
MENU  FreeDOS
MENU ----------------------------------------------------------------------
MENU   0 - Safe Mode (don't load any drivers)
MENU   1 - XMS
MENU   2 - XMS + EMS
MENU   3 - Japanese + XMS
MENU   4 - Japanese + XMS + EMS
MENU   5 - Japanese + XMS + DPMI
MENU ----------------------------------------------------------------------
MENUDEFAULT=3,10

0?ECHO Warning: basic stuff only!

12345?DOS=HIGH
12345?DOS=UMB
12345?DOSDATA=UMB
;12345?DEVICE=\FDOS\BIN\UMBPCI.SYS /I=D000-E3FF /I=EC00-EFFF
135?DEVICE=\FDOS\BIN\JEMMEX.EXE NOEMS X=TEST I=TEST
24?DEVICE=\FDOS\BIN\JEMMEX.EXE X=TEST I=TEST
345?DEVICEHIGH=\FDOS\BIN\FONTNX.EXE
;12?DEVICEHIGH=\FDOS\BIN\NANSI.SYS /S
;345?DEVICEHIGH=\FDOS\BIN\PANSI.SYS
0?SHELL=A:\COMMAND.COM A:\ /E:1024 /P=A:\AUTOEXEC.BAT
;12345?SHELLHIGH=A:\COMMAND.COM A:\ /E:1024 /P=A:\AUTOEXEC.BAT
12?SHELLHIGH=A:\FDOS\XMSSWAP\COMMAND.COM A:\FDOS\XMSSWAP /E:1024 /P=A:\AUTOEXEC.BAT
345?SHELLHIGH=A:\FDOS\JAPANESE\COMMAND.COM A:\FDOS\JAPANESE /E:1024 /P=A:\AUTOEXEC.BAT
</code></pre>

<ul>
<li>Safe Mode の時は XMS が使えないのでルートディレクトリの <code>COMMAND.COM</code> を使用</li>
<li>XMS が使える英語環境で立ち上げた場合は <code>\FDOS\XMSSWAP\</code> 配下の <code>COMMAND.COM</code> を使用</li>
<li>日本語環境 (FreeDOS/V) で立ち上げた場合は <code>\FDOS\JAPANESE\</code> 配下の <code>COMMAND.COM</code> を使用</li>
</ul>

<p>一度日本語環境で立ち上げた後に <code>CHEJ US</code> コマンドで英語環境に切り替えた場合には DBCS 版 FreeCOM の出力で文字化けしてしまうが、まぁ現状では仕方がないと諦めるしかなさそう…</p>
]]></content:encoded>


<dc:subject>DOS</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2022-02-25T00:10:44+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2021/10/post-d5c437.html">
<title>PC ケースを変えてみたが…</title>
<link>http://aimingoff.way-nifty.com/blog/2021/10/post-d5c437.html</link>
<description>DIRAC BLACK LINE という PC ケースのレビュー</description>
<content:encoded><![CDATA[<p>昔はタワー型のケースで PC を組むこともあったが、今はもうパーツに凝ることもなく、省スペースの方がありがたい。 <br />
…ということで、今まで <a href="https://www.cfd.co.jp/product/pc_case/iw-ce685_300p/">In-Win CE685</a> というスリム型のケースを使っていた。
これはこれで使いやすいのだが、スリム型ゆえの難点もある。</p>

<ul>
<li>ギリギリのサイズ設計をしているため、マザーボードによっては SATA ケーブルの引き回しが厳しい
<ul>
<li><a href="https://www.gdm.or.jp/review/2014/0713/76591/5">エルミタージュ秋葉原のレビュー</a> にある3.5インチシャドウベイの写真を見てもらうとわかるように、プラスチックのカバーとマザーボード取り付けネジとの間隔がほとんどない</li>
<li>この方向に SATA コネクタが L 字型で配置されているマザーボードは多く、その場合にはプラスチックカバーと SATA ケーブルが干渉してしまう</li>
</ul></li>
<li>エアフローがあまり良くなく、特に Disk の冷却に不安がある</li>
</ul>

<p>これまではこのケースで工夫をしながら使っていた。</p>

<ul>
<li>3.5" HDD ベイには HDD を載せずに <a href="https://www.amazon.co.jp/dp/B07FVPSGHQ/">HDD クーラー</a> を設置</li>
<li><a href="https://www.amazon.co.jp/dp/B003RNQY6Q/">5インチベイ用マルチマウンタ</a> を使ってそちらにスリム型光学ドライブと 3.5" HDD を搭載</li>
<li>背面にも（気休めで）小さなファンを設置</li>
</ul>

<p>ただ、これから Zen3 の Ryzen に変えたり…ということを想定すると <a href="http://aimingoff.way-nifty.com/blog/2020/05/post-180834.html">過去に HDD トラブル</a> があったこともあり継続して使いづらい。
他にエアフローのいいスリム型ケースはないかと探して見つけたのが <a href="https://www.dirac.co.jp/blackline/">DIRAC BLACK LINE</a> <br />
通販で購入して入れ替え <a href="https://www.cfd.co.jp/product/pc_case/iw-ce685_300p/">In-Win CE685</a> の課題は解決したものの、このケースもツッコミどころが多いものであった。</p>
]]><![CDATA[<h4>光学ドライブスロット</h4>

<p>このケースで一番のツッコミどころ。</p>

<p>ネット上のレビュー・コメントとして光学ドライブの奥行きが 170mm 以下でないと電源と干渉することが書かれており、一般に出回っているパイオニアの光学ドライブ (奥行き 180mm 程度) 等では問題がある。私はスリム型の光学ドライブを使っていたので奥行きは短く問題ないと思っていた。 <br />
ところが、このケースのフロントパネルは開口部が狭くなっており、厚型の光学ドライブのトレーに相当するサイズ分の口しかない。
私の使っているスリム型の光学ドライブのマウンタの構造上、 5インチベゼルの上端ギリギリにトレーがあるため開口部とぶつかってしまう <sup>[<A HREF="#bezel">1</A>]</sup> 。
仕方がないので、開口部の上側を 1mm 近く削って拡げなんとか対処したが、奥に引っ込んだ光学ドライブはデザイン的にもイマイチだ。</p>

<p><a href="http://aimingoff.way-nifty.com/.shared/image.html?/photos/uncategorized/dsc_1021.jpg" class="mb"><img alt="BLACK LINE" title="BLACK LINE" src="https://aimingoff.way-nifty.com/blog/images/dsc_1021.jpg" width="400" height="300" border="0" style="display: block; margin: auto;"></a></p>

<p>ネット上にも光学ドライブを搭載した状態の写真は少なく、事前に <a href="https://japan.cnet.com/storage/2018/03/09/0cc5e5ccb6d44d0688eadd64f39a8995/image.jpg">このような写真</a> を見ていれば購入をためらったかもしれない。
こんな凝ったことをせずにパネルの開口部を5インチベゼルサイズまで大きくし、もっと前面側に光学ドライブを搭載するようにすれば奥行きの問題も発生しないのに…と残念感が大きい。</p>

<h4>USB 3.0 コネクタ</h4>

<p>USB 3.0 のコネクタが L 字型 (ツクモは <a href="https://blog.tsukumo.co.jp/nagoya/2018/02/3fpc_13.html">横向刺し型</a> と呼んでいる) のため、マザーボードによっては隣と干渉する。</p>

<p><a href="https://www.dirac.co.jp/blackline/#ngg-image-15" target="_blank"><img alt="USB 3.0" title="USB 3.0" src="https://www.dirac.co.jp/wp-content/gallery/black-line/blackline_io.jpg" width="300" height="300" border="0" style="display: block; margin: auto;"></a></p>

<p>私の使っているマザーボードでは隣に USB 2.0 ヘッダがあり、ここにケーブルを挿すと USB 3.0 ケーブルは挿せなくなってしまう。
このケースはフロントパネルに USB 2.0 コネクタと SD カードスロットがあり、 USB 2.0 のケーブルも２つあるが、どちらかを諦めざるをえない。
結局 SD カードスロットの方を諦めた。</p>

<p>そもそも USB 3.0 のケーブルには USB 3.0 × 2 の信号線があるはずであり、フロントパネルの USB コネクタが USB 2.0 × 2 + USB 3.0 × 1 なのを USB 2.0 × 1 + USB 3.0 × 2 にして、一本の USB 2.0 ケーブルで USB 2.0 コネクタと SD カードをカバーしていれば良かったのではないかという気もする。</p>

<h4>HDD の SATA コネクタ</h4>

<p>このケースはドライブベイが <a href="https://akiba-pc.watch.impress.co.jp/img/ah/docs/1106/765/html/tblaln3b4.jpg.html">跳ね上げ式</a> になっており、組み立ては非常にやりやすい。</p>

<p><a href="https://www.dirac.co.jp/blackline/#ngg-image-13" target="_blank"><img alt="HDD" title="HDD" src="https://www.dirac.co.jp/wp-content/gallery/black-line/blackline_hdd04.jpg" width="300" height="300" border="0" style="display: block; margin: auto;"></a></p>

<p>しかしながら、 HDD ベイは筐体ギリギリに位置しており、 HDD の SATA ケーブルは L 字コネクタでないと収まらない。</p>

<p><a href="https://www.dirac.co.jp/blackline/#ngg-image-7" target="_blank"><img alt="HDD" title="HDD" src="https://www.dirac.co.jp/wp-content/gallery/black-line/blkackline_08.jpg" width="300" height="300" border="0" style="margin: auto;"></a>
<a href="https://www.dirac.co.jp/blackline/#ngg-image-10" target="_blank"><img alt="HDD" title="HDD" src="https://www.dirac.co.jp/wp-content/gallery/black-line/blackline_hdd01.jpg" width="300" height="300" border="0" style="margin: auto;"></a></p>

<p>私はたまたま L 字型コネクタの SATA ケーブルを持っていたので問題なかったが、ストレート型の SATA ケーブルしか持っていなかったら困ったかもしれない。</p>

<p>以上ツッコミはいれたものの、組み立ては圧倒的に In-Win CE685 よりもやりやすく、特に電源ケーブルの引き回しに無理がない点が良い。
総合的には満足しており、もう少し工夫すればベストセラーになってもおかしくない、ある意味惜しいケースである。</p>

<hr />

<p><span style="font-size:x-small;"><A NAME="bezel">[1]</A>: 厚型の光学ドライブは <a href="https://jpn.pioneer/ja/pcperipherals/bdd/products/bdr_s12j_x/spec/img/img01.gif">トレーの周りに 1mm 程度の枠</a> があるため干渉しない</span></p>
]]></content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2021-10-31T23:13:48+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2021/06/post-880af6.html">
<title>FreeDOS の kernel と COMMAND.COM がアップデート</title>
<link>http://aimingoff.way-nifty.com/blog/2021/06/post-880af6.html</link>
<description>[以前書いた FreeDOS の記事][] から約 5 年経ち [FreeDOS...</description>
<content:encoded><![CDATA[<p><a href="/blog/2016/12/freedos-12-free.html">以前書いた FreeDOS の記事</a> から約 5 年経ち <a href="http://www.freedos.org/">FreeDOS</a> の <a href="http://kernel.fdos.org/">kernel</a> と <a href="https://github.com/FDOS/FreeCom/">FreeCOM</a> (<code>COMMAND.COM</code>) が久々にアップデートされた。
例によって自分自身はほとんど使うことが無いのだがアップデートしてみる。</p>
]]><![CDATA[<h4>新しいバージョンで何が変わったか？</h4>

<p>正直なところ、変更点に関する情報はあまりない。</p>

<h5>kernel 2.43</h5>

<p>目に見える機能的な面で変わったのは以下程度でしょう。</p>

<ul>
<li><code>CONFIG.SYS</code> 内で <code>CHAIN</code> コマンドが使えるようになった</li>
<li><code>SETVER.SYS</code> が追加された</li>
</ul>

<h5>FreeCOM 0.85</h5>

<p>COMMAND.COM の非常駐部分を XMS memory に置くことができるようになった点が大きい。
従来は <a href="https://www.atmarkit.co.jp/ait/articles/1404/24/news144.html#wi-fig01.gif">メモリを多く使う外部コマンドが実行され非常駐部分が破壊された場合に Disk から再ロードされていた</a> が、 XMS に非常駐部が置かれたままならば Disk から再ロードしないで済むため性能が向上する。</p>

<p>これ以外の変更点は正直なところよくわからない。</p>

<h4>FreeDOS/V 起動フロッピーイメージ</h4>

<p>例によってアップデートの方法は詳しくは触れない。
アップデート後のフロッピーディスクイメージのディレクトリツリーを以下に示す。</p>

<pre><code>Directory of A:\

[FDOS]         AUTOEXEC.BAT   COMMAND.COM    FDCONFIG.SYS   KERNEL.SYS
         4 file(s)        133,254 bytes
</code></pre>

<pre><code>Directory of A:\FDOS

[.]            [..]           [BIN]          [XMSSWAP]      
         0 file(s)              0 bytes
</code></pre>

<pre><code>Directory of A:\FDOS\XMSSWAP

[.]            [..]           COMMAND.COM    
         1 file(s)         85,484 bytes
</code></pre>

<pre><code>Directory of A:\FDOS\BIN

[.]            [..]           04GZN16X.FNT   ATTRIB.COM     CHEJ.EXE       
CHKDSK.EXE     COUNTRY.SYS    CP437UNI.TBL   CP932UNI.TBL   CPUID.EXE      
CPUSTAT.EXE    CWSDPMI.EXE    DELTREE.COM    DEVLOAD.COM    DISPV.EXE      
DISPVA.EXE     DISPVB.EXE     DOSLFN.COM     DSP4U.COM      DSPVV.COM      
EIDL.COM       EMSSTAT.EXE    FDAPM.COM      FDISK.EXE      FDISK.INI      
FDISKPT.INI    FONTN.INI      FONTNX.EXE     FORMAT.EXE     GURI16X.FNT    
GURI19X.FNT    JEMMEX.EXE     KEYB.EXE       KEYBOARD.SYS   LABEL.EXE      
MEM.EXE        MEMSTAT.EXE    MI.COM         MODE.COM       MORE.EXE       
MOVE.EXE       MOVEXBDA.EXE   NANSI.SYS      NLSFUNC.EXE    PANSI.SYS      
SETVER.SYS     SYS.COM        UMBM.EXE       UMBPCI.SYS     V.COM          
VASK.COM       VCHKBOX.COM    VCHOICE.COM    VCLS.COM       VCPI.EXE       
VCURSOR.COM    VDELAY.COM     VDELETE.COM    VEACH.COM      VECHO.COM      
VERRLVL.COM    VFDUTIL.COM    VFONT.COM      VFRAME.COM     VGOTOXY.COM    
VINFO.COM      VINSERT.COM    VLINE.COM      VMATH.COM      VMODE.COM      
VPAUSE.COM     VPCSPKR.COM    VPROGRES.COM   VREADKEY.COM   VSTR.COM       
VVER.COM       VVIEW.COM      XCOPY.EXE      XMSSTAT.EXE    
        77 file(s)      1,084,147 bytes
</code></pre>

<h5>kernel</h5>

<p><a href="https://github.com/FDOS/kernel/releases">kernel releases</a> から入手。
どれを使うのがいいか悩ましいところだが、私自身はとりあえず <code>kernel.zip</code> 内の <code>KERNL386.SYS</code> を <code>KERNEL.SYS</code> に rename して使用。</p>

<p>kernel は <code>SYS</code> コマンドを使ってインストールする必要があるので、単純なファイルコピーと異なり少し面倒くさい。
私は QEMU で <code>-fda</code> (<code>A:</code> 起動ディスク) と <code>-fdb</code> (<code>B:</code> 新しい <code>KERNEL.SYS</code> と <code>SYS.COM</code> の入ったイメージ) の２つのイメージファイルを使って FreeDOS を起動し、 <code>B:</code> に移って <code>SYS A:</code> コマンドでインストールした。</p>

<h5>FreeCOM</h5>

<p><a href="https://github.com/FDOS/freecom/releases">FreeCOM releases</a> から入手。
日本語版は無いので <code>English.zip</code> 内の <code>kswap/command.com</code> をルートディレクトリに、 <code>xmsswap/command.com</code> を <code>\FDOS\XMSSWAP</code> ディレクトリに入れる。</p>

<p>…と思ったら、どうも FreeCOM 0.85 で <a href="https://github.com/FDOS/freecom/issues/54">うまく動作しないこと</a> があった<del>ので、結局私自身は FreeCOM 0.84-pre7 に戻した。</del></p>

<del> `com084b7.zip` 内の `COMMANDW.COM` をルートディレクトリの `COMMAND.COM` としてコピーし、 `com084b7-xmsswap` 内の `COMMANDW.COM` を `\FDOS\XMSSWAP\COMMAND.COM` としてコピーすればいい。</del>

<p>【2021/7/15 追記】
FreeCOM 0.85a がリリースされて問題は修正された。</p>

<p>FreeCOM の方は <code>dbcswip-*</code> (<a href="https://github.com/lpproj/freecom_dbcs2/">DBCS (Double Byte Character Set) edition</a>) の開発も進んでいるので、いずれは日本語化もされるかも…。</p>

<h4><code>FDCONFIG.SYS</code></h4>

<p>kernel の変更は設定ファイルに何の影響もないが、 FreeCOM を XMSSWAP で使用するためには若干の変更が必要になる。
例によって細かい説明を抜きに実際の <code>FDCONFIG.SYS</code> の中身を晒す。</p>

<pre><code>;!SWITCHES=/F
!COUNTRY=081,,\FDOS\BIN\COUNTRY.SYS
!LASTDRIVE=Z
!BUFFERS=20
!FILES=40

!MENUCOLOR=7,1
MENU  FreeDOS
MENU ----------------------------------------------------------------------
MENU   0 - Safe Mode (don't load any drivers)
MENU   1 - XMS
MENU   2 - XMS + EMS
MENU   3 - Japanese + XMS
MENU   4 - Japanese + XMS + EMS
MENU   5 - Japanese + XMS + DPMI
MENU ----------------------------------------------------------------------
MENUDEFAULT=3,10

0?ECHO Warning: basic stuff only!

12345?DOS=HIGH
12345?DOS=UMB
12345?DOSDATA=UMB
;12345?DEVICE=\FDOS\BIN\UMBPCI.SYS /I=D000-E3FF /I=EC00-EFFF
135?DEVICE=\FDOS\BIN\JEMMEX.EXE NOEMS X=TEST I=TEST
24?DEVICE=\FDOS\BIN\JEMMEX.EXE X=TEST I=TEST
345?DEVICEHIGH=\FDOS\BIN\FONTNX.EXE
;12?DEVICEHIGH=\FDOS\BIN\NANSI.SYS /S
;345?DEVICEHIGH=\FDOS\BIN\PANSI.SYS
0?SHELL=A:\COMMAND.COM A:\ /E:1024 /P=A:\AUTOEXEC.BAT
;12345?SHELLHIGH=A:\COMMAND.COM A:\ /E:1024 /P=A:\AUTOEXEC.BAT
12345?SHELLHIGH=A:\FDOS\XMSSWAP\COMMAND.COM A:\FDOS\XMSSWAP /E:1024 /P=A:\AUTOEXEC.BAT
</code></pre>

<p>Safe Mode の時は XMS が使えないのでルートディレクトリの <code>COMMAND.COM</code> を使用し、それ以外は <code>\FDOS\XMSSWAP\</code> 配下の <code>COMMAND.COM</code> を使用するようにしている。</p>

<p><a href="/blog/2016/12/freedos-12-free.html">以前書いた FreeDOS の記事</a> から CD/DVD のドライバ利用の選択肢が無くなっているが、<del>これは手元に CD/DVD を使えるハード環境が無くなったことと、</del> <code>AUTOEXEC.BAT</code> 内でドライバをロードしなくても後からロードすればいいために外している。
<code>UMBPCI.SYS</code> はどうも不安定なのでコメントアウト状態にしているが、 386 ではない kernel を使う場合には必要になるかもしれない。</p>

<p>【追記 2023-03-18】
<a href="/blog/2016/12/freedos-12-free.html">以前書いた FreeDOS の記事</a> の方にも追記したが Jemm の GitHub にて Jemm 5.83 がリリースされ SATA 接続 CD-ROM でも動く環境ができた。
詳細は <a href="/blog/2023/03/post-f8ede5.html">Jemm v5.83 の記事</a> 参照。</p>
]]></content:encoded>


<dc:subject>DOS</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2021-06-19T14:21:02+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2020/05/post-180834.html">
<title>HDD を入れ替え</title>
<link>http://aimingoff.way-nifty.com/blog/2020/05/post-180834.html</link>
<description>一年ほど前に メインマシンを AMD Ryzen 5 2400G に した際に ...</description>
<content:encoded><![CDATA[<p>一年ほど前に <a href="/blog/2019/06/post-4a8e8e.html" target="_blank">メインマシンを AMD Ryzen 5 2400G に</a> した際に HDD を WD の Red にしたが、ここのところどうも調子が悪い。
普通にアクセスしている際には問題なく動いているように見えるが、大容量のデータを書き込んでいる途中で突然エラーし、その後はディレクトリリストすらできなくなり PC を再起動するまで復旧しない。
媒体検査では何も引っかからないので、状況からすると SATA コントローラの異常のように見える。</p>

<p>このご時世でテレワークにも使っている PC が不安定なのはまずいので、思い切って HDD を入れ替えることにした。
今回は敢えて違うベンダーの <a href="https://toshiba.semicon-storage.com/jp/storage/product/data-center-enterprise/enterprise-capacity/articles/mg06acaxxxx.html" target="_blank">東芝 MG06A</a> にしてみた。
(OS は NVMe SSD のため) HDD はデータだけであり、旧 HDD も完全に壊れる前だったから、移行はすんなり。
今のところ何も問題なく動いている。</p>

<p>以前は Power On 時に Boot せずにハングすることが度々あったが、  HDD 入れ替え後はその症状も出ていない。
リセットすれば立ち上がるため電源周りの問題かな…と思っていたが、実はこれも HDD 要因だったのかもしれない。
以前から WD にはいい印象を持っていなかったが、さらにネガティブ要素が増えてしまった。</p>
]]>
</content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2020-05-07T23:05:11+09:00</dc:date>
</item>
<item rdf:about="http://aimingoff.way-nifty.com/blog/2019/12/post-498553.html">
<title>Kodi の設定</title>
<link>http://aimingoff.way-nifty.com/blog/2019/12/post-498553.html</link>
<description>Linux 上で Kodi を動かす際の設定あれこれ</description>
<content:encoded><![CDATA[<p>久々にホームサーバの <a href="https://kodi.tv/">Kodi</a> をいじったが、忘れていたことがたくさんあったので備忘録</p>
]]><![CDATA[<h4>Kodi の自動起動</h4>

<p><a href="https://kodi.wiki/view/HOW-TO:HOW-TO:Autostart_Kodi_for_Linux">Power on で自動的に Kodi を立ち上げる方法は何種類かある</a>が、 xorg もユーザランドで動くことが確実な gdm3 を介した方法を採用。 <br />
<code>kodi</code> というユーザで auto login させて kodi を <a href="https://help.gnome.org/admin/system-admin-guide/stable/session-user.html">default session</a> として動かす。</p>

<h5><code>/etc/gdm3/daemon.conf</code> を設定</h5>

<pre><code>[daemon]
WaylandEnable=false
AutomaticLoginEnable = true
AutomaticLogin = kodi
...
</code></pre>

<h5><code>/usr/share/xsessions/kodi.desktop</code> を用意</h5>

<p>debian ならば <code>kodi-data</code> パッケージに入っている</p>

<pre><code>[Desktop Entry]
Name=Kodi
Comment=This session will start Kodi media center
Exec=kodi-standalone
TryExec=kodi-standalone
Type=Application
</code></pre>

<h5><code>/var/lib/AccountsService/users/kodi</code> を作成</h5>

<pre><code>[User]
Language=ja_JP.utf8
XSession=kodi
SystemAccount=false
</code></pre>

<h4>Kodi から CD を eject できるようにする</h4>

<p>以前はできたはずだが、いつの間にか「ディスク」メニューから<a href="https://forum.kodi.tv/showthread.php?tid=227908">メディアの eject ができなくなっていた</a>ので再設定。 <br />
※ 以前は別の設定をしていたような気もするが、既に忘却の彼方…</p>

<h5><code>sysctl</code> の設定</h5>

<p><code>/etc/sysctl.d/local.conf</code> に以下を追記</p>

<pre><code>dev.cdrom.lock=0
</code></pre>

<h5><a href="https://kodi.wiki/view/Advancedsettings.xml"><code>~/.kodi/userdata/advancedsettings.xml</code></a> を作成 (or 追記)</h5>

<p>この設定により USB Disk 等も自動マウントされなくなるが、自分の使い方ではこちらの方が良い  </p>

<pre><code>&lt;advancedsettings&gt;
&lt;handlemounting&gt;false&lt;/handlemounting&gt;
&lt;/advancedsettings&gt;
</code></pre>

<ul>
<li><a href="https://forum.libreelec.tv/thread/13945-eject-dvd-tray-with-a-key/">おまけ</a></li>
</ul>

<h4><a href="https://kodi.wiki/view/Advancedsettings.xml#jsonrpc">jsonrpc</a> のポート番号変更</h4>

<p>kodi はデフォルトでポート 9090 を <a href="https://kodi.wiki/view/Advancedsettings.xml#jsonrpc">jsonrpc</a> に使用してしまい <a href="https://prometheus.io/">Prometheus</a> と競合するのでポート番号を変更 <br />
これも <code>~/.kodi/userdata/advancedsettings.xml</code> に設定する</p>

<pre><code>&lt;advancedsettings&gt;
&lt;jsonrpc&gt;
    &lt;compactoutput&gt;false&lt;/compactoutput&gt;
    &lt;tcpport&gt;9999&lt;/tcpport&gt;
&lt;/jsonrpc&gt;
&lt;/advancedsettings&gt;
</code></pre>

<p>※ 紛らわしく Kodi にも Prometheus という名の add-on があるが、ここでいう <a href="https://prometheus.io/">Prometheus</a> はサーバ監視ソフト</p>

<h4>Kodi の <a href="https://github.com/xbmc/xbmc/blob/master/docs/README.Linux.md">build</a></h4>

<p>Debian のパッケージのままでいいが、新しい Kodi 18 (Leia) を使う場合や標準的ではないライブラリを使う場合には自前で build が必要。 <br />
ここでは余計なことを書かずに自分用の備忘録として…</p>

<pre><code>$ git clone -b Leia https://github.com/xbmc/xbmc.git kodi
$ cd kodi
$ git checkout refs/tags/18.7-Leia
$ cd ..
$ mkdir kodi-build
$ cd kodi-build
$ cmake ../kodi -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_INCLUDE_PATH=/home/src/local/include -DCMAKE_LIBRARY_PATH=/home/src/local/lib -DFFMPEG_PATH=/home/src/local -DENABLE_INTERNAL_FLATBUFFERS=ON -DENABLE_INTERNAL_RapidJSON=ON -DENABLE_INTERNAL_CROSSGUID=OFF
$ cmake --build .
$ sudo make install
$ cd ..
</code></pre>

<pre><code>$ git clone -b Leia https://github.com/xbmc/visualization.projectm.git
$ cd visualization.projectm && mkdir build && cd build
$ cmake -DADDON_SRC_PREFIX=../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../../kodi-build/addons -DPACKAGE_ZIP=1 -DADDONS_TO_BUILD=visualization.projectm  ../../kodi/cmake/addons
$ make
$ cd ../../kodi-build/addons/visualization.projectm
$ sudo mkdir -p /usr/local/lib/kodi/addons/visualization.projectm
$ sudo cp -a *.so* /usr/local/lib/kodi/addons/visualization.projectm
$ sudo mkdir -p /usr/local/share/kodi/addons/visualization.projectm
$ sudo cp -a addon.xml resources /usr/local/share/kodi/addons/visualization.projectm
$ sudo chown root:root -Rh /usr/local/lib/kodi/addons/visualization.projectm /usr/local/share/kodi/addons/visualization.projectm
$ sudo ldconfig
</code></pre>

<p>【2021-05-16 追記】
Debian Buster で Kodi 19 (Matrix) を Build する場合。 <br />
buster-backports で <code>libflatbuffers-dev</code> パッケージ等を入れている前提。 <br />
Buster では waylandpp-dev パッケージが無いため、ターゲットプラットフォームから wayland を外す指定が必須。 <br />
以前からできたのかもしれないが、 Kodi プロジェクトで管理している addon の build は簡単になった。</p>

<pre><code>$ cd kodi
$ git checkout Matrix
$ git checkout refs/tags/19.1-Matrix
$ cd ..
$ mkdir kodi-build
$ cd kodi-build
$ cmake ../kodi -DCORE_PLATFORM_NAME="x11 gbm" -DAPP_RENDER_SYSTEM=gl -DCMAKE_INSTALL_PREFIX=/usr/local \
        -DCMAKE_INCLUDE_PATH=/home/src/local/include -DCMAKE_LIBRARY_PATH=/home/src/local/lib -DFFMPEG_PATH=/home/src/local \
        -DENABLE_INTERNAL_RapidJSON=ON -DENABLE_INTERNAL_CROSSGUID=OFF \
        -DCMAKE_EXE_LINKER_FLAGS="-lharfbuzz"
$ cmake --build .
$ sudo make install
</code></pre>

<pre><code>$ make -j2 binary-addons ADDONS="pvr.hts screensaver.* visualization.*"
$ cd addons
$ for d in *; do if [ -r $d/*.so ]; then
    sudo mkdir -p /usr/local/lib/kodi/addons/$d
    sudo cp -pd $d/*.so* /usr/local/lib/kodi/addons/$d
    sudo mkdir -p /usr/local/share/kodi/addons/$d
    sudo cp -ad $d/addon.xml $d/resources /usr/local/share/kodi/addons/$d
    sudo chown root:root -Rh /usr/local/lib/kodi/addons/$d /usr/local/share/kodi/addons/$d
  fi; done
$ sudo ldconfig
</code></pre>

<h4>その他リンク</h4>

<ul>
<li><a href="https://wiki.archlinux.jp/index.php/Kodi">Arch Linux Wiki</a></li>
<li><a href="https://kodi.wiki/view/External_players">External players</a></li>
<li><a href="https://kodi.wiki/view/Keymap">Keymap</a></li>
<li><a href="https://kodi.wiki/view/List_of_keynames">List of keynames</a></li>
<li><a href="https://kodi.wiki/view/Userdata">userdata</a></li>
<li><a href="http://kodi.inpane.com/main/rc/">赤外線リモコン</a></li>
<li><a href="http://sotoburo.blog.fc2.com/blog-entry-138.html">リモコンキー設定</a></li>
</ul>
]]></content:encoded>


<dc:subject>パソコン・インターネット</dc:subject>
<dc:subject>Linux</dc:subject>

<dc:creator>Aiming Off</dc:creator>
<dc:date>2019-12-02T00:18:34+09:00</dc:date>
</item>


</rdf:RDF>
