/home/tnishinaga/TechMEMO

日々行ったこと、面白かったことを書き留めます。

Failed to find path for dmidecode binaryと言ってlibvirtが起動しなくなった件

問題

いつの間にかlibvirtを使っていた仮想マシンが起動も設定もできなくなっていた.

以下のコマンドでlibvirtを再起動しても,長時間待たされた後にタイムアウトする.

$ sudo systemctl restart libvirtd.service

journalctlでログを見てみると,dmidecodeが見つからないと言われる.

$ journalctl -xe

libvirtd[2847]: internal error: Failed to find path for dmidecode binary

ぐぐってみると以下の記事が引っかかるが,ebtablesが見つからないとは言われていない.

kernhack.hatenablog.com

直し方

調べてみると,dmidecodeはハードウェアの情報を得るためのコマンドらしい.

linux.die.net

HWの情報を取得できるdmidecodeコマンドが結構便利だと思った - 完熟トマト

このパッケージをpacmanで検索してみるとインストールされてなかったので,インストールするとエラーが出なくなった.

$ sudo pacman -S dmidecode

この後システムを再起動したところ,libvirtを使った仮想マシンが起動できるようになった.

めでたしめでたし.

ArchLinuxのアップデートで署名エラーが出た場合についてメモ

本日1週間ぶりくらいに pacman -Syu したところ,以下のエラーが出ました.

error: confuse: signature from "Thorsten Töpper <atsutane@freethoughts.de>" is unknown trust

調べてみると以下の記事がヒット.

[Solved] confuse 2.7-3 install error: mainatainer gpg key is unknown / Newbie Corner / Arch Linux Forums

どうやら最初に鍵の更新をすると良いようです.

$ sudo pacman -S archlinux-keyring

後は普通にアップデートできるはずです.

以上.

黒柴(KURO-SHEEVA)にdebian jessieを入れる

tnishinaga.hatenablog.com

この記事の続きです.

前回はLinuxカーネルをビルドして動かしてみるところまでやりました. 今回はdebianのイメージを作って動かしてみたいと思います.

debootstrapでdebian環境を作る

debootstrapはdebianの基本システムを簡単に作れる公式ツールです. Arch Linuxではyaourtで導入できます.

$ yaourt debootstrap

また,debootstrapを完了するためにはbinfmtとqemu user modeのstaticバイナリが必要です.以下のコマンドで導入及び有効化してください. binfmtやqemu user modeについての解説は,ググるか,C89で僕のスタンドが同人誌の中でほんの少し解説するようなので,興味のある方は「3日目東ム36-a 迷惑研」にいらしてください.

$ yaourt -S binfmt-support binfmt-qemu-static
$ sudo update-binfmts --enable qemu-arm
$ yaourt -S qemu-user-static

debootstrapを用いてarmel用のdebian jessie環境を作るには,以下のコマンドを実行します. なお,後の作業で必要なため,debootstrapは前回linuxカーネルのソースをおいたところで実行してください.

$ cd 
$ mkdir -p debian-jessie-armel/usr/bin
$ cp /usr/bin/qemu-arm-static debian-jessie-armel/usr/bin/
$ sudo debootstrap --arch armel jessie debian-jessie-armel http://ftp.jp.debian.org/debian

次にchrootでこのdebian環境に入り,初期設定としてrootのパスワードだけ設定します.

$ LC_ALL=C LANGUAGE=C LANG=C sudo chroot debian-jessie-armel /bin/bash
# export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
# passwd
# exit
$ cd ~/

Linux Kernelからモジュールとかヘッダを入れる

前回ビルドしたlinuxカーネルのうち,モジュールとヘッダファイルをこのdebian環境に入れます.

$ cd linux
$ make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- modules
$ sudo make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- INSTALL_MOD_PATH=~/debian-jessie-armel modules_install
$ sudo make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- INSTALL_HDR_PATH=~/debian-jessie-armel/usr headers_install
$ cd ~/

SDカードにDebian環境をインストールする

前回作成したLinuxカーネルと今回作ったDebian環境をSDカードに入れていきます. なお,私の持っている黒柴のU-BootはSDカードの第2パーティションをrootfsとして起動するようになっていたので,第1パーティションカーネル,第2パーティションにrootfsを置くような構成にします.

fdisk等を用いて,第1パーティションを64MBのfat,残りをext4パーティションとしてパーティション分けを行ってください. そして次のコマンドでフォーマットを行います.

$ sudo mkfs.vfat /dev/sdX1 (Xは各自環境に合わせる)
$ sudo mkfs.ext4 /dev/sdX2

フォーマットが終わったら,第1パーティションを/mnt/fat,第2パーティションを/mnt/ext4にマウントします.

$ sudo mkdir -p /mnt/fat
$ sudo mkdir -p /mnt/ext4
$ mount -t vfat /dev/sdX1 /mnt/fat
$ mount -t ext4 /dev/sdX2 /mnt/ext4

後はカーネルdebian環境をSDカードに入れ,アンマウントします.

$ sudo cp uImage+dtb /mnt/fat/
$ sudo rsync -avh debian-jessie-armel/ /mnt/ext4/
$ sudo umount /mnt/fat
$ sudo umount /mnt/ext4 

以上でインストールは完了です.

起動してみる

最後に,黒柴にSDカードを刺した後,前回と同様の方法で起動してみます.

Marvell>> mmcinit
Marvell>> fatload mmc 0:1 0x02000000 uimage+dtb
Marvell>> bootm

正しく動作すれば,debianのログインプロンプトが出てくるはずです. 以下に動作時のログを乗せておきます.

Marvell>> mmcinit
SDHC found. Card desciption is:
Manufacturer:       0x74, OEM "JE"
Product name:       "USD  ", revision 1.0
Serial number:      1280314594
Manufacturing date: 1/2012
CRC:                0x00, b0 = 0
Marvell>> fatload mmc 0:1 0x02000000 uimage+dtb
reading uimage+dtb

4298473 bytes read
Marvell>> bootm
## Booting image at 02000000 ...
   Image Name:   Linux-sheeva-esata
   Created:      2015-12-25   5:13:54 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4298409 Bytes =  4.1 MB
   Load Address: 02000000
   Entry Point:  02000040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.3.0 (tnishinaga@arch-tx201) (gcc version 5.2.0 (crosstool-NG crosstool-ng-1.22.0) ) #6 PREEMPT Fri Dec 25 14:07:55 JST 2015
