20200125のLinuxに関する記事は10件です。

気軽にディスクを暗号化してみる

はじめに

中古ハードディスクの中身を覗かれて困っている人が居るようです。
暗号化していれば、物理的に覗かれたとしても論理的には覗かれません。

Linux だと非常に気軽にディスクを暗号化できます。

概略

luks を使って暗号化します。コマンドとしては cryptsetup を使います。

暗号化手順

# cryptsetup luksFormat <device_name>

デバイスの中身が消えるけど良いかと尋ねてきます。大文字で YES と応じます。
続いてパスフレーズを尋ねられます。例によって同じパスフレーズを2回入力します。

オープン手順

暗号化されているデバイスにアクセスできるようにするステップです。

# cryptsetup open <device_name> <mapped_name>

パスフレーズを聞かれます。
/dev/mapper/<mapped_name> にマップされます。

利用

ブロックデバイス /dev/mapper/<mapped_name> を好きなように利用します。
mkfs したり mount したり。何なら pvcreate も。

クローズ手順

オープンの逆です。
もしマウントしているなら先にアンマウントしましょう。

# cryptsetup close <mapped_name>

おまけ

単一パーティーションで非暗号化 rootfs を使っているなら、swapfile のようにファイルを使うのも手です。dd if=/dev/zero で空ファイルを作って cryptsetup luksFormat すればいいだけです。
SSD なら気になるほど性能低下しないと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WebDAVをnginxだけで作る備忘録

はじめに

この記事はdebian系列(Ubuntu系列)をベースに解説しています。

WebDAVのメソッドはnginxの標準debパッケージにも搭載されていますが、一部機能のメソッド(PROPFIND,OPTIONS)がなく、一部アプリではうまく動作しなかったりするのでそのメソッドを追加するための記事を書いてます。

※nginx公式のリポジトリを追加していることが前提です。

記事に書いてある*にはバージョンが入ります。

ビルド

デフォルトのモジュールには搭載されていないため、モジュールを追加してnginxをビルドをする必要があります。

ソースコードを入手

aptコマンドでnginxのソースコードを取り寄せます。
ディレクトリは特に問いませんが、/usr/src/あたりに置いておくといいでしょう。

# apt source nginx

取り寄せが終わるとカレントディレクトリにソースコード(nginx-*.*.*)が置かれます。

ビルド依存パッケージのインストール

ソースルートディレクトリのdebian/controlっていうファイルのBuild-dependsに依存パッケージが書かれているのでそれを頼りにインストールします。
なお、今回インストールしたバージョン(1.16.1)の依存パッケージは以下のとおりです。

# apt install debhelper dh-systemd dpkg-dev quilt lsb-release libssl-dev libpcre3-dev zlib1g-dev

build-essentialも入れておくと無難です。

WebDAV拡張モジュールの取り込み

ソースルートディレクトリで以下のコマンドを実行します。

# git clone https://github.com/arut/nginx-dav-ext-module.git

そのあと、debパッケージにするために少しだけ内容を変更します。

debian/rules
# 省略
# 39~41行目付近
config.status.nginx: config.env.nginx
        cd $(BUILDDIR_nginx) && \
        # 最後の方に" --add-module=/path/to/nginx-*.*.*/nginx-dav-ext-module "を追加。
        # ディレクトリは適宜変更。
        CFLAGS="" ./configure --prefix=/etc/nginx ... --add-module=/path/to/nginx-*.*.*/nginx-dav-ext-module
        touch $@

# 44~46行目付近
config.status.nginx_debug: config.env.nginx_debug
        cd $(BUILDDIR_nginx_debug) && \
        # 上と同様のものを追加。
        CFLAGS="" ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx ... --add-module=/path/to/nginx-*.*.*/nginx-dav-ext-module
        touch $@
# (省略)

ビルドタイム

これを実行してあとは待つだけです。

# dpkg-buildpackage -uc -b

無事に終わるとdebパッケージがソースルートディレクトリの1つ上にできます。

インストールして確認

あとはできたものをdpkgでインストールするだけです。

# dpkg -i nginx_*.*.*_*.deb

インストールが終わったら以下のコマンドを実行して確認します。

$ nginx -V

configure arguments--with-http_dav_module--add-module=/path/to/nginx-*.*.*/nginx-dav-ext-moduleが入っていれば完了です。

設定する

大まかな設定は割愛します。任意で変更してください。

location / {
  # 必要であれば設定
  # auth_basic "Authorize dialog message";
  # auth_basic_user_file /path/to/.htpasswd;

  # 標準搭載のメソッドと追加モジュール分のメソッドの設定
  dav_methods PUT DELETE MKCOL COPY MOVE;
  dav_ext_methods PROPFIND OPTIONS;

  # ファイル一覧を表示する設定
  autoindex on;
  autoindex_exact_size off;
  autoindex_localtime on;

  # 読み書きの権限設定
  dav_access user:rw group:rw all:r;

  # 一時ファイル・ディレクトリ作成の許可
  client_body_temp_path /var/www/.webdavtmp;
  create_full_put_path on;
}

nginx再起動して、おしまい。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SereneLinuxに日本語入力システムを導入する

もくじ

  1. SereneLinuxとは
  2. 日本語入力システムの導入
  3. さいごに

1.SereneLinuxとは

Ubuntu派生のLinuxディストリビューションです。
なんと作者は日本人の学生です!
実は私もSereneLinuxの開発チームに所属しております。皆さん凄い人ばかりでつよいを通り越して皆さん怖いです...
公式サイトはこちらです https://serenelinux.com

2.日本語入力システムの導入

ここから本題です!
まず、SereneLinuxではGUIを用いて簡単にソフトウェアの導入が可能となっております
それがこちらです!1.png
SereneStartdash
こちらを使っていきます。
デスクトップ上のアイコンをダブルクリックしてください。
2.png
パスワードが求められるので自分のパスワードを入力してください。

3.png
起動したらまず「アップグレード」をクリックしてください。

4.png
少々お待ちください...

5.png
パッケージの最新化が完了したらはじめの画面に戻ります。
次は「追加と削除」をクリックしてください。

6.png
確認画面が出てきますので「読み込み開始」をクリックしてください。

7.png
はい、こちらがインストール可能なソフトウェアとなっております。
沢山ありますが、ここの中から「日本語入力システム」を選択し"OK"をクリックしてください。

8.png
少々お待ちください。

9.png
少し怖いですが前に進むしかありません!
「続行する」をクリックしてください。

10.png
インストール中です...

11.png
完了しました。"OK"をクリックして終了してください。

これで日本語入力ができるようになっているはずです。
もし出来ない場合は一度ログアウト後再度ログインをお願いします。

何かご不明な点がございましたらこちらまでご連絡をお願いします。
https://twitter.com/SereneDevJP

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

計算GPUサーバーをLTSPでディスクレス化する

はじめに

