Arch Linux の Docker Image を作る

Dockerhub に ArchLinux のイメージがあるので自分で作る必要はないものの base image を作ったことがなかったので勉強がてら作ってみた。

hub.docker.com

環境

$ mkdir archlinux-docker
$ cd archlinux-docker
$ wget http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/iso/2020.06.01/archlinux-bootstrap-2020.06.01-x86_64.tar.gz
$ sudo tar xf archlinux-bootstrap-2020.06.01-x86_64.tar.gz

pacman を使えるようにするために近くのミラーサーバのコメントを外す

$ sudo vim root.x86_64/etc/pacman.d/mirrorlist

pacman を使うとスペースが足りないというエラーがでるので pacman.confCheckSpaceコメントアウトする。

$ sudo sed -i s/CheckSpace/#CheckSpace/ root.x86_64/etc/pacman.conf

chroot で入って必要なものをインストールする。

$ sudo root.x86_64/bin/arch-chroot root.x86_64/
$ pacman-key --init
$ pacman-key --populate archlinux
$ pacman -Syu base
$ exit

tar で固めて docker import で image を作る

$ sudo tar -C root.x86_64 -c . | docker import - archlinux

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
archlinux           latest              af69942a9094        10 seconds ago      641MB

$ docker run --rm archlinux cat /etc/os-release
NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
BUILD_ID=rolling
ANSI_COLOR="38;2;23;147;209"
HOME_URL="https://www.archlinux.org/"
DOCUMENTATION_URL="https://wiki.archlinux.org/"
SUPPORT_URL="https://bbs.archlinux.org/"
BUG_REPORT_URL="https://bugs.archlinux.org/"
LOGO=archlinux

参考

Julia - Terminal で 1文字ずつ入力を受ける (raw mode)

環境

  • Julia v1.4.2
  • OS: ArchLinux

readreadline を使うと EOF を入力 (Ctrl-D) したときや Enter を押したときにキーボードから入力したものを取得することができるが、何かしらのキーをタイプする度に入力を取得する方法を紹介する。

# ex.jl
using REPL

terminal = REPL.Terminals.TTYTerminal(get(ENV, "TERM", Sys.iswindows() ? "" : "dumb"), Base.stdin, Base.stdout, Base.stderr)

function readChar(term)
    c = Char(read(term.in_stream, 1)[1])
    println("$(c) $(Int(c))")
    return c
end

REPL.Terminals.raw!(terminal, true)
while true
    Char(readChar(terminal)[1]) == 'q' && break
end

while loop の print は1文字ずつ入力する毎に出力される。

$ julia ex.jl
a 97
b 98
c 99
d 100
e 101
q 113

一方で raw! を使わない場合だと、Enter が入力されるまで while loop の内容は出力されない。

# ex2.jl
using REPL

terminal = REPL.Terminals.TTYTerminal(get(ENV, "TERM", Sys.iswindows() ? "" : "dumb"), Base.stdin, Base.stdout, Base.stderr)

function readChar(term)
    c = Char(read(term.in_stream, 1)[1])
    println("$(c) $(Int(c))")
    return c
end

while true
    Char(readChar(terminal)[1]) == 'q' && break
end
$ julia ex2.jl
abcdeq
a 97
b 98
c 99
d 100
e 101
q 113

上記の例はスクリプトとして実行したが、これを REPL にコピペしても同じ動きにはならない。raw! を使っていてもカノニカルモードになってしまう。

julia> using REPL

julia> terminal = REPL.Terminals.TTYTerminal(get(ENV, "TERM", Sys.iswindows() ? "" : "dumb"), Base.stdin, Base.stdout, Base.stderr)
REPL.Terminals.TTYTerminal("xterm-termite", Base.TTY(RawFD(0x0000000a) paused, 0 bytes waiting), Base.TTY(RawFD(0x0000000d) open, 0 bytes waiting), Base.TTY(RawFD(0x0000000f) open, 0 bytes waiting))

julia> function readChar(term)
           c = Char(read(term.in_stream, 1)[1])
           println("$(c) $(Int(c))")
           return c
       end
readChar (generic function with 1 method)

julia> REPL.Terminals.raw!(terminal, true)
true

julia> while true
           Char(readChar(terminal)[1]) == 'q' && break
       end
abced
a 97
b 98
c 99
e 101
d 100

 10
q
q 113

しかし、while loop のなかで raw! を実行すると raw mode になる。

julia> while true
           REPL.Terminals.raw!(terminal, true)
           Char(readChar(terminal)[1]) == 'q' && break
       end
a 97
b 98
c 99
d 100
e 101
q 113

while loop 以外にも function, begin, let など新しくスコープを作るもののなかに raw! を入れると、そのスコープ内では raw mode になるようである。

参考