CPU: Feroceon 88FR131 [56251311] revision 1 (ARMv5TE), cr=0005397f
CPU: VIVT data cache, VIVT instruction cache
Machine model: Globalscale Technologies eSATA SheevaPlug
Memory policy: Data cache writeback
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
Kernel command line: console=ttyS0,115200 root=/dev/mmcblk0p2 rw
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 510664K/524288K available (6261K kernel code, 214K rwdata, 1680K rodata, 176K init, 666K bss, 13624K reserved, 0K cma-reserved, 0K highmem)
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
    vmalloc : 0xe0800000 - 0xff000000   ( 488 MB)
    lowmem  : 0xc0000000 - 0xe0000000   ( 512 MB)
    pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
    modules : 0xbf000000 - 0xbfe00000   (  14 MB)
      .text : 0xc0008000 - 0xc07c9984   (7943 kB)
      .init : 0xc07ca000 - 0xc07f6000   ( 176 kB)
      .data : 0xc07f6000 - 0xc082b9c0   ( 215 kB)
       .bss : 0xc082b9c0 - 0xc08d24a0   ( 667 kB)
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Preemptible hierarchical RCU implementation.
    Build-time adjustment of leaf fanout to 32.
NR_IRQS:16 nr_irqs:16 16
clocksource: orion_clocksource: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 9556302233 ns
sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 10737418237ns
Console: colour dummy device 80x30
Calibrating delay loop... 1191.11 BogoMIPS (lpj=5955584)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x81e0 - 0x8238
mvebu-soc-id: MVEBU SoC ID=0x6281, Rev=0x2
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
xor: measuring software checksum speed
   arm4regs  :  1084.400 MB/sec
   8regs     :   804.000 MB/sec
   32regs    :   970.800 MB/sec
xor: using function: arm4regs (1084.400 MB/sec)
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
cpuidle: using governor ladder
cpuidle: using governor menu
Feroceon L2: Enabling L2
Feroceon L2: Cache support initialised.
[Firmware Info]: /ocp@f1000000/ethernet-controller@72000/ethernet0-port@0: local-mac-address is not set
raid6: int32x1  gen()   115 MB/s
raid6: int32x1  xor()    76 MB/s
raid6: int32x2  gen()   167 MB/s
raid6: int32x2  xor()   103 MB/s
raid6: int32x4  gen()   185 MB/s
raid6: int32x4  xor()   119 MB/s
raid6: int32x8  gen()   187 MB/s
raid6: int32x8  xor()   116 MB/s
raid6: using algorithm int32x8 gen() 187 MB/s
raid6: .... xor() 116 MB/s, rmw enabled
raid6: using intx1 recovery algorithm
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Advanced Linux Sound Architecture Driver Initialized.
clocksource: Switched to clocksource orion_clocksource
NET: Registered protocol family 2
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
futex hash table entries: 256 (order: -1, 3072 bytes)
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
kirkwood-pinctrl f1010000.pin-controller: registered pinctrl driver
irq: Cannot allocate irq_descs @ IRQ34, assuming pre-allocated
irq: Cannot allocate irq_descs @ IRQ66, assuming pre-allocated
mv_xor f1060800.xor: Marvell shared XOR driver
mv_xor f1060800.xor: Marvell XOR (Registers Mode): ( xor cpy intr )
mv_xor f1060900.xor: Marvell shared XOR driver
mv_xor f1060900.xor: Marvell XOR (Registers Mode): ( xor cpy intr )
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
console [ttyS0] disabled
f1012000.serial: ttyS0 at MMIO 0xf1012000 (irq = 26, base_baud = 12500000) is a 16550A
console [ttyS0] enabled
loop: module loaded
sata_mv f1080000.sata: slots 32 ports 2
scsi host0: sata_mv
scsi host1: sata_mv
ata1: SATA max UDMA/133 irq 32
ata2: SATA max UDMA/133 irq 32
nand: device found, Manufacturer ID: 0xec, Chip ID: 0xdc
nand: Samsung NAND 512MiB 3,3V 8-bit
nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
Scanning device for bad blocks
Bad eraseblock 2909 at 0x000016ba0000
Bad eraseblock 3657 at 0x00001c920000
3 ofpart partitions found on MTD device orion_nand
Creating 3 MTD partitions on "orion_nand":
0x000000000000-0x000000100000 : "u-boot"
0x000000100000-0x000000500000 : "uImage"
0x000000500000-0x000020000000 : "root"
libphy: orion_mdio_bus: probed
mv643xx_eth: MV-643xx 10/100/1000 ethernet driver version 1.4
mv643xx_eth_port mv643xx_eth_port.0 eth0: port 0 with MAC address f0:ad:4e:00:5c:d9
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ehci-orion: EHCI orion driver
orion-ehci f1050000.ehci: EHCI Host Controller
orion-ehci f1050000.ehci: new USB bus registered, assigned bus number 1
ata1: SATA link down (SStatus 0 SControl F300)
orion-ehci f1050000.ehci: irq 29, io mem 0xf1050000
orion-ehci f1050000.ehci: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
usbcore: registered new interface driver usb-storage
usbcore: registered new interface driver ums-datafab
usbcore: registered new interface driver ums-freecom
usbcore: registered new interface driver ums-jumpshot
usbcore: registered new interface driver ums-sddr09
usbcore: registered new interface driver ums-sddr55
mousedev: PS/2 mouse device common for all mice
rtc-mv f1010300.rtc: rtc core: registered f1010300.rtc as rtc0
i2c /dev entries driver
orion_wdt: Initial timeout 21 sec
mvsdio f1090000.mvsdio: Got CD GPIO
mvsdio f1090000.mvsdio: Got WP GPIO
MV-CESA:Could not register sha1 driver
MV-CESA:Could not register hmac-sha1 driver
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
oprofile: no performance counters
oprofile: using timer interrupt.
NET: Registered protocol family 17
lib80211: common routines for IEEE802.11 drivers
Btrfs loaded
mmc0: new high speed SDHC card at address b368
rtc-mv f1010300.rtc: setting system clock to 2013-01-01 11:42:16 UTC (1357040536)
mmcblk0: mmc0:b368 USD   3.75 GiB 
 mmcblk0: p1 p2
ALSA device list:
  No soundcards found.
