2013年12月27日金曜日

Zynq 事始め1

2013年12月17日火曜日

ISE & Vivado 設定 on Ubuntu

2013年12月16日月曜日

Zynq 入門中

2013年10月29日火曜日

ELCE 2013 & U-Boot Mini Summit in Edinburgh

2013年9月24日火曜日

git の Acked-by と Reviewed-by

2013年9月18日水曜日

Git tips

2013年7月17日水曜日

make が関数を展開するタイミング

2013年6月25日火曜日

VirtualBox 自動起動

Ubuntu 13.04 アップグレード後始末

RAID 上の Ubuntu をアップグレードする

Ubuntu Old Releases

FreeBSD のソースを git-svn で取ってきた

FreeBSD 入門中 その4 : 環境整備2

2013年6月13日木曜日

FreeBSD 入門中 その3 : 環境整備

2013年6月6日木曜日

FreeBSD 入門中 その2: 壊して復旧する

2013年6月4日火曜日

FreeBSD 入門中 その1 : ZFS RootFS にインストール

solarized

パッチを投稿しよう!

オープンソースをダウンロードしてきて、動かしたり、改造したりしているうちに、
バグ修正や、新機能などをコミュニティへフィードバックしたくなってくるかもしれません。

自分は、最近 U-Boot によくパッチを投稿しています。

以下は、U-Boot にパッチを送り始めた時に自分がやった時の一連の流れをまとめておきます。
U-Boot は基本的に、Linux Kernel と同じ開発スタイルを踏襲しているので、それなりに参考になるかと。

ML に参加する


たいていは、パッチはメーリングリストに投稿するようになっていると思います。
なので、まずはメーリングリストを購読します。
やり方は、開発のコミュニティのページに書いてあります。

git send-email を使えるようにする


これについては、前回、git send-email でまとめておきました。

投稿用のパッチを作る


パッチの作り方は、コミュニティのページに説明があると思います。
ログの入れ方とか、いろいろと取り決めがあるので、じっくり読みます。

Linux Kernel を始め、いくつかのコミュニティでは sign-off という制度があります。
sign-off とは、このパッチはオープンソースとして提供しても大丈夫なものですよ、ということを私が証明します、という意味だと、自分なりに理解しています。

自分が一から書いたパッチであれば当然問題はないです。
パッチの中に、別の GPL のコードを含んでいても問題はないです。
一方、GPL とは相容れないライセンスのコードを含んでいたら、NGです。

コミット時に

$ git commit -s

のようにすれば、ログに Signed-off-by: ~ という行が追加されます。

パッチ生成時に

$ git format-patch -s

のようにしてもいいですが、忘れないように commit 時にやっておくのがいいように思います。

パッチ送る


前回 はとりあえず練習で自分宛に送りましたが、いよいよ今度は本物のメーリングリストに送ります。
初めてパッチを送信する時は、結構ドキドキするものです。

毎回送信先のアドレスを聞いてこないように

$ git config sendemail.to mailing-list

の設定をします。プロジェクトごとに送信先が違うはずなので、--global オプションは付けません。そうすると、この設定はリポジトリごとの .git/config に書き込まれます。

git send-email で送ります。

初回の投稿の場合、 Message-ID to be used as In-Reply-To for the first email?
については、そのまま [Return] でよいです。

自分のパッチが受け付けられたことを確認する


送信するのが初めての場合、すぐにメーリングリストに配信されずに

Your message to <...> awaits moderator approval

みたいな返信が来ることがあります。

一瞬、なんじゃこりゃ?みたいに思うかもしれませんが、心配いりません。

たぶん、スパム対策のために、初めて投稿してくる人に対しては、まともな内容かどうか審査があるんだと思います。
問題なければ、数時間後にはメーリングリストに配信されてくると思います。

2回目からは、すぐにメーリングリストに配信されると思います。

パッチのステータス管理に Patchwork http://patchwork.ozlabs.org/ というシステムを使っているプロジェクトもあります。
自分のパッチもステータス New として登録されていることを確認します。

レビューに対し、返答する


自分のパッチに対し、フィードバックしてくれる人があるかもしれません。
これに対しては、 git send-email ではなくて、普段使っているメーラーで、ごく普通に返信します。

修正版のパッチを再投稿する


投稿したパッチがそのまま Accepted になれば万々歳です。
Rejected になれば、基本的にはそこで終わりです。
Changes Requested になった場合は、指摘された部分を修正することで、Accepted になる可能性が高いです。