某大の某研で学生用の計算サーバーを管理しています。
計算サーバーの増加にメンテナンスが追いついておらず、ソフトウェアの更新も激しいです。
そもそも、それぞれのサーバーにOSがインストールされていることが諸悪の根源です。
OSをLANからブートするPreboot eXecution Environment(PXE) ブートで管理コストを削減します。
ホストの管理としてLinux Terminal Server Project(LTSP)を使います。

PXE/LTSPで何ができるの?

https://ltsp.org/
何ができるのかざっくりと言うならば、

設定済みサーバーのコピーをポンポン作れる、超簡単に。

です。コピー先のOSをインストールする必要がありません。
そもそもSSHやHDDをセットアップする必要もないです。

0. 準備

準備するもの

  • LAN環境
  • PC二台

環境

PXEブートではDHCPの設定が必要ですが、今回はDHCPプロキシという機能を使います。
DHCPサーバーはルーター付属のものをそのまま使い、特別な設定はありません。

筆者の環境ではNISNFSでアカウントが管理されています。
これらの管理システムがない状態でも使うことができるように説明します。
しかし、可用性の観点からNISやNFSによるアカウント管理、データの冗長化をお勧めします。

この記事ではUbuntu Server 18.04.3で動作確認します。
そこそこ良いワークステーションをホストにしましょう。
依存関係のトラブルは面倒なので、クリーンインストールした状態から説明を始めます。

GPU環境を導入する場合は、ホストとクライアントのどちらにもGPUを差しておいてください。
GPUドライバの都合、BIOSのセキュアブートをOFFにする必要があるかもしれません。
ホストにはGPUがなくても動作するかもしれませんが、未確認です。

Internet <--> Router(DHCP) <--(HUB)--> Host
                                |--> Client_1
                         NIS <--|--> Client_2
                         NFS <--|--> Client_n

1. LTSPの導入

インストール

ホストマシンにLTSPを導入します。
LTSPのインストールページの通りに進めます。

$ sudo apt -y purge --auto-remove indicator-application mate-hud snapd
$ sudo apt -y install synaptic
$ sudo add-apt-repository -y ppa:ltsp
$ sudo apt update
$ sudo apt -y install --install-recommends ltsp ltsp-binaries dnsmasq nfs-kernel-server openssh-server squashfs-tools ethtool net-tools epoptes

LTSPの初期設定

細かいオプションがありますが、ほとんどの環境ではデフォルト設定で良いです。
詳しくはLTSPのインストールページドキュメントを見てください。

$ sudo ltsp dnsmasq
$ sudo install -m 0660 -g sudo /usr/share/ltsp/common/ltsp/ltsp.conf /etc/ltsp/ltsp.conf
$ sudo ltsp image /
$ sudo ltsp ipxe
$ sudo ltsp nfs
$ sudo ltsp initrd

この時点で、ブートができるようになっています。
クライアントから起動してログインできるか確認しましょう。
BIOSの設定からNetwork Boot(PXE BOOT)を有効にし、起動順序でLANを優先にします。
初期設定で既に、/homeがNFSでマウントされているため、環境によってはこれだけで十分かもしれません。

2. SSHリモートアクセスの設定(Option)

計算サーバーはSSHで接続する必要があります。
SSHの有効化と静的IPの設定をします。
各サーバーのMACアドレスが必要です。

クライアント用のSSHホスト鍵を作成

$ sudo mkdir -p /etc/ltsp/etc/ssh
$ sudo ssh-keygen -A -f /etc/ltsp
$ sudo mv /etc/ltsp/etc/ssh/ssh_host_* /etc/ltsp/ # 鍵が思った場所に生成されないので移動
$ sudo rm -r /etc/ltsp/etc/

SSHの設定を追加

$ sudo vim /etc/ltsp/ltsp.conf
[clients]
KEEP_SYSTEM_SERVICES="ssh"
POST_INIT_CP_KEYS="mv /etc/ltsp/ssh_host_* /etc/ssh/"

それぞれのクライアント用に静的IPの設定を追加

$ sudo vim /etc/ltsp/ltsp.conf
[00:11:22:33:44:55]
HOSTNAME="client1"
KERNEL_PARAMETERS="ip=192.168.0.10:\${srv}:\${gateway}:\${netmask}"

3. GPUの設定(Option)

NvidiaのGPUを使う場合はホストにnvidia-driverをインストールします。
CUDAも一緒にインストールします。
LTSPの設定に追加は不要です。
ただし、ディスプレイをGPUに接続すると画面がはみ出します。(原因調査中)

$ wget https://developer.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.105_418.39_linux.run
$ sudo sh cuda_10.1.105_418.39_linux.run --silent --driver --toolkit

4. NISとNFSの設定(Option)

ホストでNISを設定してください。ホストでNFSは設定しません。
クライアントでNFSを有効にするために、FSTABの記述を加える必要があります。

$ sudo vim /etc/ltsp/ltsp.conf
[clients]
FSTAB_HOME="file-server:/home /home nfs defaults"

5. 運用

ホスト環境やLTSPの設定を変更した場合は以下を実行する必要があります。
その後、クライアントを再起動すると反映されます。

$ sudo ltsp image /
$ sudo ltsp ipxe
$ sudo ltsp nfs
$ sudo ltsp initrd

さいごに

後任への引継ぎ資料も兼ねて、ここに備忘録を記します。
不明点や間違いの指摘があればコメントにお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

計算サーバーをLTSPでディスクレス化する

はじめに

某大の某研で学生用の計算サーバーを管理しています。
計算サーバーの増加にメンテナンスが追いついておらず、ソフトウェアの更新も激しいです。
そもそも、それぞれのサーバーにOSがインストールされていることが諸悪の根源です。
OSをLANからブートするPreboot eXecution Environment(PXE) ブートで管理コストを削減します。
ホストの管理としてLinux Terminal Server Project(LTSP)を使います。

PXE/LTSPで何ができるの?

https://ltsp.org/
何ができるのかざっくりと言うならば、

設定済みサーバーのコピーをポンポン作れる、超簡単に。

です。コピー先のOSをインストールする必要がありません。
そもそもSSHやHDDをセットアップする必要もないです。

0. 準備

準備するもの

  • LAN環境
  • PC二台

環境

PXEブートではDHCPの設定が必要ですが、今回はDHCPプロキシという機能を使います。
DHCPサーバーはルーター付属のものをそのまま使い、特別な設定はありません。

筆者の環境ではNISNFSでアカウントが管理されています。
これらの管理システムがない状態でも使うことができるように説明します。
しかし、可用性の観点からNISやNFSによるアカウント管理、データの冗長化をお勧めします。

この記事ではUbuntu Server 18.04.3で動作確認します。
そこそこ良いワークステーションをホストにしましょう。
依存関係のトラブルは面倒なので、クリーンインストールした状態から説明を始めます。