ata2: SATA link down (SStatus 0 SControl F300)
EXT2-fs (mmcblk0p2): error: couldn't mount because of unsupported optional features (240)
EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext4 filesystem) on device 179:2.
devtmpfs: mounted
Freeing unused kernel memory: 176K (c07ca000 - c07f6000)
random: systemd urandom read with 7 bits of entropy available
systemd[1]: systemd 215 running in system mode. (+PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR)
systemd[1]: Detected architecture 'arm'.

Welcome to Debian GNU/Linux 8 (jessie)!

systemd[1]: Failed to insert module 'autofs4'
systemd[1]: Failed to insert module 'ipv6'
systemd[1]: Set hostname to <arch-tx201>.
systemd[1]: Cannot add dependency job for unit dbus.socket, ignoring: Unit dbus.socket failed to load: No such file or directory.
systemd[1]: Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory.
systemd[1]: Expecting device dev-ttyS0.device...
         Expecting device dev-ttyS0.device...
systemd[1]: Starting Forward Password Requests to Wall Directory Watch.
systemd[1]: Started Forward Password Requests to Wall Directory Watch.
systemd[1]: Starting Remote File Systems (Pre).
[  OK  ] Reached target Remote File Systems (Pre).
systemd[1]: Reached target Remote File Systems (Pre).
systemd[1]: Starting Encrypted Volumes.
[  OK  ] Reached target Encrypted Volumes.
systemd[1]: Reached target Encrypted Volumes.
systemd[1]: Starting Dispatch Password Requests to Console Directory Watch.
systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
systemd[1]: Starting Paths.
[  OK  ] Reached target Paths.
systemd[1]: Reached target Paths.
systemd[1]: Set up automount Arbitrary Executable File Formats File System Automount Point.
systemd[1]: Starting Swap.
[  OK  ] Reached target Swap.
systemd[1]: Reached target Swap.
systemd[1]: Starting Root Slice.
[  OK  ] Created slice Root Slice.
systemd[1]: Created slice Root Slice.
systemd[1]: Starting User and Session Slice.
[  OK  ] Created slice User and Session Slice.
systemd[1]: Created slice User and Session Slice.
systemd[1]: Starting Delayed Shutdown Socket.
[  OK  ] Listening on Delayed Shutdown Socket.
systemd[1]: Listening on Delayed Shutdown Socket.
systemd[1]: Starting /dev/initctl Compatibility Named Pipe.
[  OK  ] Listening on /dev/initctl Compatibility Named Pipe.
systemd[1]: Listening on /dev/initctl Compatibility Named Pipe.
systemd[1]: Starting Journal Socket (/dev/log).
[  OK  ] Listening on Journal Socket (/dev/log).
systemd[1]: Listening on Journal Socket (/dev/log).
systemd[1]: Starting udev Control Socket.
[  OK  ] Listening on udev Control Socket.
systemd[1]: Listening on udev Control Socket.
systemd[1]: Starting udev Kernel Socket.
[  OK  ] Listening on udev Kernel Socket.
systemd[1]: Listening on udev Kernel Socket.
systemd[1]: Starting Journal Socket.
[  OK  ] Listening on Journal Socket.
systemd[1]: Listening on Journal Socket.
systemd[1]: Starting System Slice.
[  OK  ] Created slice System Slice.
systemd[1]: Created slice System Slice.
systemd[1]: Starting system-getty.slice.
[  OK  ] Created slice system-getty.slice.
systemd[1]: Created slice system-getty.slice.
systemd[1]: Starting system-serial\x2dgetty.slice.
[  OK  ] Created slice system-serial\x2dgetty.slice.
systemd[1]: Created slice system-serial\x2dgetty.slice.
systemd[1]: Starting Increase datagram queue length...
         Starting Increase datagram queue length...
systemd[1]: Starting Load Kernel Modules...
         Starting Load Kernel Modules...
systemd[1]: Starting udev Coldplug all Devices...
         Starting udev Coldplug all Devices...
systemd[1]: Mounting Debug File System...
         Mounting Debug File System...
systemd[1]: Starting Create list of required static device nodes for the current kernel...
         Starting Create list of required static device nodes...rrent kernel...
systemd[1]: Mounted POSIX Message Queue File System.
systemd[1]: Started Set Up Additional Binary Formats.
systemd[1]: Mounted Huge Pages File System.
systemd[1]: Starting Slices.
[  OK  ] Reached target Slices.
systemd[1]: Reached target Slices.
systemd[1]: Starting Remount Root and Kernel File Systems...
         Starting Remount Root and Kernel File Systems...
[  OK  ] Mounted Debug File System.
systemd[1]: Mounted Debug File System.
[  OK  ] Started Increase datagram queue length.
systemd[1]: Started Increase datagram queue length.
[  OK  ] Started Load Kernel Modules.
systemd[1]: Started Load Kernel Modules.
[  OK  ] Started Create list of required static device nodes ...current kernel.
systemd[1]: Started Create list of required static device nodes for the current kernel.
[  OK  ] Started Remount Root and Kernel File Systems.
systemd[1]: Started Remount Root and Kernel File Systems.
[  OK  ] Started udev Coldplug all Devices.
systemd[1]: Started udev Coldplug all Devices.
systemd[1]: Starting Various fixups to make systemd work better on Debian...
         Starting Various fixups to make systemd work better on Debian...
systemd[1]: Starting Load/Save Random Seed...
         Starting Load/Save Random Seed...
systemd[1]: Starting Create Static Device Nodes in /dev...
         Starting Create Static Device Nodes in /dev...
systemd[1]: Mounted Configuration File System.
systemd[1]: Mounted FUSE Control File System.
systemd[1]: Starting Apply Kernel Variables...
         Starting Apply Kernel Variables...
systemd[1]: Starting Syslog Socket.
[  OK  ] Listening on Syslog Socket.
systemd[1]: Listening on Syslog Socket.
systemd[1]: Starting Sockets.
[  OK  ] Reached target Sockets.
systemd[1]: Reached target Sockets.
systemd[1]: Starting Journal Service...
         Starting Journal Service...
[  OK  ] Started Journal Service.
systemd[1]: Started Journal Service.
[  OK  ] Started Various fixups to make systemd work better on Debian.
[  OK  ] Started Load/Save Random Seed.
[  OK  ] Started Create Static Device Nodes in /dev.
[  OK  ] Started Apply Kernel Variables.
         Starting udev Kernel Device Manager...
[  OK  ] Reached target Local File Systems (Pre).
[  OK  ] Reached target Local File Systems.
systemd-udevd[1159]: starting version 215
         Starting Create Volatile Files and Directories...