この場合、元のスレッドに対して修正版のパッチを返信するのではありません。
(Changes Requested になれば、そのスレッドは基本的に終わりです。)

新しいパッチファイルを作り直し、投稿します。

修正をしたら、

$ git commit --amend

でコミットを作り直します。

そして、今度はVersion 2のパッチであることがわかるようにタイトルに入れます。
以下のようにすれば git がやってくれます。

$ git format-patch --subject-prefix="PATCH v2" HEAD^

さらに、前回のパッチからどこが変わったのかをパッチの中に書き込みます。

$ nano 0001-blabla-blablabla


Signed-off-by: ~ の直後に

---

という行があって、この直後にコメントを入れることができます。
これは git のコミットログには反映されません。
例えば、以下のような感じです。

Signed-off-by: Masahiro Yamada <abc@xyz.com>
---

Changes for v2:
   - Fix hogehoge

git send-email で送りますが、今度は
Message-ID to be used as In-Reply-To for the first email?
のところに、前回のバージョンのパッチの Message-ID(前回のメールのヘッダを見れば書いてある)を入力します。
これによって、スレッドで関連付けられます。

2013年6月3日月曜日

git send-email

git には send-email というメールを送信するコマンドがあります。
ただし、普通のメールを送信するのに使うというより、パッチを送る用途に使います。

パッチを自分のメーラーに貼りつけて送信してもいいのですが、
メーラーによっては、長い行を勝手に改行してくれたりして、パッチが破壊される可能性もあります。

リポジトリ管理に git を使っているプロジェクトだと、
git format-pach でパッチ生成 ⇒ git send-email で送信
とするのが手順的にも楽です。
オープンソースの開発にコントリビュートするのに必須ですね。

セットアップについてメモ。

git-core を入れただけでは、 git send-email コマンドはまだ入っていないかもしれません。

Ubuntu の場合は

# apt-get install git-email

でインストールできます。
(他のディストリビューション未確認)


まずは練習のために、自分宛に、何か送ってみましょう。

なんでもいいので、git リポジトリでパッチを生成します。
$ git format-patch HEAD^
0001-blabla-blablabla.patch
今生成したパッチを送信してみます。
$ git send-email 0001-blabla-blablabla.patch
0001-blabla-blablabla.patch
Who should the emails appear to be from? [Masahiro Yamada <abc@xyz.com>]
Emails will be sent from: Masahiro Yamada <abc@xyz.com>
Who should the emails be sent to? abc@xyz.com
Message-ID to be used as In-Reply-To for the first email?
みたいな感じになります。

Who should the emails appear to be from?
というのは、メールの送信元 (From: フィールド) のことです。
基本的にコミットログからとってくれるので、それでよければそのまま [Return] を押します。

Who should the emails be sent to?
は送り先です。
今は練習なので、自分のメールアドレスを入れます。

Message-ID to be used as In-Reply-To for the first email?
は、今から送るメールが、何か別のメールに対する返信であるときに、引用元の Message-ID を入れておくと、メーラーなどがスレッドの分類などに使ってくれます。
今は、新規メールですので、そのまま [Return] でよいです。

最後に

Send this email? ([y]es|[n]o|[q]uit|[a]ll): y

と聞いてきますので、 間違いがないか確認して、 y[Return]
とします。

ローカルで sendmail 系のサービスが動いていれば、これで送信できちゃいます。
自分は postfix を入れています。postfix の設定は以前、git push でメールをとばす で簡単にまとめた。

postfix など入れてないケースが多いでしょうが、その場合は SMTPサーバーを指定しないといけません。

$ git config --global sendemail.smtpserver server_address
で設定します。必要であれば
$ git config --global smtpserverport port_number
でポート番号を設定します。

プロジェクトごとに別の SMTP サーバーを使う必要は普通はないので、--global オプションを付けます。すると、この設定は ~/.gitconfig に書き込まれます。


特に Gmail を使って送信する方法もメモっておきます。
GitTips に書いてありました。

~/.gitconfig/に以下を追加
[sendemail]
        smtpencryption = tls
        smtpserver = smtp.gmail.com
        smtpuser = your_account@gmail.com
        smtpserverport = 587
を追加して、 git send-email を実行すると Password を聞いてくるので、Gmail のパスワードを入力すると送信できる。