GPU環境を導入する場合は、ホストとクライアントのどちらにもGPUを差しておいてください。
GPUドライバの都合、BIOSのセキュアブートをOFFにする必要があるかもしれません。
ホストにはGPUがなくても動作するかもしれませんが、未確認です。

Internet <--> Router(DHCP) <--(HUB)--> Host
                                |--> Client_1
                         NIS <--|--> Client_2
                         NFS <--|--> Client_n

1. LTSPの導入

インストール

ホストマシンにLTSPを導入します。
LTSPのインストールページの通りに進めます。

$ sudo apt -y purge --auto-remove indicator-application mate-hud snapd
$ sudo apt -y install synaptic
$ sudo add-apt-repository -y ppa:ltsp
$ sudo apt update
$ sudo apt -y install --install-recommends ltsp ltsp-binaries dnsmasq nfs-kernel-server openssh-server squashfs-tools ethtool net-tools epoptes

LTSPの初期設定

細かいオプションがありますが、ほとんどの環境ではデフォルト設定で良いです。
詳しくはLTSPのインストールページドキュメントを見てください。

$ sudo ltsp dnsmasq
$ sudo install -m 0660 -g sudo /usr/share/ltsp/common/ltsp/ltsp.conf /etc/ltsp/ltsp.conf
$ sudo ltsp image /
$ sudo ltsp ipxe
$ sudo ltsp nfs
$ sudo ltsp initrd

この時点で、ブートができるようになっています。
クライアントから起動してログインできるか確認しましょう。
BIOSの設定からNetwork Boot(PXE BOOT)を有効にし、起動順序でLANを優先にします。
初期設定で既に、/homeがNFSでマウントされているため、環境によってはこれだけで十分かもしれません。

2. SSHリモートアクセスの設定(Option)

計算サーバーはSSHで接続する必要があります。
SSHの有効化と静的IPの設定をします。
各サーバーのMACアドレスが必要です。

クライアント用のSSHホスト鍵を作成

$ sudo mkdir -p /etc/ltsp/etc/ssh
$ sudo ssh-keygen -A -f /etc/ltsp
$ sudo mv /etc/ltsp/etc/ssh/ssh_host_* /etc/ltsp/ # 鍵が思った場所に生成されないので移動
$ sudo rm -r /etc/ltsp/etc/

SSHの設定を追加

$ sudo vim /etc/ltsp/ltsp.conf
[clients]
KEEP_SYSTEM_SERVICES="ssh"
POST_INIT_CP_KEYS="mv /etc/ltsp/ssh_host_* /etc/ssh/"

それぞれのクライアント用に静的IPの設定を追加

$ sudo vim /etc/ltsp/ltsp.conf
[00:11:22:33:44:55]
HOSTNAME="client1"
KERNEL_PARAMETERS="ip=192.168.0.10:\${srv}:\${gateway}:\${netmask}"

3. GPUの設定(Option)

NvidiaのGPUを使う場合はホストにnvidia-driverをインストールします。
CUDAも一緒にインストールします。
LTSPの設定に追加は不要です。
ただし、ディスプレイをGPUに接続すると画面がはみ出します。(原因調査中)

$ wget https://developer.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.105_418.39_linux.run
$ sudo sh cuda_10.1.105_418.39_linux.run --silent --driver --toolkit

4. NISとNFSの設定(Option)

ホストでNISを設定してください。ホストでNFSは設定しません。
クライアントでNFSを有効にするために、FSTABの記述を加える必要があります。
こちらの記事 CentOS7(研究室内新設サーバー)の設定メモ が参考になるかもしれません。

$ sudo vim /etc/ltsp/ltsp.conf
[clients]
FSTAB_HOME="file-server:/home /home nfs defaults"

5. 運用

ホスト環境やLTSPの設定を変更した場合は以下を実行する必要があります。
その後、クライアントを再起動すると反映されます。

$ sudo ltsp image /
$ sudo ltsp ipxe
$ sudo ltsp nfs
$ sudo ltsp initrd

さいごに

後任への引継ぎ資料も兼ねて、ここに備忘録を記します。
不明点や間違いの指摘があればコメントにお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【OS/Linux】プロセス、スレッド、メモリ管理について

知識不足だー

SRE業務についてから、OSの仕組みやLinuxの仕組みの知識が不足していると日々感じます。
最近はその周辺の本を読み漁り、知識を徐々に補完していってなんとかやってます。
この記事はその補完した際のアウトプットになります。
ご指摘ありましたら、コメントいただけると幸いです。

またこの記事を書くにあたり、下記の書籍を主に参考にしました!
インフラエンジニアの教科書2 スキルアップに効く技術と知識

プロセスとスレッド

プロセス

OS上の最小実行単位のことを指します。
プロセスは、CPUリソースが割り当てられる事によって、実行されます。

プロセスを構成する要素

  • PID
  • プログラム
  • データ
  • ファイル記述子
  • コンテキスト
  • スレッド

状態遷移

「実行まち」、「実行中」、「休止中」の状態があります。
プロセスが作成されてからその都度、様々な状態に遷移します。

新しいプロセスの作成

新しいプロセスを作成する場合は、すでに存在しているプロセスをコピーする(forkすると言います)ことから始まります。
コマンドでも確認できるので、ぜひ確認してみてください。
pstree

仮にlsコマンドを打ち込んだ場合は下記の順序で実行されます。

1. lsコマンドを打つ
2. bashプロセスがforkされる
3. 子プロセス生成(仮想メモリを割り当てられる。)
4. execシステムコールによって子プロセスの中身がlsコマンドになる

スレッド

並列処理ができるように、プロセス内に複数作ることができるタスクの実行単位のことです。

image.png

プロセスとの違い

同じ構造体なのですが、buildするときにメモリ空間をコピーするかなどのフラグを渡すことで、threadを実現しています。

Processを作るときには、親プロセスのすべての情報が子プロセスに引き継がれ、さらに子プロセス用に仮想メモリを確保されるので、比較的重い処理になります。

下記記事でも書かれている通り、歴史的背景でいうと、初めはプロセスだけで、スレッドはなかったです。
そしてプロセスを作成するときは、親のプロセスが子プロセスをforkして全ての情報が引き継がれので、どうしても非効率になってしまう。
それをプロセスのメモリ空間を共有し、並列処理を実現することができているのがスレッドだと考えています。

並行処理、並列処理のあれこれ - Qiita

ミュータックス

1つのスレッドからしか書き換えができないようにしている仕組み

メモリ管理

プロセスを作成するときは、仮想メモリを割り当てられ、プロセスが実行されます。

全体像

image.png

物理メモリ

主記憶装置(メインメモリ/RAM)を指します。

仮想メモリ

システムに実際以上のメモリがあるかのように見せる仕組みのことを指します。
プロセスがメモリアクセスを行う際は、仮想メモリを通して行います。

The Linux Kernel

MMU