[  OK  ] Reached target Remote File Systems.
         Starting Trigger Flushing of Journal to Persistent Storage...
         Starting LSB: Raise network interfaces....
[  OK  ] Started udev Kernel Device Manager.
[  OK  ] Started Create Volatile Files and Directories.
         Starting Update UTMP about System Boot/Shutdown...
         Starting Copy rules generated while the root was ro...
[  OK  ] Started Copy rules generated while the root was ro.
systemd-journald[1157]: Received request to flush runtime journal from PID 1
[  OK  ] Started Trigger Flushing of Journal to Persistent Storage.
[  OK  ] Started Update UTMP about System Boot/Shutdown.
[  OK  ] Found device /dev/ttyS0.
[  OK  ] Started LSB: Raise network interfaces..
[  OK  ] Reached target Network.
[  OK  ] Reached target System Initialization.
[  OK  ] Reached target Timers.
[  OK  ] Reached target Basic System.
         Starting Regular background program processing daemon...
[  OK  ] Started Regular background program processing daemon.
         Starting /etc/rc.local Compatibility...
         Starting getty on tty2-tty6 if dbus and logind are not available...
         Starting System Logging Service...
         Starting Permit User Sessions...
[  OK  ] Started /etc/rc.local Compatibility.
[  OK  ] Started Permit User Sessions.
[  OK  ] Started System Logging Service.
         Starting Getty on tty2...
[  OK  ] Started Getty on tty2.
         Starting Getty on tty1...
[  OK  ] Started Getty on tty1.
         Starting Serial Getty on ttyS0...
[  OK  ] Started Serial Getty on ttyS0.
[  OK  ] Started getty on tty2-tty6 if dbus and logind are not available.
         Starting Getty on tty6...
[  OK  ] Started Getty on tty6.
         Starting Getty on tty5...
[  OK  ] Started Getty on tty5.
         Starting Getty on tty4...
[  OK  ] Started Getty on tty4.
         Starting Getty on tty3...
[  OK  ] Started Getty on tty3.
[  OK  ] Reached target Login Prompts.
[  OK  ] Reached target Multi-User System.
[  OK  ] Reached target Graphical Interface.
         Starting Update UTMP about System Runlevel Changes...
[  OK  ] Started Update UTMP about System Runlevel Changes.

Debian GNU/Linux 8 arch-tx201 ttyS0

arch-tx201 login:

実は,Linuxカーネルを1からビルドして,rootfsも用意して正しく動いたのが初めてなので,すごく嬉しいです. やたー!

黒柴(KURO-SHEEVA)用にLinux Kernel 4.3をビルドする

先日,セキュリティミニキャンプ沖縄2015にチューターとして参加させていただきました. そこでお手伝いしながら木藤さんの講義「組込みシステム解体新書(入門編)」を聞いていたところ,組み込み機器をいじりたい欲がむくむくと湧き出してきたので,以前とあるお方から頂いた黒柴(KURO-SHEEVA)に最新のLinuxカーネルDebian jessieを入れてみることにしました.

本日はKernelをビルドして起動するまでできたので,それまでの方法を記します.

なお,以降の作業はArch Linux(x86_64)環境上で行いました. arm環境用のクロスコンパイル環境は用意されているものとします. ない方はcrosstool-ngなどで作ってください.

黒柴(KURO-SHEEVA)

黒柴は,2010年頃に玄人志向から発売されたSheeva-Plugをベースとしたプラグコンピューターです. 電源プラグにつなぐだけで使える小型省電力サーバーとして,当時プラグコンピューターが(私の観測では)けっこう流行りました. 今でいうところのRaspberry Piのようなものです.

SoCはMarvell社のKirkwood SoCプロセッサ「88F6281」 ARMv5te 1.2GHzとなっています. 周辺機器はGigabitEther,USB2.0ポート,SDカードスロット,eSATAポート,コンソール&JTAG用USB type miniB がひとつずつついています.

Linux Kernelをビルドする

基本は,黒柴の元となったSheeva-Plug用のLinux Kernelビルド方法を参考に進めます. ただし,この記事はLinux 2.6頃の話をしているので,最近のLinuxに合わせてちょこっといじる必要があります.

Building and installing a new kernel for a SheevaPlug

最初にlinux KernelのSourceをとってきます. バージョンは4.3を使いました.

$ cd ~/
$ git clone --depth 1 https://github.com/torvalds/linux
$ cd linux
$ git checkout -b v4.3 refs/tags/v4.3

次にKirkwood用のconfigをロードします. 昔はkirkwood_defconfigという名前であったようですが,現在はmvebuに統合されたようです.

$ make ARCH=arm mvebu_v5_defconfig

最近のsystemdな環境ではCONFIG_CGROUPSを有効にする必要があるので,menuconfigで設定をいじります.

$ make ARCH=arm menuconfig

General setup ---> Control Group support を選択して設定してください.

後はカーネルをビルドします. CROSS_COMPILEのところは各自環境に合わせて修正してください.

$ make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- zImage dtbs

zImageをuImageにする

正確なバージョンは忘れましたが,現在のLinuxカーネルでは個々の組み込みボードのハードウエア構成等をDevice Treeで設定するようになりました. そのため,Kernelの起動時には,Device Treeを記述したソースをビルドしてできるDevice Tree Blob(以下 dtb)をKernelに渡す必要があります.

U-Bootが対応している場合はKernelとdtbを適当にメモリにおいて起動できるようですが,黒柴に入ってるU-Bootは古いのでできるかわかりません. 以下の資料を参照すると,zImageのケツにdtbをくっつけてuImageに変換し,U-Bootに食わせることもできるようなので,それを試します.

http://tokyodebian.alioth.debian.org/pdf/debianmeetingresume201307-presentation-iwamatsu.pdf

私の黒柴のU-Bootはbootmすると0x02000000からuImageを読みだすようなので,ロードアドレスに0x02000000,エントリポイントにはuImageのヘッダ分ずらした0x02000040を設定します.

$ cd ~/
$ cp linux/arch/arm/boot/zImage linux/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dtb ./
$ cat zImage kirkwood-sheevaplug-esata.dtb > zImage+btb
$ mkimage -A arm -O linux -T kernel -C none \
  -a 0x02000000 -e 0x02000040 -n 'Linux-sheeva-esata' \
  -d zImage+btb uImage+dtb