この場合の注意点は、git send-email での表示と無関係に、メールの From フィールドを
smtpuser = your_account@gmail.com で指定したアドレスに強制的に置き換えてしまうことです。

2013年5月31日金曜日

vnc で Ubuntu をリモート操作

2013年5月10日金曜日

RAM を一切使わずにプリントデバッグ

Linux Kernel のコードを見ていると、
arch/arm/kernel/debug.S にかなりローレベルなプリントデバッグ用のサブルーチンがありますね。

これをちょっと真似して、より少ない資源で、ARM の起動初期のプリントデバッグができるように改良したものを作ってみました。

printhex2: 2桁の16進数を表示する
printhex4: 4桁の16進数を表示する
printhex8: 8桁の16進数を表示する
printunsigned: unsigned な10進数を表示する
printsigned: signed な10進数を表示する
printascii: 文字列表示
printch: 一文字表示

表示したい数値もしくは文字列を r0 にセットして、上記のマクロを call すれば使えます。

printhex2, printhex4, printhex8, printascii, printch は Linux Kernelにもあるのですが、
Linux Kernel に含まれているバージョンとの違いは
RAM を一切使用せず、破壊するレジスタは r0, r1, r2, r3のみです。
printunsigned と printsigned はオリジナルで作りました。

これら用途としては、ブートのかなり初期で、RAM もまだ使えない状態で、簡単にプリントデバッグしたいときのために作ったものなのです。
(LEDぐらいしか点灯しないとなるとかなりデバッグが苦しいですので。)
私は U-Boot で lowlevel_init 関数とかのデバッグ用途に使っていました。


以下、コードです。

レジスタビューは 16550 を想定してます。
最初に early_serial_initを call する必要があります。
DEBUG_UART_BASE, UART_SHIFT, DIVISOR あたりは自分の環境に合わせて変更して下さい。

---
#define DEBUG_UART_BASE    0xXXXXXXXXX
#define UART_SHIFT 1

/*
 * DIVISER = ((BAUDCLK / 8 / BAUDRATE + 1) / 2)
 */
//#define DIVISOR  40 /* 19200 bps */
//#define DIVISOR  20 /* 38400 bps */
#define DIVISOR  7 /* 115200 bps */

#define UART_TX  0 /* Out: Transmit buffer */

#define UART_LCR 3 /* Out: Line Control Register */
#define UART_LCR_DLAB  0x80 /* Divisor latch access bit */
#define UART_LCR_WLEN8  0x03 /* Wordlength: 8 bits */

#define UART_LSR 5 /* In:  Line Status Register */
#define UART_LSR_TEMT  0x40 /* Transmitter empty */
#define UART_LSR_THRE  0x20 /* Transmit-hold-register empty */

/*
 * DLAB=1
 */
#define UART_DLL 0 /* Out: Divisor Latch Low */
#define UART_DLM 1 /* Out: Divisor Latch High */


/*
 * Call the routine once
 * before calling printhex8/4/2, printascii, printch.
 */