仮想記憶のアドレスと物理メモリのアドレスの変換は CPUに組み込まれたMMU (Memory Management Unit: メモリ管理ユニット) が行う。MMUはページングテーブルという情報を持って入り、それを使用し、変換を行なっています。
またこの対応付のことをマッピングと呼びます。
【図解】仮想記憶(仮想メモリ)の本質や仕組み、メリット 〜スワップ、MMU、ページングテーブルについて〜 | SEの道標

スワップ

プロセスがOSに対して、メモリ割り当てを要求した時に物理メモリが不足していたとします。
その場合、すでに割り当てられている物理メモリ空間をスワップ領域に逃します。(スワップアウト)
逆に、追い出したデータが必要になったときは、スワップ領域から物理メモリ空間にデータが戻ってきます。(スワップイン)
仮想記憶のうち、HDDを使用する使用する領域がスワップ領域ということです。

システムコール

OSは『システムコール』という関数(API)を一般的なプログラム向けに提供しており、原則そのシステムコールにより間接的にアクセスすることになっています

インターフェースのイメージだと思っています。・
Linuxカーネルへのアクセスを仲介してくれます。

【図解】初心者向けユーザー空間とカーネル空間,システムコール,MMU/メモリ保護,の仕組み | SEの道標

Linuxカーネル

ハードウェアとソフトウェアの仲立ちをしてくれるものがOSです。LinuxカーネルはそんなOSの基幹部分の機能である

下記記事のこの説明がかなりしっくりきました。

【初心者向け】Linuxカーネルって一体なんだ? - Qiita

image.png
下記より引用
ファイル:Layer-of-System.png

カーネル空間とユーザー空間

ユーザー空間とは、アプリケーション(OS上で動作するソフトウェア)が使用するメモリ領域のことであり、
カーネル空間とは、カーネルが使用するメモリ領域のことを指します

これはMMUの中で、カーネル空間とユーザー空間が分けられています。

なぜ分ける必要があるのか

カーネル空間に誰でもアクセスできるようになった場合、OSに対してアクセスできることに繋がります。
これは、同時にOSそのものを破壊しかねません。
そのため、あえてこのように空間を分けることにしているのです。

カーネル空間を使用したい場合

ユーザーモードのプロセスでは、カーネル空間にアクセスすることはできません。
だけど使用したいというときにそこで、Context Switchという機能によってユーザモードとカーネルモードの切り替えを実現することができています。

Linuxカーネル超入門
ユーザー空間とカーネル空間 | Linuxデバイスドライバ開発入門

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VirtualBox上にCentOSをインストールする際、「セッションが開けませんでした」と出た時の対処法

Hyper-Vを無効化しているのに、VT-xが有効にならなくて困っていた。

image.png

表示上は無効化されているはずなんだけどな・・・

解決策

1.コマンドプロンプトを管理者で実行し、以下を入力

dism.exe /Online /Disable-Feature:Microsoft-Hyper-V

2.再起動&VirtualBoxで起動

ce.png

内部的には、無効化されていなかったみたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(コマンド化)AWS CLIにおけるMFA認証

概要

AWSマネジメントコンソールにアクセスするためのIAMユーザーにMFAを設定している場合、
同ユーザーにてAWS CLIを使う時にもMFAによる認証が必要になるけど、
すぐに忘れちゃうのでコマンド化した。

ざっくりセットアップ手順

  1. アクセスキーの作成(まだやってない人は)
  2. .bashrcに以下追記
  3. ログインし直す or source ~/.bashrc
.bashrc

function AWSCLIINIT() {
    unset AWS_ACCESS_KEY_ID
    unset AWS_SECRET_ACCESS_KEY
    unset AWS_SESSION_TOKEN
    aws configure

    mfa_arn=`aws sts get-caller-identity --query 'Arn' --output text 2>/dev/null | sed -e "s/:user\//:mfa\//g"`
    if [ -n "$mfa_arn" ]
    then
        echo "YourMFA :"$mfa_arn
        echo -n INPUT YourMFA-Code :
        read mfa_code

        get_session_token=`aws sts get-session-token --output text --serial-number $mfa_arn --token-code $mfa_code 2>/dev/null`

        if [ -n "$get_session_token" ]
        then
            set -- $get_session_token
            export AWS_ACCESS_KEY_ID=$2
            export AWS_SECRET_ACCESS_KEY=$4
            export AWS_SESSION_TOKEN=$5
        else
            echo "MFA ERROR"
        fi

    else
        echo "aws configure is wrong"
    fi
}

使い方

AWSCLIINIT

  • 中でaws configureをやってるので必要に応じて入力
  • mfaを聞かれるので入力
$ AWSCLIINIT 
AWS Access Key ID [********************]: 
AWS Secret Access Key [********************]: 
Default region name [ap-northeast-1]: 
Default output format [json]: 
YourMFA :arn:aws:iam::123456789012:mfa/abcdefg
INPUT YourMFA-Code :123456
$

エラーがでなければ認証成功。環境変数にトークンなどがセットされます。

こんな感じ。

MFA認証前

$ aws iam get-user

An error occurred (AccessDenied) when calling the GetUser operation: User: arn:aws:iam::123456789012:user/abcdefg is not authorized to perform: iam:GetUser on resource: user abcdefg with an explicit deny

本コマンド利用時

$ aws iam get-user
{
    "User": {
        "UserName": "abcdefg", 
        "PasswordLastUsed": "2020-01-25T01:16:10Z", 
        "CreateDate": "2019-12-10T02:55:57Z", 
        "UserId": "AAAAAAAAAAAAAAAAAA", 
        "Path": "/", 
        "Arn": "arn:aws:iam::123456789012:user/abcdefg"
    }
}

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Powershellでの作業記録の取り方

作業記録として何を残すか

何らかの作業を行うときに、作業記録を求められることがある。エビデンスや証跡と言われることもあるが、自分が何をやってどうなったかを記録することは大事だ。Powershellで作業する際、以下の二つの記録をとっておこう。

  • コマンドの実行結果の記録
  • コマンドの履歴

コマンドの出力の記録

コマンドを実行したときに出力された内容の記録。Powerehllで出力を記録する方法はいくつかある。

  • リダイレクトで出力する
  • コマンドで出力を記録する
  • コマンドの出力をエクスポートする

この他に、画面に出力された内容を選択してコピペで保存するというのがあるが、説明は省く。

コマンドの履歴

実行したコマンドの履歴。Powershellでコマンドの実行履歴をとる方法

・ historyファイルをコピー
・ Get-History

コマンドの出力を記録するる方法

コマンドの出力をリダイレクトでテキストに保存

実行した内容をそのままテキストに出力するには > (リダイレクト)を使う。オーソドックスな方法。

[コマンド] > [テキストファイル].txt

コマンドの後に > をつけて出力するテキストファイルを指定する。

PS > echo "うに" > test.txt
PS > Get-Content test.txt
うに