できたカーネルを起動してみる

できたカーネル黒柴にくわせてみます. 先ほど作ったuImage+dtbファイルをFATでフォーマットしたSDカードにコピーし,黒柴にさして起動してください. 加えて,ホストマシンと黒柴をUSBでつなぎ,シリアルコンソールを繋いでください.ボーレート等は115200です.

シリアルコンソールを繋いだ状態でEnterを押すと以下のようなプロンプトが出ます.

Marvell>>

これを確認したら,以下のコマンドを実行してカーネルのロードと起動を行います.

mmcinit
fatload mmc 0:1 0x02000000 uimage+dtb
bootm

うまく起動すれば,以下のようにログがどばっと出て,最後にrootfsが見つからないといってパニックします.

Marvell>> mmcinit
SDHC found. Card desciption is:
Manufacturer:       0x74, OEM "JE"
Product name:       "USD  ", revision 1.0
Serial number:      1280314594
Manufacturing date: 1/2012
CRC:                0x00, b0 = 0
Marvell>> fatload mmc 0:1 0x02000000 uimage+dtb
reading uimage+dtb

4284489 bytes read
Marvell>> bootm
## Booting image at 02000000 ...
   Image Name:   Linux-sheeva-esata
   Created:      2015-12-24  12:22:51 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4284425 Bytes =  4.1 MB
   Load Address: 02000000
   Entry Point:  02000040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.3.0 (tnishinaga@arch-tx201) (gcc version 5.2.0 (crosstool-NG crosstool-ng-1.22.0) ) #5 PREEMPT Thu Dec 24 18:13:55 JST 2015
CPU: Feroceon 88FR131 [56251311] revision 1 (ARMv5TE), cr=0005397f
CPU: VIVT data cache, VIVT instruction cache
Machine model: Globalscale Technologies eSATA SheevaPlug
Memory policy: Data cache writeback
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
Kernel command line: console=ttyS0,115200 root=/dev/mmcblk0p2 rw
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 510696K/524288K available (6241K kernel code, 212K rwdata, 1680K rodata, 172K init, 661K bss, 13592K reserved, 0K cma-reserved, 0K highmem)
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
    vmalloc : 0xe0800000 - 0xff000000   ( 488 MB)
    lowmem  : 0xc0000000 - 0xe0000000   ( 512 MB)
    pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
    modules : 0xbf000000 - 0xbfe00000   (  14 MB)
      .text : 0xc0008000 - 0xc07c4704   (7922 kB)
      .init : 0xc07c5000 - 0xc07f0000   ( 172 kB)
      .data : 0xc07f0000 - 0xc0825220   ( 213 kB)
       .bss : 0xc0825220 - 0xc08ca9a0   ( 662 kB)
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Preemptible hierarchical RCU implementation.
    Build-time adjustment of leaf fanout to 32.
NR_IRQS:16 nr_irqs:16 16
clocksource: orion_clocksource: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 9556302233 ns
sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 10737418237ns
Console: colour dummy device 80x30
Calibrating delay loop... 1191.11 BogoMIPS (lpj=5955584)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x81e0 - 0x8238
mvebu-soc-id: MVEBU SoC ID=0x6281, Rev=0x2
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
xor: measuring software checksum speed
   arm4regs  :  1084.400 MB/sec
   8regs     :   804.400 MB/sec
   32regs    :   970.800 MB/sec
xor: using function: arm4regs (1084.400 MB/sec)
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
cpuidle: using governor ladder
cpuidle: using governor menu
Feroceon L2: Enabling L2
Feroceon L2: Cache support initialised.
[Firmware Info]: /ocp@f1000000/ethernet-controller@72000/ethernet0-port@0: local-mac-address is not set
raid6: int32x1  gen()   111 MB/s
raid6: int32x1  xor()    76 MB/s
raid6: int32x2  gen()   167 MB/s
raid6: int32x2  xor()   103 MB/s
raid6: int32x4  gen()   185 MB/s
raid6: int32x4  xor()   119 MB/s
raid6: int32x8  gen()   187 MB/s
raid6: int32x8  xor()   116 MB/s
raid6: using algorithm int32x8 gen() 187 MB/s
raid6: .... xor() 116 MB/s, rmw enabled
raid6: using intx1 recovery algorithm
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Advanced Linux Sound Architecture Driver Initialized.
clocksource: Switched to clocksource orion_clocksource
NET: Registered protocol family 2
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
futex hash table entries: 256 (order: -1, 3072 bytes)
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
kirkwood-pinctrl f1010000.pin-controller: registered pinctrl driver
irq: Cannot allocate irq_descs @ IRQ34, assuming pre-allocated
irq: Cannot allocate irq_descs @ IRQ66, assuming pre-allocated
mv_xor f1060800.xor: Marvell shared XOR driver
mv_xor f1060800.xor: Marvell XOR (Registers Mode): ( xor cpy intr )
mv_xor f1060900.xor: Marvell shared XOR driver
mv_xor f1060900.xor: Marvell XOR (Registers Mode): ( xor cpy intr )
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
console [ttyS0] disabled
f1012000.serial: ttyS0 at MMIO 0xf1012000 (irq = 26, base_baud = 12500000) is a 16550A
console [ttyS0] enabled
loop: module loaded
sata_mv f1080000.sata: slots 32 ports 2
scsi host0: sata_mv
scsi host1: sata_mv
ata1: SATA max UDMA/133 irq 32
ata2: SATA max UDMA/133 irq 32
nand: device found, Manufacturer ID: 0xec, Chip ID: 0xdc
nand: Samsung NAND 512MiB 3,3V 8-bit
nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
Scanning device for bad blocks
Bad eraseblock 2909 at 0x000016ba0000
Bad eraseblock 3657 at 0x00001c920000
3 ofpart partitions found on MTD device orion_nand
Creating 3 MTD partitions on "orion_nand":
0x000000000000-0x000000100000 : "u-boot"
0x000000100000-0x000000500000 : "uImage"
0x000000500000-0x000020000000 : "root"
libphy: orion_mdio_bus: probed
mv643xx_eth: MV-643xx 10/100/1000 ethernet driver version 1.4
mv643xx_eth_port mv643xx_eth_port.0 eth0: port 0 with MAC address f0:ad:4e:00:5c:d9
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ehci-orion: EHCI orion driver
orion-ehci f1050000.ehci: EHCI Host Controller
orion-ehci f1050000.ehci: new USB bus registered, assigned bus number 1
ata1: SATA link down (SStatus 0 SControl F300)
orion-ehci f1050000.ehci: irq 29, io mem 0xf1050000
orion-ehci f1050000.ehci: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
usbcore: registered new interface driver usb-storage
usbcore: registered new interface driver ums-datafab
usbcore: registered new interface driver ums-freecom
usbcore: registered new interface driver ums-jumpshot
usbcore: registered new interface driver ums-sddr09
usbcore: registered new interface driver ums-sddr55
mousedev: PS/2 mouse device common for all mice
rtc-mv f1010300.rtc: rtc core: registered f1010300.rtc as rtc0
i2c /dev entries driver
orion_wdt: Initial timeout 21 sec
mvsdio f1090000.mvsdio: Got CD GPIO
mvsdio f1090000.mvsdio: Got WP GPIO
MV-CESA:Could not register sha1 driver
MV-CESA:Could not register hmac-sha1 driver
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
oprofile: no performance counters
oprofile: using timer interrupt.
NET: Registered protocol family 17
lib80211: common routines for IEEE802.11 drivers
Btrfs loaded
rtc-mv f1010300.rtc: setting system clock to 2013-01-01 11:15:49 UTC (1357038949)
ALSA device list:
mmc0: new high speed SDHC card at address b368
  No soundcards found.