ENTRY(early_serial_init)
  addruart r3
  mov r0, #UART_LCR_DLAB
  strb r0, [r3, #UART_LCR << UART_SHIFT]
  mov r0, #(DIVISOR & 0xff)   @ LSB of divisor
  strb r0, [r3, #UART_DLL << UART_SHIFT]
  mov r0, #((DIVISOR >> 8) & 0xff) @ MSB of divisor
  strb r0, [r3, #UART_DLM << UART_SHIFT]
  mov r0, #UART_LCR_WLEN8
  strb r0, [r3, #UART_LCR << UART_SHIFT]
  mov pc, lr
ENDPROC(early_serial_init)


  .macro addruart, rx
  ldr \rx, =DEBUG_UART_BASE
  .endm

  .macro senduart,rd,rx
  strb \rd, [\rx, #UART_TX << UART_SHIFT]
  .endm

  .macro busyuart,rd,rx
1002:  ldrb \rd, [\rx, #UART_LSR << UART_SHIFT]
  and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
  teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
  bne 1002b
  .endm

/*
 * Useful debugging routines
 *
 * printhex8, printhex4, printhex2:
 *  print a number in 8, 4, 2 digits hexadecimal, respectively.
 *  r0 = number
 *  r1-r3 corrupted
 *
 * printunsigned, printsigned
 *  print a number in decimal.
 *  r0 = number
 *  r1-r3 corrupted
 *
 * printascii
 *  print a string
 *  r0 = pointer to string
 *  r0-r3 corrupted
 *
 * printch
 *  print a character
 *  r0 = character code
 *  r0-r3 corrupted
 */
ENTRY(printhex8)
  mov r2, #28
  b printhex
ENDPROC(printhex8)

ENTRY(printhex4)
  mov r2, #12
  b printhex
ENDPROC(printhex4)

ENTRY(printhex2)
  mov r2, #4
printhex:
  addruart r3
1:  mov r1, r0, lsr r2
  and r1, r1, #15
  cmp r1, #10
  addlt r1, r1, #'0'
  addge r1, r1, #'a' - 10
  senduart r1, r3
  busyuart r1, r3
  subs r2, r2, #4
  bge 1b
  mov pc, lr
ENDPROC(printhex2)

ENTRY(printunsigned)
  mov r1, #1
  mov r2, #0
1:  mov r1, r1, lsl #1  @ r1 = 2 * r1
  add r1, r1, r1, lsl #2 @ r1 = 5 * r1
  add r2, r2, #1
  cmp r2, #10   @ prevent overflow of r1
  bge 2f
  cmp r1, r0
  bls 1b
2:  mov r3, r2   @ number of digits
3:  mov r1, #1
  mov r2, #0
4:  add r2, r2, #1
  cmp r2, r3
  movlt r1, r1, lsl #1  @ r1 = 2 * r1
  addlt r1, r1, r1, lsl #2 @ r1 = 5 * r1
  blt 4b
  mov r2, #0
5:  cmp r1, r0
  subls r0, r0, r1
  addls r2, r2, #1
  blo 5b
  add r2, r2, #'0'
  addruart r1
  senduart r2, r1
  busyuart r2, r1
  subs r3, r3, #1
  bgt 3b
  mov pc, lr
ENDPROC(printunsigned)

ENTRY(printsigned)
  cmp r0, #0
  bge printunsigned  @ signed greater or equal
  addruart r3
  mov r1, #'-'
  senduart r1, r3
  busyuart r1, r3
  rsb r0, r0, #0  @ r0 = 0 - r0
  b printunsigned
ENDPROC(printsigned)

ENTRY(printascii)
  addruart r3
  b 2f
1:  senduart r1, r3
  busyuart r2, r3
  teq r1, #'\n'
  moveq r1, #'\r'
  beq 1b
2:  teq r0, #0
  ldrneb r1, [r0], #1
  teqne r1, #0
  bne 1b
  mov pc, lr
ENDPROC(printascii)

ENTRY(printch)
  addruart r3
  mov r1, r0
  mov r0, #0
  b 1b
ENDPROC(printch)

2013年5月6日月曜日

バイナリファイルを逆アセンブル

2013年4月29日月曜日

アドレスサイズプレフィックス、オペランドサイズプレフィックス

GNU assemblerの話。
.code16, .code32, .code64でそれぞれ 16bit, 32bit, 64bit モードでアセンブルしてくれるようです。

まず、レジスタの名前ですが、ビット長ごとに以下の通り。
16bit  32bit  64bit
%ax    %eax   %rax
%bx    %ebx   %rbx
%cx    %ecx   %rcx
%dx    %edx   %rdx
%si    %esi   %rsi
%di    %edi   %rdi



例えば、以下のような test.s というファイルを作る。


.file "test.s"
.text

.code16

main16:
mov (%si), %ax
mov (%si), %eax
mov (%esi), %ax
mov (%esi), %eax

.code32

main32:
mov (%si), %ax
mov (%si), %eax
mov (%esi), %ax
mov (%esi), %eax

.code64

main64:
// mov (%si), %ax
// mov (%si), %eax
// mov (%si), %rax
mov (%esi), %ax
mov (%esi), %eax
mov (%esi), %rax
mov (%rsi), %ax
mov (%rsi), %eax
mov (%rsi), %rax


リストファイルを出してみる。
$ gcc -Wa,-a=test.lst -c -o test.o test.s
$ cat test.lst
GAS LISTING test.s page 1


   1               .file "test.s"
   2               .text
   3              
   4               .code16
   5               main16:
   6 0000 8B04     mov (%si), %ax
   7 0002 668B04   mov (%si), %eax
   8 0005 678B06   mov (%esi), %ax
   9 0008 67668B06 mov (%esi), %eax
  10              
  11               .code32
  12               main32:
  13 000c 67668B04 mov (%si), %ax
  14 0010 678B04   mov (%si), %eax
  15 0013 668B06   mov (%esi), %ax
  16 0016 8B06     mov (%esi), %eax
  17              
  18               .code64
  19               main64:
  20               // mov (%si), %ax
  21               // mov (%si), %eax
  22               // mov (%si), %rax
  23 0018 67668B06 mov (%esi), %ax
  24 001c 678B06   mov (%esi), %eax
  25 001f 67488B06 mov (%esi), %rax
  26 0023 668B06   mov (%rsi), %ax
  27 0026 8B06     mov (%rsi), %eax
  28 0028 488B06   mov (%rsi), %rax
  29              
GAS LISTING test.s page 2


DEFINED SYMBOLS
                            *ABS*:0000000000000000 test.s
              test.s:5      .text:0000000000000000 main16
              test.s:12     .text:000000000000000c main32
              test.s:19     .text:0000000000000018 main64

NO UNDEFINED SYMBOLS


ここで気が付くのは、同じ命令でも、違うコードが出ている。
例えば、
mov (%esi), %eax
16bitでは、67668B06
32bitでは、8B06
64bitでは、678B06
となっている。

67というのは、アドレスサイズプレフィックス
66というのは、オペランドサイズプレフィックス

これを見ると、各モードで、最も命令コードが短くなるアドレスサイズ、オペランドサイズが決まっているように見える。

16bitモードでは、アドレスサイズ、オペランドサイズが16bitが基本。
67を付けるとアドレスサイズが32bitになる。
66を付けるとオペランドサイズが32bitになる。

32bitモードでは、アドレスサイズ、オペランドサイズが32bitが基本。
67を付けるとアドレスサイズが16bitになる。
66を付けるとオペランドサイズが16bitになる。

64bitモードでは、アドレスサイズ64bit、オペランドサイズ32bitが基本。
67を付けるとアドレスサイズが16bitになる。
66を付けるとオペランドサイズが16bitになる。
48を付けるとオペランドサイズが64bitになる。

以下の表はアドレスサイズとオペランドサイズのbit幅に対し、どのようなプレフィックスを付ければいいのかを表している。


                  Mode
Addr Data   16bit 32bit 64bit
16   16      なし  6766   不可
16   32      66    67    不可
16   64      不可   不可   不可
32   16      67    66   6766
32   32     6766   なし   67
32   64      不可   不可  6748
64   16      不可   不可   66
64   32      不可   不可   なし
64   64      不可   不可   48

2013年3月24日日曜日

ハンダ用の排気ダクトを自作する

ハンダ付けを長時間やったりすると、ヤニで頭が痛くなることがありますよね。

そこで、低予算で排気ダクトを作ってみました。

材料は、コーナンで売ってるものと、ありあわせのもので作ってみました。


<<材料>>

(1) アルミダクトホース (Φ100 x 3000mm)
コーナンProで購入。698円。



(2) クーラーキャップ
コーナンProで購入。248円。



(3) アルミテープ
コーナンProで購入。598円。




(4)CPUファン
余っているものを流用。
Scythe製の NINJA3 というCPUクーラーについてた FANが余っていたので、それを使います。




(5)ACアダプタ (12V)
余っているものを流用。




(6) DCジャック
電子工作用に、秋月で買い置きしておいたものですが、流用できそうです。
秋月で100円で売っています。







<<作り方>>

ダクトホースにキャップをはめ、空気が漏れないように、しっかりとアルミテープでとめます。
キャップは必須ではないのですが、アルミダクトホースは端の部分で手を切りやすいので、安全のために、キャップを取り付けておいた方がよいです。





その上に、CPUファンを取り付けて、アルミテープでとめます。




DCジャックからピンヘッダに変換して、CPUファンへ給電しています。





完成したところ。
写真ではわかりにくいのですが、煙を勢い良く吸い込んでくれています。
NINJA3 付属のファンはボリューム付きなのが良いですね。



問題は、ダクトのもう一端をどうやって室外に出すかですが、
横から窓、上からシャッターで挟んで、外に出しています。
若干のすきま風はあります。
エアコンを入れられないので、夏と冬はつらいかも。。




奥さんに「またガラクタ増やして〜」と怒られるかと思ったら、意外にも「すごい〜」と言ってくれました。

これで快適に電子工作できますね。