リダイレクトされたテキストファイルは上書きされる。もし追記させたければ、>> でリダイレクトする。

PS > echo "うに" >> test.txt

リダイレクトを使用すると、コマンドの実行結果は画面に表示されない。画面にも表示したい場合は、Tee-Objectを使用する。

PS > echo "うに" | Tee-Object test.txt
うに
PS > Get-Content test.txt
うに

画面に出力される内容をファイルに記録する

テキストの記録を開始するときと終了するときに以下のコマンドを実行する。

Start-Transcript → 記録開始
Stop-Transcript → 記録終了

記録開始

> Start-Transcript
トランスクリプトが開始されました。出力ファイル: [カレントパス]\PowerShell_transcript.HORUS.Wm+ZpDyv.[日時].txt

コマンドの実行後、記録が開始される。

記録終了

> Stop-Transcript
トランスクリプトが停止されました。出力ファイル: [カレントパス]\Documents\PowerShell_transcript.HORUS.Wm+ZpDyv.[日時].txt

コマンドの実行後、記録が停止される。保存したテキストファイルのヘッダーには色々な情報が記録されている。出力されたファイルのヘッダーは以下のようになっている。

出力内容

**********************
Windows PowerShell トランスクリプト開始
開始時刻: 20200111180312
ユーザー名: [ユーザ]
RunAs ユーザー: [ユーザ]
構成名: 
コンピューター: [ホスト名] (Microsoft Windows NT 10.0.18362.)
ホスト アプリケーション: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
プロセス ID: 13508
PSVersion: 5.1.18362.145
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.18362.145
BuildVersion: 10.0.18362.145
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************

記録の開始時間、終了時間、ホスト名等の情報が自動で記入される。

コマンドの実行結果をCSVファイルに保存

コマンドの出力を Export-Csv にパイプで渡す。オプションに付けたファイルに出力が保存される。

<コマンド> | Export-Csv <ファイル名>.csv

画面に出力されるアウトプットをCSVにフォーマットするので、表示されていないデータは保存されない。出力されたCSVはExcel等でそのまま読み込むことができる。

コマンドの実行結果をxmlファイルに保存

コマンドの出力を Export-Clixml にパイプで渡す。オプションに付けたファイルに出力が保存される。

<コマンド> | Export-Clixml <ファイル名>.xml

以下のコマンドで出力した xml ファイルをインポートする。

Import-Clixml <ファイル名>.xml

インポートすると、エクスポートされた出力が表示される。出力を変数に入れたり、パイプを通して加工して活用する。

コマンドの実行履歴の保存

実行履歴が記録されているファイル

Powershellでコマンドを実行すると、実行したコマンドが履歴としてテキストファイルに出力されて保存される。保存されるファイルの場所は、以下のコマンドを実行して確かめることができる。

(Get-PSReadLineOption).HistorySavePath

また、以下のコマンドで出力場所の変更もできるようです。

 Set-PSReadLineOption -HistorySavePath [変更先のファイルパス]

ただし、一回プロンプトを閉じると、デフォルトの場所に戻ります。

コマンドで履歴を表示する

Get-historyのコマンドで、コマンドの実行履歴を表示できる。

PS C:\Users\Main> Get-History

  Id CommandLine
  -- -----------
   1 Get-History
   2 Get-History

プロパティをしていすれば、コマンドの実行履歴や実行時間、終了時間のデータも表示できる。

項目 内容
ExecutionStatus コマンドの実行結果
StartExecutionTime コマンドの実行開始時刻
EndExecutionTime コマンドの実行終了時刻

Select-Object * で全てのプロパティを表示すると、これらの情報が表示される。

PS C:\Users\Main> Get-History | Select-Object *


Id                 : 1
CommandLine        : Get-History | Select-Object *
ExecutionStatus    : Completed
StartExecutionTime : 2020/01/16 19:54:41
EndExecutionTime   : 2020/01/16 19:54:41

Id                 : 2
CommandLine        : Get-History | Select-Object *
ExecutionStatus    : Completed
StartExecutionTime : 2020/01/16 19:54:43
EndExecutionTime   : 2020/01/16 19:54:43

Powershellで、コマンドの実行履歴と出力の履歴を組み合わせれば、いつどのようなデータを取得したのかを確実に記録することができる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ultra96-V2 で Linux からパワーオフする方法

はじめに

Ultra96-V2 はZynqMP の I/O ポートからの出力信号がパワーオン/オフLSI の KILL_N入力ポートに接続されています。この信号をLにすれば Ultra96-V2 をパワーオフ状態にすることができます。

しかし、通常の方法で BOOT.BIN と Linux をビルドした場合、この信号を制御することが出来ないようで Linux からパワーオフにすることが出来ません。ちなみにパワーオフにする時は パワーボタンを長押しする必要がありますが、小さいボタンを長押しするのはけっこう指が痛いです(これが動機)。

この記事では BOOT.BIN に含まれる PMUFW(Platform Management Unit Firmware) に手を入れることによって、Linux から Poweroff を実行した時に、この信号を L にして自動的にパワーオフにする方法を示します。

パワーオフのしくみ

パワーオフまわりの回路

Fig.1 に Ultra96-V2 の パワーオフまわりの回路を示します。

Fig.1 Ultra96-V2 の MIO34_POWER_KILL_N 信号

Fig.1 Ultra96-V2 の MIO34_POWER_KILL_N 信号


パワーオン/オフするLSI(SLG4G42480V)の KILL_N ポートは ZynqMP のMIO34 ポートにレベル変換回路を通じて接続されています。ZynqMP の MIO34 ポートからの出力信号はプルアップされていて、電源投入直後から MIO34 のコンフィギュレーションが行われるまでの期間は H に固定されます。

ZynqMP の MIO34 ポートから L を出力することで、パワーオン/オフする LSI の KILL_N 入力ポートが L になって Ultra96-V2 をパワーオフ状態にします。

ZynqMP の MIO34 ポートの設定

Fig.2 に Ultra96-V2 で ZynqMP の MIO34 ポートが Vivado でどのように設定されているかを示します。

Fig.2 Ultra96-V2 の ZynqMP の MIO34 ポートの設定

Fig.2 Ultra96-V2 の ZynqMP の MIO34 ポートの設定


Ultra96-V2 では ZynqMP の MIO34 ポートは PMU(Platform Management Unit) の GPO2 に接続されるように設定されています。

PMU(Platform Management Unit)

PMU(Platform Management Unit) は、プロセッサ間割り込みや電力管理レジスタなどを利用して ZynqMP 内のリソースのパワーアップ、リセット、モニター(監視)を行うためにZynqMP 内に組み込まれたサブシステムです。PMU は、MicroBlaze プロセッサ、32KByte ROM、128KByte RAM で構成されています。ZynqMP の電源投入直後は、まず PMU が起動して ROM 内部のステージ0ブートローダーを実行します。ステージ0ブートローダは、ストレージ(SD-Card等)にある BOOT.BIN に含まれるステージ1ブートローダー(FSBL)を内部RAMにロードして APU (Application Processing Unit) に制御を移します。