mmcblk0: mmc0:b368 USD   3.75 GiB 
 mmcblk0: p1
ata2: SATA link down (SStatus 0 SControl F300)
VFS: Cannot open root device "mmcblk0p2" or unknown-block(179,2): error -6
Please append a correct "root=" boot option; here are the available partitions:
1f00            1024 mtdblock0  (driver?)
1f01            4096 mtdblock1  (driver?)
1f02          519168 mtdblock2  (driver?)
b300         3941376 mmcblk0  driver: mmcblk
  b301         3937280 mmcblk0p1 00000000-01
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2)
CPU: 0 PID: 1 Comm: swapper Not tainted 4.3.0 #5
Hardware name: Marvell Kirkwood (Flattened Device Tree)
[<c000f848>] (unwind_backtrace) from [<c000d254>] (show_stack+0x10/0x14)
[<c000d254>] (show_stack) from [<c008368c>] (panic+0x98/0x1ec)
[<c008368c>] (panic) from [<c07c618c>] (mount_block_root+0x170/0x220)
[<c07c618c>] (mount_block_root) from [<c07c632c>] (mount_root+0xf0/0x11c)
[<c07c632c>] (mount_root) from [<c07c6474>] (prepare_namespace+0x11c/0x17c)
[<c07c6474>] (prepare_namespace) from [<c07c5db0>] (kernel_init_freeable+0x184/0x1cc)
[<c07c5db0>] (kernel_init_freeable) from [<c05f1e28>] (kernel_init+0x8/0xec)
[<c05f1e28>] (kernel_init) from [<c000a470>] (ret_from_fork+0x14/0x24)
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2)

これでとりあえず,Kernelがそこそこ動いていることが確認できました. 次はDebian環境を用意してちゃんと使えるようにしたいと思います.

おやすみなさい.

PyOCDを使ってmbedをデバッグする(2015年末ver)

この記事はmbed Advent Calendar 2015の9日目の記事です.


お久しぶりです. 今回の紹介するPyOCDは,mbedのプログラミングやデバッグに使えるPythonのライブラリです. 昨年のmbedアドベントカレンダーではmbedをデバッグするために使用していました.

tnishinaga.hatenablog.com tnishinaga.hatenablog.com

このPyOCDとgccを用いたmbedオフラインコンパイル環境を組み合わせると無料でmbedのデバッグができます. アセンブリをゴリゴリ書いてmbedのプログラミングをしている私にとってデバッガは必須なので,とても嬉しいです.

先週くらいにPyOCDをインストールし直そうとgithubのページを参照したところ,インストール方法からgdbサーバーの建て方等色々便利に変わっていたので,幾つか便利なコマンドの使い方を紹介します.

環境

OS ArchLinux
pyOCD version 0.6.1
使用したmbedボード FRDM-KL25Z

PyOCDの使い方

対応mbedボード

PyOCDが対応しているmbedボードと,そうでないボードがあります.

コードを読む限りでは,以下のボードに対応しているようです.

対応ボード
FRDM-KL25Z NXP LPC800-MAX
FRDM-KL05Z nRF51822-mKIT
FRDM-KL46z Arch BLE
FRDM-K20D50M Seeed Tiny BLE
FRDM-K22F DT01 + MB2001
FRDM-K64F DT01 + MB00xx
FRDM-KL02Z Bambino 210
FRDM-KL26Z Bambino 210E
FRDM-KL28Z maxwsnenv
mbed NXP LPC1768 max32600mbed
Arch Pro nRF51-DK
mbed NXP LPC11U24 WIZwik_W7500

github.com

PyOCDのインストール

以前はgithubからコードを取ってきてビルドしていましたが,現在はpipからインストールできるようになってました.

$ sudo pip2 install pyocd

プログラムの書き込み

pyocd-flashtool というコマンドはmbedのプログラムを書き込むことができます.

使い方は pyocd-flashtool の後ろにmbedのオンラインコンパイラコンパイルした時に降ってくるbinファイルを指定するだけです.

$ sudo pyocd-flashtool hoge.bin

実行ログはこんな感じです.

$ sudo pyocd-flashtool hoge.bin
INFO:root:new board id detected: 0200020318CE2E18E532D3E0
INFO:root:board allows 5 concurrent packets
INFO:root:DAP SWD MODE initialised
INFO:root:IDCODE: 0xBC11477
INFO:root:KL25Z not in secure state
INFO:root:2 hardware breakpoints, 0 literal comparators
INFO:root:CPU core is Cortex-M0+
INFO:root:2 hardware watchpoints
[====================] 100%

複数のmbedがつながっている場合はTARGETオプションをいじるひつようがありそうですが,試したことがないのでわかりません.

gdbサーバーを立てる

gdbサーバーを立てるのはpyocd-gdbserverというコマンドを叩くだけになっていました.

コマンドと実行ログは以下.