AmazonLinux 2 で parquet-tools をビルド

ビルドに必要なものを用意する

yum install -y wget git tar gcc gcc-c++ boost-devel make maven
wget -nv http://archive.apache.org/dist/thrift/0.12.0/thrift-0.12.0.tar.gz && \
    tar xzf thrift-0.12.0.tar.gz && \
    cd thrift-0.12.0 && \
    chmod +x ./configure && \
    ./configure --disable-libs && \
    make install
git clone -b apache-parquet-1.11.0 --depth 1 https://github.com/apache/parquet-mr
cd parquet-mr/parquet-tools/

依存ライブラリ不足でビルドに失敗したので dependencies に以下を追加

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.10.0</version>
</dependency>
mvn clean package -Plocal

target/parquet-tools-1.11.0.jar にファイルができる。

Dockerfile

# parquet-tools
FROM amazonlinux:2
RUN yum install -y wget git tar gcc gcc-c++ boost-devel make maven
RUN wget -nv http://archive.apache.org/dist/thrift/0.12.0/thrift-0.12.0.tar.gz && \
    tar xzf thrift-0.12.0.tar.gz && \
    cd thrift-0.12.0 && \
    chmod +x ./configure && \
    ./configure --disable-libs && \
    make install

COPY pom.xml /tmp/pom.xml  # dependency を追加した pom.xml をカレントディレクトリに置いておく
RUN git clone -b apache-parquet-1.11.0 --depth 1 https://github.com/apache/parquet-mr /root/parquet-mr && \
    cd /root/parquet-mr/parquet-tools && \
    mv /tmp/pom.xml . && \
    mvn clean package -Plocal

4bit CPU TD4 を作った

GW をフルに使って自作界隈では有名な「CPUの創りかた」の TD4 を作ってみました。

CPUの創りかた

CPUの創りかた

  • 作者:渡波 郁
  • 発売日: 2003/10/01
  • メディア: 単行本(ソフトカバー)

f:id:goropikarikun:20200513234135g:plain

実は2年前にすでにパーツ類は購入済みだったのですが、当時はアセンブリ機械語の経験がなかったため本の命令フォーマットのところがいまいち理解できず、結局作らずじまいになってしまっていました。

現在は、コンパイラ作成の経験のおかげで多少なりともアセンブリの読み書きにも慣れていたので、比較的すいすいと内容を理解することができました。

概ねオリジナルの TD4 と同じ実装にしましたが、ROM の横に LED を追加したのと、74HC154 が手に入らなかったので 74LS138 を使ったところがオリジナルとの主な変更点です。74HC154 以外の IC は秋月やマルツ経由で Digi-Key から購入して揃えました。 74HC154 の置き換えに関してはこちらの方の投稿を参考にさせていただきました。

オリジナルからの変更点|cuboktahedron|note

全体像はこんな感じ

f:id:goropikarikun:20200513225148j:plain

f:id:goropikarikun:20200513225201j:plain

配線がなかなか苦しいことになっています。基本的には黒いビニール線を使いましたが、作成途中でカラフルなビニール線を買っていたことを思い出したのでなんとなく使ってみました。作成初期から使っていたら、どこをどこに配線したのかが見やすかったかもしれません。

今回は配線する前には回路図を改めて書いていたので配線箇所を間違えることなく進めることができました。

f:id:goropikarikun:20200513232423p:plain

f:id:goropikarikun:20200513231630j:plain

こまめに接続確認もしていたので手戻り作業を減らすことができたのかなと思います。 ただ、線と線の間隔が狭すぎたところは、はんだ付けしている最中に隣の線のビニールを溶かしてしまったようでショートが起きてしまいました。 最終的な動作確認のときに想定外の動作に気づいたのでそのときは絶望しかなかったですが、すぐにに原因箇所が見つかってスパゲッティコードデバッグ沼に踏み込むことはありませんでした。

今回簡易的なものとはいえ CPU を作ってみたことで、コンパイラを作ったときに疑問に思ったニーモニック機械語との1対1の対応関係や、その機械語を CPU はどのように解釈するのかといったところを身を以て学ぶことができた思います。 とはいえ、 IC で CPU 作るのは結構結構辛いなぁと思ったので次回作成するときは FPGA を使ったり、配線の負担を減らすためにプリント基板を使いたいと思いました。

github.com

自宅ではじめるDocker入門 を読んだ

日々、Docker を使っているものの今まで体系的に学んだことがないと気付いたので1冊買って勉強してみた。 約5時間で読了。

全体的に丁寧な解説でコマンドも省略せずに書かれていてとても読みやすい印象でした。 最後の docker-compose の章を除き、標準の docker コマンドで解説してくれているので今までなぁなぁにしてしまっていたコンテナ間通信が裏では何をやっていたのかがわかって有意義でした。