PMUFW(Platform Management Unit Firmware)

ステージ1ブートローダー(FSBL)は BOOT.BIN に含まれる PMUFW(Platform Management Unit Firmware) を PMU の RAM にロードします。PMU はその後、 PMUFW に従ってZynqMP 内のリソースのパワーアップ、リセット、モニター(監視)を行います。

Linux でパワーオフをする際、最終的にこの PMUFW のシャットダウン API を呼び出します。

PmProcessRequest()

PMUFW のシャットダウン API は pm_core.c にあります。

pm_core.c
/**
 * PmProcessApiCall() - Called to process PM API call
 * @master  Pointer to a requesting master structure
 * @pload   Pointer to array of integers with the information about the pm call
 *          (api id + arguments of the api)
 *
 * @note    Called to process PM API call. If specific PM API receives less
 *          than 4 arguments, extra arguments are ignored.
 */
void PmProcessRequest(PmMaster *const master, const u32 *pload)
{
    (中略)
    case PM_SYSTEM_SHUTDOWN:
        PmSystemShutdown(master, pload[1], pload[2]);
        break;
    (中略)
}

PmSystemShutdown()

PmSystemShutdown() は pm_core.c にあります。

pm_core.c
/**
 * PmSystemShutdown() - Request system shutdown or restart
 * @master  Master requesting system shutdown
 * @type    Shutdown type
 * @subtype Shutdown subtype
 */
static void PmSystemShutdown(PmMaster* const master, const u32 type,
                 const u32 subtype)
{
    s32 status = XST_SUCCESS;
    PmInfo("%s> SystemShutdown(%lu, %lu)\\r\\n", master->name, type, subtype);
    /* For shutdown type the subtype is irrelevant: shut the caller down */
    if (PMF_SHUTDOWN_TYPE_SHUTDOWN == type) {
        status = PmMasterFsm(master, PM_MASTER_EVENT_FORCE_DOWN);
#if defined(BOARD_SHUTDOWN_PIN) && defined(BOARD_SHUTDOWN_PIN_STATE)
        if (PMF_SHUTDOWN_SUBTYPE_SYSTEM == subtype) {
            PmKillBoardPower();
        }
#endif
        goto done;
    }
    if (PMF_SHUTDOWN_TYPE_RESET != type) {
        status = XST_INVALID_PARAM;
        goto done;
    }
    /* Now distinguish the restart scope depending on the subtype */
    switch (subtype) {
    case PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM:
        status = PmMasterRestart(master);
        break;
    case PMF_SHUTDOWN_SUBTYPE_PS_ONLY:
        XPfw_ResetPsOnly();
        break;
    case PMF_SHUTDOWN_SUBTYPE_SYSTEM:
        XPfw_ResetSystem();
        break;
    default:
        PmLog(PM_ERRNO_INVALID_SUBTYPE, subtype, master->name);
        status = XST_INVALID_PARAM;
        break;
    }
done:
    IPI_RESPONSE1(master->ipiMask, status);
}

ここで注目するのは、BOARD_SHUTDOWN_PIN と BOARD_SHUTDOWN_PIN_STATE が define されている時に実行される PmKillBoardPower() です。

PmKillBoardPower()

PmKillBoardPower() は pm_core.c にあります。

pm_core.c
/**
 * PmKillBoardPower() - Power-off board by sending KILL signal to power chip
 */
#if defined(BOARD_SHUTDOWN_PIN) && defined(BOARD_SHUTDOWN_PIN_STATE)
static void PmKillBoardPower(void)
{
    u32 reg = XPfw_Read32(PMU_LOCAL_GPO1_READ);
    u32 mask = PMU_IOMODULE_GPO1_MIO_0_MASK << BOARD_SHUTDOWN_PIN;
    u32 value = BOARD_SHUTDOWN_PIN_STATE << BOARD_SHUTDOWN_PIN;
    u32 mioPinOffset;
    mioPinOffset = IOU_SLCR_MIO_PIN_34_OFFSET + (BOARD_SHUTDOWN_PIN - 2U)*4U;
    reg = (reg & (~mask)) | (mask & value);
    XPfw_Write32(PMU_IOMODULE_GPO1, reg);
    /* Configure board shutdown pin to be controlled by the PMU */
    XPfw_RMW32((IOU_SLCR_BASE + mioPinOffset),
            0x000000FEU, 0x00000008U);
}
#endif

この PmKillBoardPower() こそが、シャットダウン時に指定された MIO(Ultra96-V2 では MIO34 ポート)を L にしてボードのパワーをオフにする部分です。具体的には GPO レジスタのポートに対応するビット(Ultra96-V2 では GPO2) に指定された値(Ultra96-V2 では 0) をセットした後、指定されたMIO(Ultra96-V2 では MIO34 ポート) を出力モードにしています。

xpfw_config.h

BOARD_SHUTDOWN_PIN と BOARD_SHUTDOWN_PIN_STATE は xpfw_config.h で define されています。

xpfw_config.h
    (前略)
/*
 * PMU Firmware code include options
 *
 * PMU Firmware by default disables some functionality and enables some
 * Here we are listing all the build flags with the default option.
 * User can modify these flags to enable or disable any module/functionality
 *  - ENABLE_PM : Enables Power Management Module
 *  - ENABLE_EM : Enables Error Management Module
 *  - ENABLE_SCHEDULER : Enables the scheduler
 *  - ENABLE_RECOVERY : Enables WDT based restart of APU sub-system
 *  - ENABLE_RECOVERY_RESET_SYSTEM : Enables WDT based restart of system
 *  - ENABLE_RECOVERY_RESET_PS_ONLY : Enables WDT based restart of PS
 *  - ENABLE_ESCALATION : Enables escalation of sub-system restart to
 *                        SRST/PS-only if the first restart attempt fails
 *  - ENABLE_WDT : Enables WDT based restart functionality for PMU
 *  - ENABLE_STL : Enables STL Module
 *  - ENABLE_RTC_TEST : Enables RTC Event Handler Test Module
 *  - ENABLE_IPI_CRC_VAL : Enables CRC calculation for IPI messages
 *  - ENABLE_FPGA_LOAD : Enables FPGA bit stream loading feature
 *  - ENABLE_SECURE : Enables security features
 *  - XPU_INTR_DEBUG_PRINT_ENABLE : Enables debug for XMPU/XPPU functionality
 *
 *  - PM_LOG_LEVEL : Enables print based debug functions for PM. Possible
 *          values are: 1 (alerts), 2 (errors), 3 (warnings),
 *          4 (info). Higher numbers include the debug scope of
 *          lower number, i.e. enabling 3 (warnings) also enables
 *          1 (alerts) and 2 (errors).
 *  - IDLE_PERIPHERALS : Enables idling peripherals before PS or System reset
 *  - ENABLE_NODE_IDLING : Enables idling and reset of nodes before force
 *                         of a sub-system
 *  - DEBUG_MODE : This macro enables PM debug prints if XPFW_DEBUG_DETAILED
 *                 macro is also defined
 *  - ENABLE_POS : Enables Power Off Suspend feature
 *  - ENABLE_DDR_SR_WR : Enables DDR self refresh over warm restart feature
 *  - ENABLE_UNUSED_RPU_PWR_DWN : Enables unused RPU power down feature
 *  - DISABLE_CLK_PERMS : Disable clock permission checking (it is not safe
 *          to ever disable clock permission checking). Do this at
 *          your own responsibility.
 *  - ENABLE_EFUSE_ACCESS : Enables efuse access feature
 *
 *  These macros are specific to ZCU100 design where it uses GPO1[2] as a
 *  board power line and
 *  - PMU_MIO_INPUT_PIN : Enables board shutdown related code for ZCU100
 *  - BOARD_SHUTDOWN_PIN : Tells board shutdown pin. In case of ZCU100,
 *                         GPO1[2] is the board power line.
 *  - BOARD_SHUTDOWN_PIN_STATE : Tells what should be the state of board power
 *                               line when system shutdown request comes
 */