$ sudo pyocd-gdbserver
INFO:root:new board id detected: 0200020318CE2E18E532D3E0
INFO:root:board allows 5 concurrent packets
INFO:root:DAP SWD MODE initialised
INFO:root:IDCODE: 0xBC11477
INFO:root:KL25Z not in secure state
INFO:root:2 hardware breakpoints, 0 literal comparators
INFO:root:CPU core is Cortex-M0+
INFO:root:2 hardware watchpoints
INFO:root:Telnet: server started on port 4444
INFO:root:GDB server started at port:3333

後はgdbからリモート接続すればデバッグができます. 例えば,hogeというプログラムのfuga関数の実行を見たいときは以下のように行います *1

$ arm-none-eabi-gdb hoge.elf
(gdb) target remote :3333
(gdb) load
(gdb) break fuga
(gdb) c

後はstepコマンド等でステップ実行して見ていきます. 詳しくは去年の記事を参照してください.

pyocd-tool

$ pyocd-tool --help
usage: pyocd-tool [-h] [--version] [-H] [-k KHZ] [-b ID] [-t TARGET]
                  [-d LEVEL]
                  [cmd] [args [args ...]]

Target inspection utility

positional arguments:
  cmd                   Command
  args                  Arguments for the command.

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -H, --halt            Halt core upon connect.
  -k KHZ, --clock KHZ   Set SWD speed in kHz. (Default 1 MHz.)
  -b ID, --board ID     Use the specified board.
  -t TARGET, --target TARGET
                        Override target.
  -d LEVEL, --debug LEVEL
                        Set the level of system logging output. Supported
                        choices are: debug, info, warning, critical, error

Available commands: clock, d, disasm, erase, exit, g, go, h, halt, i, info,
list, log, map, quit, r, r16, r32, read, read16, read32, read8, reg, reset, s,
stat, status, step, unlock, w, w16, w32, wreg, write, write16, write32, write8

マイコンレジスタやメモリを読み書きしたりできるようですが,使いみちがよくわかっていません...すみません...

次の人

つぎはkb10uyさんです.

よろしくお願いします.

*1:デバッグを行いやすくするためにはシンボル情報等を含んだELFファイルが必要ですが,mbedオンラインコンパイラからそれら情報をごっそり落としたbinファイルしか落ちてきません. そのため,gccを用いたオフラインコンパイル環境でコンパイルを行う必要があります. オフラインコンパイルのやり方については以下の資料を参照してください.

オフライン コンパイル | mbed

UEFIアプリでファイルを任意のメモリアドレスにロードする方法メモ

UEFIアプリケーションでファイルを任意のメモリアドレスにロードする方法についてのメモです. ブートローダーを作ったりするのに役立つと思います.

開発環境はEDK2(28f27af6f007c3794fcc9d098ef91713160f4e5b),OSはArch Linuxを使いました.

これを行うにあたって,そもそもUEFIって何? 環境構築の方法は? 仕様書の読み方は? プロトコルとハンドラって何? どうやって動作確認するの?...等々いろいろわからないことがあり調べたのですが,今回はメモなので記述を省略します. 気力があれば後日書きます.

まだまだ勉強途中なので,間違い等ありましたらコメントでの指摘をお願いします.

ファイルを任意メモリアドレスにロードする方法

ソースコード

コードはAppPkg/Application/Helloを改変して作りました.

まずはiniファイルを示します.

## @file
#  A simple, basic, EDK II native, "hello" application.
#
#   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
#   This program and the accompanying materials
#   are licensed and made available under the terms and conditions of the BSD License
#   which accompanies this distribution. The full text of the license may be found at
#   http://opensource.org/licenses/bsd-license.
#
#   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
#   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##

[Defines]
  INF_VERSION                    = 0x00010006
  BASE_NAME                      = Hello
  FILE_GUID                      = a912f198-7f0e-4803-b908-b757b806ec83
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 0.1
  ENTRY_POINT                    = UefiMain

#
#  VALID_ARCHITECTURES           = IA32 X64 IPF
#

[Sources]
  Hello.c

[Packages]
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec

[LibraryClasses]
  UefiApplicationEntryPoint
  UefiLib

[Guids]
  gEfiFileInfoGuid

[Protocols]
  gEfiSimpleFileSystemProtocolGuid

次にCのソースを示します.

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>

#include <Protocol/DevicePath.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/SimpleFileSystem.h>


#define BUF_MAX_SIZE (512*1024) // 512KB

#define KERNEL_BASE  0x200000

EFI_SYSTEM_TABLE  *gST;
EFI_BOOT_SERVICES *gBS;

EFI_STATUS
EFIAPI
UefiMain (
      IN     EFI_HANDLE        ImageHandle,
      IN     EFI_SYSTEM_TABLE  *SystemTable
      )
{
  Print(L"Hello there fellow Programmer.\n");
  Print(L"Welcome to the world of EDK II.\n");


  EFI_STATUS                       Status = EFI_SUCCESS;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *SimpleFile;
  EFI_FILE_PROTOCOL                *Root;
  EFI_FILE_PROTOCOL                *File;
  CHAR16 *Path = L"hoge.txt";

  gST = SystemTable;
  gBS = gST->BootServices;

  Status = gBS->LocateProtocol (
                &gEfiSimpleFileSystemProtocolGuid,
                NULL,
                (VOID **)&SimpleFile
                );
  if (EFI_ERROR (Status)) {
    Print(L"%r on Locate EFI Simple File System Protocol.\n", Status);
    return Status;
  }

  Status = SimpleFile->OpenVolume (SimpleFile, &Root);
  if (EFI_ERROR (Status)) {
    Print(L"%r on Open volume.\n", Status);
    return Status;
  }

  Status = Root->Open (Root, &File, Path, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY);
  if (EFI_ERROR (Status)) {
    Print(L"%r on Open file.\n", Status);
    return Status;
  }

  UINTN                            BufferSize = 0;
  EFI_PHYSICAL_ADDRESS Buffer;
  BufferSize = BUF_MAX_SIZE;
  Buffer = (EFI_PHYSICAL_ADDRESS)KERNEL_BASE;
  // if you want to know MemoryType List, please refer UEFI Spec2.5 document pp.152-153
  Status = gBS->AllocatePages(
                 AllocateAddress,
                 EfiLoaderData,
                 BufferSize / 4 / 1024, // 1page = 4KiB 
                 &Buffer
                 );
  if (EFI_ERROR (Status)) {
    Print(L"%Could not allocate memory pool %r\n", Status);
    return Status;
  }

    
  Status = File->Read(
              File,
              &BufferSize,
              (VOID *)Buffer
              );
  if (EFI_ERROR (Status)) {
    Print(L"%r on Open file.\n", Status);
    return Status;
  }
  Print(L"BufferSize = %d\n", BufferSize);
  Print(L"Address = %p\n", Buffer);

  for (UINTN i = 0; i < BufferSize; i++) {
    Print(L"%c", ((CHAR8 *)Buffer)[i]);
  }
  Print(L"\n");


  File->Close(File);
  Root->Close(Root);

  gBS->FreePages(Buffer, BUF_MAX_SIZE);

  Print(L"All success hoge.txt\n");

  return EFI_SUCCESS;
}