#define ENABLE_PM_VAL                   (1U)
#define ENABLE_EM_VAL                   (0U)
#define ENABLE_SCHEDULER_VAL            (0U)
#define ENABLE_RECOVERY_VAL             (0U)
#define ENABLE_RECOVERY_RESET_SYSTEM_VAL        (0U)
#define ENABLE_RECOVERY_RESET_PS_ONLY_VAL       (0U)
#define ENABLE_ESCALATION_VAL           (0U)
#define CHECK_HEALTHY_BOOT_VAL          (0U)
#define ENABLE_WDT_VAL                  (0U)
#define ENABLE_CUSTOM_MOD_VAL           (0U)
#define ENABLE_STL_VAL                  (0U)
#define ENABLE_RTC_TEST_VAL             (0U)
#define ENABLE_IPI_CRC_VAL              (0U)
#define ENABLE_FPGA_LOAD_VAL            (1U)
#define ENABLE_SECURE_VAL               (1U)
#define ENABLE_EFUSE_ACCESS             (0U)
#define XPU_INTR_DEBUG_PRINT_ENABLE_VAL (0U)
#define PM_LOG_LEVEL_VAL                (0U)
#define IDLE_PERIPHERALS_VAL            (0U)
#define ENABLE_NODE_IDLING_VAL          (0U)
#define DEBUG_MODE_VAL                  (0U)
#define ENABLE_POS_VAL                  (0U)
#define ENABLE_DDR_SR_WR_VAL                (0U)
#define DISABLE_CLK_PERMS_VAL               (0U)
#define ENABLE_UNUSED_RPU_PWR_DWN_VAL           (1U)
#define PMU_MIO_INPUT_PIN_VAL           (0U)
#define BOARD_SHUTDOWN_PIN_VAL       (1U)
#define BOARD_SHUTDOWN_PIN_STATE_VAL (1U)
#define PMU_MIO_INPUT_PIN_VAL           (0U)
#define BOARD_SHUTDOWN_PIN_VAL          (0U)
#define BOARD_SHUTDOWN_PIN_STATE_VAL    (0U)
    :
    (中略)
    :
#if BOARD_SHUTDOWN_PIN_VAL
#define BOARD_SHUTDOWN_PIN          2U
#endif
#if BOARD_SHUTDOWN_PIN_STATE_VAL
#define BOARD_SHUTDOWN_PIN_STATE    0U
#endif
    :
    (後略)

BOARD_SHUTDOWN_PIN は GPO のポート番号です。Ultra96-V2 では2( GPO2) です。

BOARD_SHUTDOWN_PIN_STATE はポートに出力する値です。Ultra96-V2 では 0 (Low) を出力します。

BOOT.BINの修正

PMUFW の修正

PMUFW の構築には Sample FPGA Design のハードウェア情報が必要です。Simple FPGA Design の構築 を参考にして target/Ultra96-V2/build-v2019.1/fpga/project.sdk/design_1_wrapper.hdf を作っておきます。

PMUFW を構築する際に、xpfw_config.h を修正します。具体的には、BOARD_SHUTDOWN_PIN_VAL と BOARD_SHUTDOWN_PIN_STATE_VAL に 1U を設定します。

ビルドする際は次のようなスクリプトを使うと良いでしょう。

target/Ultra96-V2/build-v2019.1/fpga/build_zynqmp_pmufw.hsi
#!/usr/bin/tclsh
set app_name          "pmufw"
set app_type          "zynqmp_pmufw"
set hwspec_file       "design_1_wrapper.hdf"
set proc_name         "psu_pmu_0"
set project_name      "project"
set project_dir       [pwd]
set sdk_workspace     [file join $project_dir $project_name.sdk]
set app_dir           [file join $sdk_workspace $app_name]
set app_release_dir   [file join [pwd] ".." ]
set app_release_elf   "zynqmp_pmufw.elf"
set shutdown_pin      true
set hw_design         [open_hw_design [file join $sdk_workspace $hwspec_file]]
hsi::generate_app -hw $hw_design -os standalone -proc $proc_name -app $app_type -dir $app_dir
if {$shutdown_pin} {
    file copy -force [file join $app_dir "xpfw_config.h"] [file join $app_dir "xpfw_config.h.org"] 
    set xpfw_config_old [open [file join $app_dir "xpfw_config.h.org"]  r]
    set xpfw_config_new [open [file join $app_dir "xpfw_config.h.new"]  w]
    while {[gets $xpfw_config_old line] >= 0} {
        if       {[regexp {^#define\\s+BOARD_SHUTDOWN_PIN_VAL\\s+\\S+}       $line]} {
            puts $xpfw_config_new "#define BOARD_SHUTDOWN_PIN_VAL       (1U)"
        } elseif {[regexp {^#define\\s+BOARD_SHUTDOWN_PIN_STATE_VAL\\s+\\S+} $line]} {
            puts $xpfw_config_new "#define BOARD_SHUTDOWN_PIN_STATE_VAL (1U)"
        } else {
            puts $xpfw_config_new $line
        }
    }
    close $xpfw_config_old
    close $xpfw_config_new
    file rename -force [file join $app_dir "xpfw_config.h.new"] [file join $app_dir "xpfw_config.h"] 
}
exec make -C $app_dir all >&@ stdout
file copy -force [file join $app_dir "executable.elf"] [file join $app_release_dir $app_release_elf]

build_zynqmp_pmufw.hsi を Vivado で実行することにより、target/Ultra96-V2/build-v2019.1/zynqmp_pmufw.elf が生成されます。

vivado% cd target/Ultra96/build-v2019.1/fpga/
vivado% hsi -mode tcl -source build_zynqmp_pmufw.hsi

BOOT.BIN の構築

前節で構築した zynqmp_pmufw.elf を BOOT.BIN に組み込みます。具体的には BOOT.BIN の構築 を参照してください。

余談

psu_init.c の不思議

Simple FPGA Design の構築 で作ったハードウェア情報には、ZynqMP のポートの設定を行うための psu_init.c が含まれます。psu_init.c は ステージ1ブートローダー(FSBL) が ZynqMP のポートを設定するためのプログラムが含まれています。Ultra96-V2 用に作った psu_init.c には不思議な箇所があります。

psu_init.c
    /*
    * Register : MIO_PIN_33 @ 0XFF180084
    * Level 0 Mux Select 0= Level 1 Mux Output 1= gem0, Input, gem0_rgmii_rxd[
    * 0]- (RX RGMII data)
    *  PSU_IOU_SLCR_MIO_PIN_33_L0_SEL                              0
    * Level 1 Mux Select 0= Level 2 Mux Output 1= pcie, Input, pcie_reset_n- (
    * PCIE Reset signal)
    *  PSU_IOU_SLCR_MIO_PIN_33_L1_SEL                              0
    * Level 2 Mux Select 0= Level 3 Mux Output 1= pmu, Output, pmu_gpo[1]- (PM
    * U GPI) 2= test_scan, Input, test_scan_in[33]- (Test Scan Port) = test_sc
    * an, Output, test_scan_out[33]- (Test Scan Port) 3= csu, Input, csu_ext_t
    * amper- (CSU Ext Tamper)
    *  PSU_IOU_SLCR_MIO_PIN_33_L2_SEL                              1
    * Level 3 Mux Select 0= gpio1, Input, gpio_1_pin_in[7]- (GPIO bank 1) 0= g
    * pio1, Output, gpio_1_pin_out[7]- (GPIO bank 1) 1= can1, Input, can1_phy_
    * rx- (Can RX signal) 2= i2c1, Input, i2c1_sda_input- (SDA signal) 2= i2c1
    * , Output, i2c1_sda_out- (SDA signal) 3= swdt1, Output, swdt1_rst_out- (W
    * atch Dog Timer Output clock) 4= spi1, Output, spi1_n_ss_out[2]- (SPI Mas
    * ter Selects) 5= ttc3, Output, ttc3_wave_out- (TTC Waveform Clock) 6= ua1
    * , Input, ua1_rxd- (UART receiver serial input) 7= trace, Output, tracedq
    * [11]- (Trace Port Databus)
    *  PSU_IOU_SLCR_MIO_PIN_33_L3_SEL                              0
    * Configures MIO Pin 33 peripheral interface mapping
    * (OFFSET, MASK, VALUE)      (0XFF180084, 0x000000FEU ,0x00000008U)
    */
    PSU_Mask_Write(IOU_SLCR_MIO_PIN_33_OFFSET, 0x000000FEU, 0x00000008U);
/*##################################################################### */

    /*
    * Register : MIO_PIN_35 @ 0XFF18008C
    * Level 0 Mux Select 0= Level 1 Mux Output 1= gem0, Input, gem0_rgmii_rxd[
    * 2]- (RX RGMII data)
    *  PSU_IOU_SLCR_MIO_PIN_35_L0_SEL                              0
    * Level 1 Mux Select 0= Level 2 Mux Output 1= pcie, Input, pcie_reset_n- (
    * PCIE Reset signal)
    *  PSU_IOU_SLCR_MIO_PIN_35_L1_SEL                              0
    * Level 2 Mux Select 0= Level 3 Mux Output 1= pmu, Output, pmu_gpo[3]- (PM
    * U GPI) 2= test_scan, Input, test_scan_in[35]- (Test Scan Port) = test_sc
    * an, Output, test_scan_out[35]- (Test Scan Port) 3= dpaux, Input, dp_hot_
    * plug_detect- (Dp Aux Hot Plug)
    *  PSU_IOU_SLCR_MIO_PIN_35_L2_SEL                              0
    * Level 3 Mux Select 0= gpio1, Input, gpio_1_pin_in[9]- (GPIO bank 1) 0= g
    * pio1, Output, gpio_1_pin_out[9]- (GPIO bank 1) 1= can0, Output, can0_phy
    * _tx- (Can TX signal) 2= i2c0, Input, i2c0_sda_input- (SDA signal) 2= i2c
    * 0, Output, i2c0_sda_out- (SDA signal) 3= swdt0, Output, swdt0_rst_out- (
    * Watch Dog Timer Output clock) 4= spi1, Input, spi1_n_ss_in- (SPI Master
    * Selects) 4= spi1, Output, spi1_n_ss_out[0]- (SPI Master Selects) 5= ttc2
    * , Output, ttc2_wave_out- (TTC Waveform Clock) 6= ua0, Output, ua0_txd- (
    * UART transmitter serial output) 7= trace, Output, tracedq[13]- (Trace Po
    * rt Databus)
    *  PSU_IOU_SLCR_MIO_PIN_35_L3_SEL                              0
    * Configures MIO Pin 35 peripheral interface mapping
    * (OFFSET, MASK, VALUE)      (0XFF18008C, 0x000000FEU ,0x00000000U)
    */
    PSU_Mask_Write(IOU_SLCR_MIO_PIN_35_OFFSET, 0x000000FEU, 0x00000000U);
/*##################################################################### */

見ての通り、MIO34 ポートの設定がすっぽり抜けています。つまりステージ1ブートローダー(FSBL) では MIO34 ポートの設定は行われません。MIO34 ポートの設定が行われるのは PMUFW(Platform Management Unit Firmware) の PmKillBoardPower() で、MIO34 ポートに L を出力する時です。その時まで、MIO34 ポートはオープン状態にあり、パワーオン/オフするLSI の KILL_N ポートはプルアップされているので H になっています。

これはブートシーケンスを考えてみれば当たり前の話で、ステージ1ブートローダー実行中は、PMUFW はまだ動いていないので、PMU の GPO2 はデフォルトの0になっています。この状態で MIO34 ポートの設定を行うと、MIO34 ポートには PMU の GPO2 に設定された0(=Low) が出力されてしまいます。

つまりステージ1ブートローダー実行中にパワーオフになってしまいます。これを防ぐために psu_init.c では MIO34 ポートの設定は行わないようになっているのでしょう。

パワーオフはMIO34ポートのみ?

前節で説明した psu_init.c の内容やPMUFW のソースコード(特に xpfw_config.h)をみた範囲では、どうも ZynqMP で パワーオフする際の ポートは MIO34 ポートに固定されているようです。

もし ZynqMP を使ったボードを設計する時、パワーオフを ZynqMP から行いたい場合は MIO34 ポートを使うことを念頭に置いておいた方が良いかもしれません。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む