処理の流れ

このコードの流れを日本語で示すと,次のようになっています.

  1. BootService(以降BS)からLocateProtocol関数を呼び出し,ファイルアクセスするためのプロトコルEFI_SIMPLE_FILE_SYSTEM_Protocol(以降SimpleFile)を取得する
  2. SimpleFileのOpenVolume関数でデバイスのルートディレクトリを開き,ルートディレクトリのファイルハンドラ(Root)を取得する
  3. RootのOpen関数で指定したファイル(今回はhoge.txt)を開き,そのファイルハンドラ(File)を取得する
  4. BSからAllocatePages関数を呼び出し,任意アドレスからメモリを確保する
  5. ファイルハンドラFileのRead関数を呼び出し,ファイルの内容を確保したメモリ領域に読みこむ
  6. ファイルハンドラを閉じる
  7. メモリを開放する

ファイルを場所を気にせず読みこむだけであれば,AllocatePool関数を使うことで手軽にメモリを確保できます. しかし,今回は「任意」のメモリアドレスにファイルを読み込むため,AllocatePagesという関数を用いています.

AllocatePages関数は第一引数にAllocateAddressを指定することで,第4引数で指摘したアドレスから第3引数で指定したページ分(1ページは4KiB)メモリを確保しようと試みます.

メモリが確保できない場合は,NOT FOUNDエラーが返ります.どの領域でどの程度メモリが取れるのかは,調べているところなのでまだわかっていません.

実行結果

メモリの確保が行われ,正常に動作した場合のログは以下のようになります.

UEFI Interactive Shell v2.1
EDK II
UEFI v2.50 (EDK II, 0x00010000)
Mapping table
      FS0: Alias(s):HD7a1:;BLK3:
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)
     BLK2: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
     BLK4: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x0)
     BLK1: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x1)
Press ESC in 5 seconds to skip startup.nsh or any other key to continue.
Shell> fs0:
FS0:\> Hello.efi  
Hello there fellow Programmer.
Welcome to the world of EDK II.
BufferSize = 5
Address = 200000
hoge

コードで指定したKERNEL_BASEのアドレス0x200000からメモリを取得し,hoge.txtの内容(hoge)を読み込み,出力できていることが確認できます.

emacs使い始めましたメモ1

リモート接続してCUI環境で作業することが多くなってきたので,CUIテキストエディタも使えるように環境を整備し始めました.

基本的に政治と宗教の話はしないのですが,私はemacsを使うことにしました. emacsベテランの方はいろいろ教えていただけると嬉しいです.

環境

OS: Mac OSX 10.10.4 パッケージ管理: Homebrew, Homebrew-cask

emacs のインストール

デフォルトで入ってるのは古いので,以下のコマンドで新しいのをインストールします.

$ brew install --with-cocoa emacs
$ ln -sfv /usr/local/opt/emacs/*.plist ~/Library/LaunchAgents
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.emacs.plist
$ brew linkapps emacs

--with-cocoa オプションをつけると,GUIでもemacsが使えるようになります. ファイルをダブルクリックしてemacsを開いて編集したいときは,必要です. ただし,関連付けは行ってくれないので,自分でやる必要があります(コマンドで設定する方法があれば教えてください).

基本操作

とりあえず,

  • C-? は Ctrl + ?
  • M-? が Esc + ?

であることがわかれば,後は自分で検索して何とか出来るはず.

init.elの作成

emacsはホームディレクトリ以下の .emacs ファイルや .emacs.d 以下にプラグインを記述することで機能を拡張できるようです. プラグインEmacs 用のLispEmacs Lisp を使って記述します.拡張子.el です.

以下のコマンドを実行して, .emacs.d/init.el を作ります(もし.emacsファイルがインストール時にできていた場合は,それを削除してください).

$ mkdir ~/.emacs.d
$ touch ~/.emacs.d/init.el

パッケージ管理システム

リポジトリの登録

emacs24からは,emacsプラグイン用のパッケージ管理システムがデフォルトで入っています. ただし,リポジトリを登録しないと使えないので,その設定をします.

.emacs.d/init.el を開いて以下を追記し,リポジトリの一つであるMELPAを追加してください.

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/") t)
(when (< emacs-major-version 24)
  ;; For important compatibility libraries like cl-lib
  (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize)

記述後,emacsを再起動するとパッケージ管理システムが使えるようになります.

パッケージ管理システムの使い方

以下のコマンドを実行すると,パッケージ管理システムの画面が立ち上がります.

M-x package-list-packages

起動した後の画面はこんな感じ

f:id:tnishinaga:20150704221831p:plain

パッケージのインストール方法は,インストールしたいパッケージ名(青色になってるところ)にカーソルを移動し,Enterを押すと画面の下半分にパッケージの詳細が出ます.

その状態で C-x o(Ctrl+xを入力後,Ctrlを離してoを入力) を入力すると,下半分の詳細欄にカーソルが移動します. その後「Install」のところにカーソルを持っていき,Enterを押すと以下の様な確認メッセージが出るので,そこで「y」を押せばインストールが開始されます.

f:id:tnishinaga:20150704221836p:plain

インストールしたパッケージ

とりあえずmultiple-cursorsをインストールして,SublimeTextのCmd+DやCmd+Shift+Lを使えるようにしてみました.

region-bindings-mode(インストールが必要)を使ってキーバインドを登録しているので,Ctrl+spaceで範囲を選択後

  • aを押すと,選択した単語すべてを選択してカーソルを増殖
  • nを押すと,選択した単語を順番に選択してカーソルを増殖
  • lを押すと,選択した行全てにカーソルを増殖

できるようにしています.

カーソルを1つに戻したいときは,Ctrl+spaceを入力して範囲選択モードに入った後,「;」を入力するとmultiple-cursorsモードが終了します.

今後追加したい機能たち