::log
[ TOP | 1997 1998 1999 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 ]
uboot on RaspberryPi3 その2 / uboot on RaspberryPi3 / i.MX6UL Starter Kit / docomo L-02C on netbsd / ESP8266 lwip / NetBSD/arm の printf が遅い。 / Nitrogen6MAX / CuBox-i1にシリアルをつける / NetBSD/evbarm NITROGEN6X - i.MX6 processor / about KERNEL_BASE_* on evbarm / cvsの闇 / raidframeチューニングふたたび / NITROGEN6X / PenguinDrum / EdgeRouterLite / kobo / NetBSD on さくらVPS / Aterm WM3600R / NetBSD/FON2405E #2 / CTIO
2018-01-10 uboot on RaspberryPi3 その2
netbsd/rpiがfdt化されたのでubootからの起動のさせ方をメモ。
RPI2でconfig/buildして nbmkubootimage -A arm -T kernel -O linux -a 0x0000000000008000 -e 0x0000000000008000 -n NetBSD/rpi3 -C none netbsd.bin netbsd.ub しておく。
tftpboot 0x00f00000 bcm2837-rpi-3-b.dtb tftpboot 0x01000000 netbsd.ub bootm 0x01000000 - 0x00f00000
でok。dtbのロードアドレスを100とかにするとダメだった。uboot imageのちょっと前あたりにしておけば良い。
どうもextentの扱いがおかしいっぽいけど詳細は謎。
netbsd/evbarm64のrpi3もfdt化された。これも同様に nbmkubootimage -A arm64 -T kernel_noload -O linux -n NetBSD/evbarm64 netbsd.bin netbsd.ub しておいて
tftpboot 0x01000000 netbsd.ub tftpboot 0x00000100 bcm2837-rpi-3-b.dtb; bootm 0x01000000 - 0x00000100
でok。こっちはdtbのロードアドレスが0x100でも大丈夫だった。
mkubootimgのパラメータとか微妙に変えただけで動かなくなるので気をつける。
2017-08-09 uboot on RaspberryPi3
夏休みの宿題のためRasPI3にubootを入れてみる。
https://kernelnomicon.org/?p=682 を見ながら…見てもよくわからない。
幸いRasPI3はググれば星の数ほど解説ページが出てくるので、色々なページをつらつらと読んでみた所
・RasPI3のUARTはbluetooth用に使われていて使えない?
・mini-uartという機能でcpu clockからbaud rateを作って通信する機能があってそっちなら使える
・そのためserialのスピードがcpu clock(可変)に引きづられ通信できない環境がある?
ということのようだ。しかし手元の環境だと普通に通信できてるので問題ないのかな。
とりあえずRPI3 uboot SD cardの作り方
・https://www.raspberrypi.org/downloads/raspbian/ からRaspbian Jessie Liteのイメージを落とす
・SD cardにddで書き込む
・SD cardにFATとLinuxのパーティションができる。Linux Partitionは使わないので無視
・FATパーティションをmountして、config.txt に以下の3行を追加
arm_control=0x200 enable_uart=1 kernel=u-boot.bin
・適当なLinux hostにaarch64なcross gccを入れる。apt-cache search aarch64-linux-gnuしてbinutil、gccをapt-get install
・http://git.denx.de/?p=u-boot.git を clone してビルドする
# make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- CONFIG_EFI=y rpi_3_defconfig # make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- CONFIG_EFI=y
・できた u-boot.bin を、SD cardのFATパーティションにコピー
・できあがり!
RasPI3のGPIO14(=TXD=PIN8)とGPIO15(=RXD=PIN10)にシリアルをつないでBoot!
U-Boot 2017.09-rc1-00133-geaa90e5-dirty (Aug 09 2017 - 02:23:24 +0900) DRAM: 944 MiB RPI 3 Model B (0xa02082) MMC: sdhci@7e300000: 0 reading uboot.env In: serial Out: vidconsole Err: vidconsole Net: No ethernet found. starting USB... USB0: Core Release: 2.80a scanning bus 0 for devices... 3 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found U-Boot> ? ? - alias for 'help' base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootefi - Boots an EFI payload from memory bootelf - Boot from an ELF image in memory booti - boot arm64 Linux Image image from memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol bootvx - Boot vxWorks from an ELF image cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation dhcp - boot image via network using DHCP/TFTP protocol dm - Driver model low level access echo - echo args to console editenv - edit environment variable env - environment handling commands exit - exit script ext2load- load binary file from a Ext2 filesystem ext2ls - list files in a directory (default /) ext4load- load binary file from a Ext4 filesystem ext4ls - list files in a directory (default /) ext4size- determine a file's size false - do nothing, unsuccessfully fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fatsize - determine a file's size fatwrite- write file into a dos filesystem fdt - flattened device tree utility commands fstype - Look up a filesystem type go - start application at address 'addr' gpio - query and control gpio pins help - print command description/usage iminfo - print header information for application image imxtract- extract a part of a multi-image itest - return true/false on integer compare lcdputs - print string on video framebuffer load - load binary file from a filesystem loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loadx - load binary file over serial line (xmodem mode) loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range ls - list files in a directory (default /) md - memory display mii - MII utility commands mm - memory modify (auto-incrementing address) mmc - MMC sub system mmcinfo - display MMC info mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) part - disk partition related commands ping - send ICMP ECHO_REQUEST to network host printenv- print environment variables pxe - commands to get and boot from pxe files reset - Perform RESET of the CPU run - run commands in an environment variable save - save file to a filesystem saveenv - save environment variables to persistent storage setcurs - set cursor position within screen setenv - set environment variables setexpr - set environment variable as the result of eval expression showvar - print local hushshell variables size - determine a file's size sleep - delay execution for some time source - run script from memory sysboot - command to get and boot from syslinux files test - minimal test like /bin/sh tftpboot- boot image via network using TFTP protocol true - do nothing, successfully usb - USB sub-system usbboot - boot from USB device version - print monitor, compiler and linker version U-Boot> bdinfo arch_number = 0x00000000 boot_params = 0x00000100 DRAM bank = 0x00000000 -> start = 0x00000000 -> size = 0x3B000000 baudrate = 115200 bps TLB addr = 0x3AFF0000 relocaddr = 0x3AF55000 reloc off = 0x3AED5000 irq_sp = 0x3AB4E0F0 sp start = 0x3AB4E0F0 Early malloc usage: 2d8 / 2000 fdt_blob = 000000003ab4e100 U-Boot>
2016-11-21 i.MX6UL Starter Kit
U-Boot dub-2015.04-r4.7 (Sep 13 2016 - 14:52:25)
CPU: Freescale i.MX6UL rev1.1 528 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 46C
Reset cause: POR
I2C: ready
DRAM: 256 MiB
MCA: HW_VER=1 FW_VER=0.8
PMIC: PFUZE300 DEV_ID=0x30 REV_ID=0x11
NAND: 256 MiB
MMC: FSL_SDHC: 0
In: serial
Out: serial
Err: serial
ConnectCore 6UL SOM variant 0x02: Industrial Ultralite 528MHz, 256MB NAND, 256MB DDR3, -40/+85C, Wireless, Bluetooth
Board: ConnectCore 6UL StarterBoard, version 2, ID 129
Net: FEC0
Hit any key to stop autoboot: 0
UBI: attaching mtd1 to ubi0
UBI: scanning is finished
UBI: attached mtd1 (name "mtd=3", size 14 MiB) to ubi0
UBI: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
UBI: VID header offset: 2048 (aligned 2048), data offset: 4096
UBI: good PEBs: 112, bad PEBs: 0, corrupted PEBs: 0
UBI: user volume: 0, internal volumes: 1, max. volumes count: 128
UBI: max/mean erase counter: 1/1, WL threshold: 4096, image sequence number: 0
UBI: available PEBs: 68, total reserved PEBs: 44, PEBs reserved for bad PEB handling: 40
Error reading superblock on volume 'ubi0:linux' errno=-19!
ubifsmount - mount UBIFS volume
Usage:
ubifsmount <volume-name>
- mount 'volume-name' volume
arch=arm
baudrate=115200
board=ccimx6ulstarter
board_id=129
board_name=ccimx6ulstarter
board_version=2
boot_fdt=yes
bootargs_linux=cma=96M
bootargs_nand_linux=setenv bootargs console=${console},${baudrate} ${bootargs_linux} ${mtdparts} ubi.mtd=${mtdlinuxindex} ubi.mtd=${mtdrootfsindex} root=ubi1_0 rootfstype=ubifs rw ${bootargs_once} ${extra_bootargs}
bootargs_recovery=setenv bootargs console=${console},${baudrate} androidboot.hardware=ccimx6ulstarter androidboot.console=${console}${mtdparts} ${bootargs_once} ${extra_bootargs}
bootcmd=if run loadscript; then source ${loadaddr};fi;
bootdelay=1
bscantest=PASS
btaddr=00:40:9D:98:AB:B5
console=ttymxc4
cpu=armv7
eth1addr=00:40:9D:98:AB:B3
ethact=FEC0
ethaddr=00:40:9D:98:AB:B2
ethprime=FEC
fdt_addr=0x83000000
fdt_file=zImage-imx6ul-ccimx6ulstarter.dtb
fdt_high=0xffffffff
initrd_addr=0x83800000
initrd_file=uramdisk.img
initrd_high=0xffffffff
install_linux_fw_sd=if load mmc 0 ${loadaddr} install_linux_fw_sd.scr;then source ${loadaddr};fi;
ipaddr=192.168.42.30
linux_file=core-image-base-ccimx6ulstarter.boot.ubifs
loadaddr=0x80800000
loadscript=if ubi part linux; then if ubifsmount ubi0:linux; then ubifsload ${loadaddr} ${script};fi;fi;
module_variant=0x02
mtddevname=bootloader
mtddevnum=0
mtdids=nand0=gpmi-nand
mtdlinuxindex=3
mtdparts=mtdparts=gpmi-nand:3m(bootloader),1m(environment),1m(safe),14m(linux),14m(recovery),128m(rootfs),-(update)
mtdrootfsindex=5
netmask=255.255.0.0
partition=nand0,0
recovery_file=recovery.img
recoverycmd=if ubi part recovery; thenif ubifsmount ubi0:recovery; thenubifsload ${loadaddr} ${zimage};ubifsload ${fdt_addr} ${fdt_file};ubifsload ${initrs_addr} ${initrd_file};run bootargs_recovery;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};fi;fi;
rootfs_file=core-image-base-ccimx6ulstarter.ubifs
rootpath=/exports/nfsroot-ccimx6ulstarter
script=boot.scr
serverip=192.168.42.1
soc=mx6
stderr=serial
stdin=serial
stdout=serial
uboot_file=u-boot.imx
vendor=digi
verifyaddr=88400000
wlanaddr=00:40:9D:98:AB:B4
zimage=zImage-ccimx6ulstarter.bin
Environment size: 2144/131067 bytes
=> help
? - alias for 'help'
askenv - get environment variables from stdin
base - print or set address offset
bdinfo - print Board Info structure
bmode - sd1|sd2|qspi1|nand|normal|usb|sata|ecspi1:0|ecspi1:1|ecspi1:2|ecspi1:3|esdhc1|esdhc2|esdhc3|esdhc4 [noreset]
board_id- Carrier board ID on fuse sub-system
board_version- Carrier board version on fuse sub-system
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
bootz - boot Linux zImage image from memory
chpart - change active partition
clocks - display clocks
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
dboot - Digi modules boot command
dcache - enable or disable data cache
dek_blob- Data Encryption Key blob encapsulation
dhcp - boot image via network using DHCP/TFTP protocol
dm - Driver model low level access
echo - echo args to console
editenv - edit environment variable
env - environment handling commands
erase - erase FLASH memory
exit - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls - list files in a directory (default /)
ext4load- load binary file from a Ext4 filesystem
ext4ls - list files in a directory (default /)
ext4size- determine a file's size
ext4write- create a file in the root directory
false - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
fatsize - determine a file's size
fatwrite- write file into a dos filesystem
fdt - flattened device tree utility commands
flinfo - print FLASH memory information
fstype - Look up a filesystem type
fuse - Fuse sub-system
go - start application at address 'addr'
gpt - GUID Partition Table
hab_auth_img- authenticate image via HAB
hab_status- display HAB status
help - print command description/usage
hwid - HWID on fuse sub-system
i2c - I2C sub-system
icache - enable or disable instruction cache
iminfo - print header information for application image
imxtract- extract a part of a multi-image
itest - return true/false on integer compare
load - load binary file from a filesystem
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loadx - load binary file over serial line (xmodem mode)
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
ls - list files in a directory (default /)
md - memory display
mdio - MDIO utility commands
mii - MII utility commands
mm - memory modify (auto-incrementing address)
mmc - MMC sub system
mmcinfo - display MMC info
mtdparts- define flash/nand partitions
mtest - simple RAM read/write test
mw - memory write (fill)
nand - NAND sub-system
nboot - boot from NAND device
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
part - disk partition related commands
ping - send ICMP ECHO_REQUEST to network host
pmic - PMIC
printenv- print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
run - run commands in an environment variable
save - save file to a filesystem
saveenv - save environment variables to persistent storage
setenv - set environment variables
setexpr - set environment variable as the result of eval expression
showvar - print local hushshell variables
size - determine a file's size
sleep - delay execution for some time
source - run script from memory
test - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
time - run commands and summarize execution time
true - do nothing, successfully
trustfence- Digi Trustfence(TM) command
ubi - ubi commands
ubifsload- load file from an UBIFS filesystem
ubifsls - list files in a directory
ubifsmount- mount UBIFS volume
ubifsumount- unmount UBIFS volume
update - Digi modules update command
usb - USB sub-system
usbboot - boot from USB device
version - print monitor, compiler and linker version
=>
2016-10-22 docomo L-02C on netbsd
iosysでL-02Cが1.5kだったのでなんとなく確保。
netbsdで動かそうと思ってググったけどそのものズバリな(コピペして使える)設定が見つからなかったのでgooglability向上のため置いておく。
% sudo mkdir -p /etc/ppp/peers % sudo touch /etc/ppp/options % sudo tee /etc/ppp/peers/iijmio /dev/dtyU2 921600 #debug local connect '/usr/sbin/chat -v -f /etc/ppp/iijmio.chat' defaultroute nopersist asyncmap 0 noauth ^D % sudo tee /etc/ppp/iijmio.chat ABORT BUSY ABORT ERROR ABORT 'NO CARRIER' '' AT OK AT OK ATZ OK ATH OK AT OK AT+CGDCONT=1,"IP","iijmio.jp" OK AT OK ATD*99***1# CONNECT \c ^D
で pppd call iijmio でppp0インターフェース経由で繋がる。簡単。
切断しても自動的に繋げなおしたい場合は /etc/ppp/peers/iijmio の nopersist を persist に変更すべし。
IPv6? よくわかりません! :D
2015-10-01 ESP8266 lwip
最近ESP8266をいじってます。Arduinoは中で何やってるかよくわからなくてキモチワルイので、xtensa--gccを使ってC言語です。
なので必然的にespressifが出してるsdkを使うのですが、このsdkがいまいちイケてない…
まず、WiFiやらに繋げるコードを書いてみると、シリアルに意図しない出力が。
どうもsdk libraryの中でprintfしてくれちゃってるようです。勝手にprintfしないでよ。
調べたら system_set_os_print(0) としておけば sdk library の中で printf するのを抑制できるらしいので、入れてみる。
すると今度は user program からの printf (os_printf()) も何も出力しなくなった。おいw
つーかーえーねーーーーーーーー(1つめ)
幸いシリアルのI/O portを直接ドライブするサンプルコードがあったので、オレオレprintfを入れてしまうことで対処。なんだかなあ。
もう一つは、TCPが不安定。telnetでつないで各種ルータやunixマシンのシリアルコンソールに繋げるものを作ったんだけど、
大量に送受信しているとTCPが切れる。tcpdumpで見てみると、ずいぶん変な切れ方をしている。
ESP8266側がtimeoutで切れた時にTCP_RSTを送るのだが、TCPのseqが狂っている。
そのためcilentは無視するので何度も再送ackを送る。ESPは何度もRSTを返す、みたいなことになっている。
糞IPスタックじゃねーか。(2つめ)
そもそもなんで切れるんだよTCPだろ再送しろよと思って調べてたらESP8266のsdkに使われてるlwipのソースがあった http://bbs.espressif.com/viewtopic.php?f=46&t=951 ので
これでliblwipを作りなおしてdebugできるぜと張り切ってデバッグしてみると、切断直前の数秒間にESP側でTCPの再送が走ってる。しかしtcpdumpして見ててもESP側から再送ackを送ってるようには見えない。
やっぱり糞IPスタックじゃねーか。
というわけでちまちまデバッグしてたら、追いかけてった先に #if 1 /* by Snake: resolve the bug of pbuf reuse */ 〜 #endif みたいな修正個所が。
本家 lwip には無い修正で、これのせいじゃねーの? と思って #if 0 にしたらTCP切れる問題は綺麗になおった。
どうも espressif でコメントの内容の事を修正しようとしたがエンバグしちゃったんだろうなぁ。リポジトリ公開してくれてないから経緯がよくわかんないけど。
とりあえず #if 0 にしてもメモリリークとかは起きてない様子なので問題なさげ。
なんで俺はsdkのデバッグをしてるんだろう。
なので必然的にespressifが出してるsdkを使うのですが、このsdkがいまいちイケてない…
まず、WiFiやらに繋げるコードを書いてみると、シリアルに意図しない出力が。
どうもsdk libraryの中でprintfしてくれちゃってるようです。勝手にprintfしないでよ。
調べたら system_set_os_print(0) としておけば sdk library の中で printf するのを抑制できるらしいので、入れてみる。
すると今度は user program からの printf (os_printf()) も何も出力しなくなった。おいw
つーかーえーねーーーーーーーー(1つめ)
幸いシリアルのI/O portを直接ドライブするサンプルコードがあったので、オレオレprintfを入れてしまうことで対処。なんだかなあ。
もう一つは、TCPが不安定。telnetでつないで各種ルータやunixマシンのシリアルコンソールに繋げるものを作ったんだけど、
大量に送受信しているとTCPが切れる。tcpdumpで見てみると、ずいぶん変な切れ方をしている。
ESP8266側がtimeoutで切れた時にTCP_RSTを送るのだが、TCPのseqが狂っている。
そのためcilentは無視するので何度も再送ackを送る。ESPは何度もRSTを返す、みたいなことになっている。
糞IPスタックじゃねーか。(2つめ)
そもそもなんで切れるんだよTCPだろ再送しろよと思って調べてたらESP8266のsdkに使われてるlwipのソースがあった http://bbs.espressif.com/viewtopic.php?f=46&t=951 ので
これでliblwipを作りなおしてdebugできるぜと張り切ってデバッグしてみると、切断直前の数秒間にESP側でTCPの再送が走ってる。しかしtcpdumpして見ててもESP側から再送ackを送ってるようには見えない。
やっぱり糞IPスタックじゃねーか。
というわけでちまちまデバッグしてたら、追いかけてった先に #if 1 /* by Snake: resolve the bug of pbuf reuse */ 〜 #endif みたいな修正個所が。
本家 lwip には無い修正で、これのせいじゃねーの? と思って #if 0 にしたらTCP切れる問題は綺麗になおった。
どうも espressif でコメントの内容の事を修正しようとしたがエンバグしちゃったんだろうなぁ。リポジトリ公開してくれてないから経緯がよくわかんないけど。
とりあえず #if 0 にしてもメモリリークとかは起きてない様子なので問題なさげ。
なんで俺はsdkのデバッグをしてるんだろう。
2015-07-09 NetBSD/arm の printf が遅い。
NetBSD/arm で、long long を printf "%llu" ("%lld") で表示するスピードが尋常じゃない遅さなのに気づいた。
ちなみにどれくらい遅いかというと、sprintf("%lld") は sprintf("%d") の20倍くらい遅い。2倍じゃないぞ。20倍だ。
追いかけてみると、10進数に変換する部分、10の商と剰余を毎桁計算して
としている個所がメチャ遅い様子。そう、armには割り算が無い。(Cortex-A15から存在する)
そもそも定数割り算の場合はコンパイラがよきにはからって乗算とシフトに展開してくれるのではないか?
…と思ってgccを調べたら、乗算+シフトに展開してくれるのは32bit除算の時だけで、64bit除算の場合gccはlibgccのudivdi3()を呼んでいた。(gcc/arm)
じゃあudivdi3が遅いのではないか? よく使う除数は内部で場合分けしてて、乗算+シフトで計算してくれても良さそうだが、と思ってこれまた調べたら、そういうものもない様子。
それならそれでいいんだけど、じゃあ64bit除算も乗算+シフトに展開してくれよんgcc! とか思った。これじゃ片手落ちだ。
まぁgccがそういう実装なのはしょうがないので置いとくとして、これを速くしてやろうと思う。
そもそも乗算+シフトで除算をするにはどうしたらいいか。
32bitの値を10で割る場合、0xCCCCCCCDを掛けてから35ビット右シフトすればよい。
0xCCCCCCCD てなんじゃらほい? と思った人のために説明すると、0xCCCCCCCD は10進で3435973837、35ビット右シフトは1/2^35で1/34359738368であるので、
3435973837/34359738368 = 0.10000000000582076609134674072265625 = 0.1 = 1/10
となる。
つまり (2^n/10) に近い値を掛けて、nビット右シフトしてやればいいのだ。
3倍して右5bitシフト(1/32)してもいいし、102倍して右10ビットシフト(1/1024)してもいいのだが、当然誤差がでてしまうので、32bitに収まるうちのギリギリの数が0xCCCCCCCDというわけだ。
64bitの場合は、2^67/10に近い 0xCCCCCCCCCCCCCCCD を掛けて、67ビット右シフトする。
同様に説明すると、0xCCCCCCCCCCCCCCCD は 14757395258967641293、67ビット右シフトは 2^67 = 147573952589676412928 なので、
14757395258967641293 / 147573952589676412928 = 0.1000000000000000000013552527156068805425093160010874271392822265625 = 0.1 = 1/10
となる。
uint64_t を 10 で割る所を上の乗算+シフトに書き換えれば速くなるに違いないというわけで、書いてみた。
ベンチマークは以下の通り。
sprintf … 素のprintf
str_uint64_div … 中身はsprintfの実装をシンプルにしたもの
str_uint64_nodiv … 上の乗算+シフトで実装したもの
というわけで15倍くらいになった。
処理内容がほぼ同はずのsprintfとstr_uint64_divの8%の差は、libcのsprintf()には桁合わせとか色々余計な処理があるためのオーバーヘッドと測定誤差と思われる。
ちなみにLinux(glibc)はどうなんだと思って調べたら、glibcはちゃんと乗算+シフトを使っていた。NetBSDダメじゃん…
さて、libcのsprintfの方も修正すればとりあえず解決なのだが、他にもっと速い方法は無いものかと、思いついたものを試してみた。
・上の桁から引き算していく方法
64bitを10進にする場合、0xFFFFFFFFFFFFFFFF = 18446744073709551615 なので最大20桁。ならば
10^20、10^19…と順に桁毎に引き算していき、引けた数を表示すれば10進になるよね、というわけで書いてみた。
各桁でループしてるから遅いかな、と思ったが、これがなかなか速い。
乗算+シフトよりも2割ほど速くなった。しかし引ける数でループしてるので、999999999 みたいな数だとループの回数が多くなるので遅くなる(それでも速いが)。
そこでループを展開してみた。何も考えず展開するのではなくて、桁の値が8未満なら4以上か4未満か、4未満なら2以上か2未満か…のように二分探索で展開する。
これはかなり効いたようだ。
最初の除算から比べると36倍。乗算+シフトと比較しても2倍以上だ。コードサイズが7〜8kbyteになるが ;)
ベンチマークプログラムはgithubに置いておく。https://github.com/ryo/lltoa
というわけでオレオレNetBSD/armにはnodiv_noloop版を入れることにした。
本家netbsdにも少くともsprintf遅杉という問題提起はしなきゃですね。
ちなみにどれくらい遅いかというと、sprintf("%lld") は sprintf("%d") の20倍くらい遅い。2倍じゃないぞ。20倍だ。
追いかけてみると、10進数に変換する部分、10の商と剰余を毎桁計算して
do { *--dst = (n % 10) + '0'; n /= 10; } while (n != 0);
としている個所がメチャ遅い様子。そう、armには割り算が無い。(Cortex-A15から存在する)
そもそも定数割り算の場合はコンパイラがよきにはからって乗算とシフトに展開してくれるのではないか?
…と思ってgccを調べたら、乗算+シフトに展開してくれるのは32bit除算の時だけで、64bit除算の場合gccはlibgccのudivdi3()を呼んでいた。(gcc/arm)
じゃあudivdi3が遅いのではないか? よく使う除数は内部で場合分けしてて、乗算+シフトで計算してくれても良さそうだが、と思ってこれまた調べたら、そういうものもない様子。
それならそれでいいんだけど、じゃあ64bit除算も乗算+シフトに展開してくれよんgcc! とか思った。これじゃ片手落ちだ。
まぁgccがそういう実装なのはしょうがないので置いとくとして、これを速くしてやろうと思う。
そもそも乗算+シフトで除算をするにはどうしたらいいか。
32bitの値を10で割る場合、0xCCCCCCCDを掛けてから35ビット右シフトすればよい。
0xCCCCCCCD てなんじゃらほい? と思った人のために説明すると、0xCCCCCCCD は10進で3435973837、35ビット右シフトは1/2^35で1/34359738368であるので、
3435973837/34359738368 = 0.10000000000582076609134674072265625 = 0.1 = 1/10
となる。
つまり (2^n/10) に近い値を掛けて、nビット右シフトしてやればいいのだ。
3倍して右5bitシフト(1/32)してもいいし、102倍して右10ビットシフト(1/1024)してもいいのだが、当然誤差がでてしまうので、32bitに収まるうちのギリギリの数が0xCCCCCCCDというわけだ。
64bitの場合は、2^67/10に近い 0xCCCCCCCCCCCCCCCD を掛けて、67ビット右シフトする。
同様に説明すると、0xCCCCCCCCCCCCCCCD は 14757395258967641293、67ビット右シフトは 2^67 = 147573952589676412928 なので、
14757395258967641293 / 147573952589676412928 = 0.1000000000000000000013552527156068805425093160010874271392822265625 = 0.1 = 1/10
となる。
uint64_t を 10 で割る所を上の乗算+シフトに書き換えれば速くなるに違いないというわけで、書いてみた。
static inline uint64_t lldiv10(uint64_t x) { #define MAGIC10_H 0xcccccccc #define MAGIC10_L 0xcccccccd #define MAGIC10_SHIFT 3 uint64_t xh = x >> 32; uint64_t xl = x & 0xffffffff; uint64_t a = xh * MAGIC10_L; uint64_t ah = a >> 32; uint64_t al = a & 0xffffffff; uint64_t b = xl * MAGIC10_H;; uint64_t bh = b >> 32; uint64_t bl = b & 0xffffffff; return (((((xl * MAGIC10_L) >> 32) + al + bl) >> 32) + ah + bh + xh * MAGIC10_H) >> MAGIC10_SHIFT; } char * str_uint64_mulshift(char *dst, uint64_t n) { uint64_t q; int l; char *p, *p0; p = p0 = dst + 20; /* 20 = maximum length of decimal UINT64_MAX */ do { q = lldiv10(n); *--p = (n - (q * 10)) + '0'; n = q; } while (n != 0); l = p0 - p; memmove(dst, p, l); dst[l] = '\0'; return &dst[l]; } char * str_uint64_div(char *dst, uint64_t n) { int l; char *p, *q; p = q = dst + 20; /* 20 = maximum length of decimal UINT64_MAX */ do { *--p = (n % 10) + '0'; n /= 10; } while (n != 0); l = q - p; memmove(dst, p, l); dst[l] = '\0'; return &dst[l]; }
ベンチマークは以下の通り。
sprintf … 素のprintf
str_uint64_div … 中身はsprintfの実装をシンプルにしたもの
str_uint64_nodiv … 上の乗算+シフトで実装したもの
try 10000 loops for each functions ---------------------------------------------------------------------------- sprintf 6.416028455 sec, 1558.59658 times/sec, 100.00% str_uint64_div 5.933064350 sec, 1685.46967 times/sec, 108.14% str_uint64_mulshift 0.372681510 sec, 26832.56274 times/sec, 1702.15%
というわけで15倍くらいになった。
処理内容がほぼ同はずのsprintfとstr_uint64_divの8%の差は、libcのsprintf()には桁合わせとか色々余計な処理があるためのオーバーヘッドと測定誤差と思われる。
ちなみにLinux(glibc)はどうなんだと思って調べたら、glibcはちゃんと乗算+シフトを使っていた。NetBSDダメじゃん…
さて、libcのsprintfの方も修正すればとりあえず解決なのだが、他にもっと速い方法は無いものかと、思いついたものを試してみた。
・上の桁から引き算していく方法
64bitを10進にする場合、0xFFFFFFFFFFFFFFFF = 18446744073709551615 なので最大20桁。ならば
10^20、10^19…と順に桁毎に引き算していき、引けた数を表示すれば10進になるよね、というわけで書いてみた。
char * str_uint64_nodiv(char *dst, uint64_t n) { char *p = dst; int q; int pad = 0; /* * uint64_t の最大は 18446744073709551615 なので * 一番上の桁は0か1しかない */ if (n >= 10000000000000000000ULL) { *p++ = '1'; n -= 10000000000000000000ULL; pad = 1; } #define QOUTPUT(X) \ if (n >= X) { \ q = 0; \ do { \ q++; \ n -= X; \ } while (n >= X); \ *p++ = q + '0'; \ pad = 1; \ } else if (pad) { \ *p++ = '0'; \ } QOUTPUT(1000000000000000000ULL); QOUTPUT(100000000000000000ULL); QOUTPUT(10000000000000000ULL); QOUTPUT(1000000000000000ULL); QOUTPUT(100000000000000ULL); QOUTPUT(10000000000000ULL); QOUTPUT(1000000000000ULL); QOUTPUT(100000000000ULL); QOUTPUT(10000000000ULL); QOUTPUT(1000000000ULL); QOUTPUT(100000000ULL); QOUTPUT(10000000ULL); QOUTPUT(1000000ULL); QOUTPUT(100000ULL); QOUTPUT(10000ULL); QOUTPUT(1000ULL); QOUTPUT(100ULL); QOUTPUT(10ULL); *p++ = n + '0'; *p = '\0'; return p; }
各桁でループしてるから遅いかな、と思ったが、これがなかなか速い。
try 10000 loops for each functions ------------------------------- str_uint64_div 6.248697894 sec, 1600.33341 times/sec, 100.00% str_uint64_mulshift 0.372665050 sec, 26833.74789 times/sec, 1676.75% str_uint64_nodiv 0.307277311 sec, 32543.89323 times/sec, 2033.56%
乗算+シフトよりも2割ほど速くなった。しかし引ける数でループしてるので、999999999 みたいな数だとループの回数が多くなるので遅くなる(それでも速いが)。
そこでループを展開してみた。何も考えず展開するのではなくて、桁の値が8未満なら4以上か4未満か、4未満なら2以上か2未満か…のように二分探索で展開する。
char * str_uint64_nodiv_noloop(char *dst, uint64_t n) { char *p = dst; int q; int pad = 0; /* * uint64_t の最大は 18446744073709551615 なので * 一番上の桁は0か1しかない */ if (n >= 10000000000000000000ULL) { *p++ = '1'; n -= 10000000000000000000ULL; pad = 1; } #define QXOUTPUT(X) \ if (n < ((X) * 8)) { \ if (n < ((X) * 4)) { \ if (n < ((X) * 2)) { \ if (n < (X)) { \ if (pad) \ *p++ = '0'; \ } else { \ *p++ = '1'; \ n -= (X); \ pad = 1; \ } \ } else { \ pad = 1; \ if (n < ((X) * 3)) { \ *p++ = '2'; \ n -= (X) * 2; \ } else { \ *p++ = '3'; \ n -= (X) * 3; \ } \ } \ } else { \ pad = 1; \ if (n < ((X) * 6)) { \ if (n < ((X) * 5)) { \ *p++ = '4'; \ n -= (X) * 4; \ } else { \ *p++ = '5'; \ n -= (X) * 5; \ } \ } else { \ if (n < ((X) * 7)) { \ *p++ = '6'; \ n -= (X) * 6; \ } else { \ *p++ = '7'; \ n -= (X) * 7; \ } \ } \ } \ } else { \ pad = 1; \ if (n < ((X) * 9)) { \ *p++ = '8'; \ n -= (X) * 8; \ } else { \ *p++ = '9'; \ n -= (X) * 9; \ } \ } QXOUTPUT(1000000000000000000ULL); QXOUTPUT(100000000000000000ULL); QXOUTPUT(10000000000000000ULL); QXOUTPUT(1000000000000000ULL); QXOUTPUT(100000000000000ULL); QXOUTPUT(10000000000000ULL); QXOUTPUT(1000000000000ULL); QXOUTPUT(100000000000ULL); QXOUTPUT(10000000000ULL); QXOUTPUT(1000000000ULL); QXOUTPUT(100000000ULL); QXOUTPUT(10000000ULL); QXOUTPUT(1000000ULL); QXOUTPUT(100000ULL); QXOUTPUT(10000ULL); QXOUTPUT(1000ULL); QXOUTPUT(100ULL); QXOUTPUT(10ULL); *p++ = n + '0'; *p = '\0'; return p; }
これはかなり効いたようだ。
try 100000 loops for each functions ------------------------------- str_uint64_div 59.452894663 sec, 1682.00389 times/sec, 100.00% str_uint64_mulshift 3.668981392 sec, 27255.52117 times/sec, 1620.41% str_uint64_nodiv 3.080811260 sec, 32458.98290 times/sec, 1929.78% str_uint64_nodiv_noloop 1.623337725 sec, 61601.47606 times/sec, 3662.38%
最初の除算から比べると36倍。乗算+シフトと比較しても2倍以上だ。コードサイズが7〜8kbyteになるが ;)
ベンチマークプログラムはgithubに置いておく。https://github.com/ryo/lltoa
というわけでオレオレNetBSD/armにはnodiv_noloop版を入れることにした。
本家netbsdにも少くともsprintf遅杉という問題提起はしなきゃですね。
2014-12-22 Nitrogen6MAX
ひと月前に自分で自分に買ったクリスマスプレゼントキタ━━━━━━(゚∀゚)━━━━━━ !!
U-Boot 2014.07-00136-gf870252 (Sep 22 2014 - 09:15:50) CPU: Freescale i.MX6Q rev1.2 at 792 MHz Reset cause: POR Board: Nitrogen6_max I2C: ready DRAM: 3.8 GiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 SF: Detected SST25VF016B with page size 256 Bytes, erase size 4 KiB, total 2 MiB No panel detected: default to HDMI Display: HDMI (1024x768) In: serial Out: serial Err: serial Net: using phy at 6 FEC [PRIME], usb_ether Hit any key to stop autoboot: 0 U-Boot > ? ? - alias for 'help' base - print or set address offset bdinfo - print Board Info structure bmode - mmc0|mmc1|normal|usb|sata|escpi1:0|escpi1:1|escpi1:2|escpi1:3|esdhc1|esdhc2|esdhc3|esdhc4 [noreset] bmp - manipulate BMP image data boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol bootvx - Boot vxWorks from an ELF image bootz - boot Linux zImage image from memory clocks - display clocks cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation dcache - enable or disable data cache dhcp - boot image via network using DHCP/TFTP protocol echo - echo args to console editenv - edit environment variable env - environment handling commands erase - erase FLASH memory exit - exit script ext2load- load binary file from a Ext2 filesystem ext2ls - list files in a directory (default /) ext4load- load binary file from a Ext4 filesystem ext4ls - list files in a directory (default /) false - do nothing, unsuccessfully fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fdt - flattened device tree utility commands flinfo - print FLASH memory information fuse - Fuse sub-system go - start application at address 'addr' gpio - query and control gpio pins hdmidet - detect HDMI monitor help - print command description/usage i2c - I2C sub-system icache - enable or disable instruction cache iminfo - print header information for application image imxtract- extract a part of a multi-image itest - return true/false on integer compare kbd - Tests for keypresses, sets 'keybd' environment variable load - load binary file from a filesystem loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loadx - load binary file over serial line (xmodem mode) loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range ls - list files in a directory (default /) md - memory display mdio - MDIO utility commands mii - MII utility commands mm - memory modify (auto-incrementing address) mmc - MMC sub system mmcinfo - display MMC info mtest - simple RAM read/write test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) ping - send ICMP ECHO_REQUEST to network host printenv- print environment variables protect - enable or disable FLASH write protection reset - Perform RESET of the CPU run - run commands in an environment variable sata - SATA sub system saveenv - save environment variables to persistent storage setenv - set environment variables setexpr - set environment variable as the result of eval expression sf - SPI flash sub-system showvar - print local hushshell variables sleep - delay execution for some time source - run script from memory test - minimal test like /bin/sh tftpboot- boot image via network using TFTP protocol time - run commands and summarize execution time true - do nothing, successfully ums - Use the UMS [User Mass Storage] usb - USB sub-system usbboot - boot from USB device version - print monitor, compiler and linker version U-Boot > ver U-Boot 2014.07-00136-gf870252 (Sep 22 2014 - 09:15:50) arm-linux-gnueabihf-gcc (Ubuntu/Linaro 4.8.2-16ubuntu4) 4.8.2 GNU ld (GNU Binutils for Ubuntu) 2.24 U-Boot > base Base Address: 0x00000000 U-Boot > bdinfo arch_number = 0x00000EC2 boot_params = 0x10000100 DRAM bank = 0x00000000 -> start = 0x10000000 -> size = 0xF0000000 eth0name = FEC ethaddr = 00:19:b8:01:97:1a eth1name = usb_ether eth1addr = (not set) current eth = FEC ip_addr = <NULL> baudrate = 115200 bps TLB addr = 0xFFFF0000 relocaddr = 0xFFF52000 reloc off = 0xE8752000 irq_sp = 0xFF34FEC0 sp start = 0xFF34FEB0 FB base = 0xFF357300 U-Boot > clocks PLL_SYS 792 MHz PLL_BUS 528 MHz PLL_OTG 480 MHz PLL_NET 50 MHz IPG 66000 kHz UART 80000 kHz CSPI 60000 kHz AHB 132000 kHz AXI 264000 kHz DDR 528000 kHz USDHC1 198000 kHz USDHC2 198000 kHz USDHC3 198000 kHz USDHC4 198000 kHz EMI SLOW 132000 kHz IPG PERCLK 66000 kHz U-Boot > coninfo List of available devices: vga 80000002 S.O serial 80000003 SIO stdin stdout stderr nulldev 80000003 SIO mxc_serial 00000003 .IO nc 80000003 SIO U-Boot > dcache Data (writethrough) Cache is ON U-Boot > dcache Data (writethrough) Cache is ON U-Boot > printenv baudrate=115200 board=nitrogen6_max bootcmd=for dtype in ${bootdevs}; do if itest.s "xusb" == "x${dtype}" ; then usb start ;fi; for disk in 0 1 ; do ${dtype} dev ${disk} ;for fs in fat ext2 ; do ${fs}load ${dtype} ${disk}:1 10008000 /6x_bootscript&& source 10008000 ; done ; done ; done; setenv stdout serial,vga ; echo ; echo 6x_bootscript not found ; echo ; echo serial console at 115200, 8N1 ; echo ; echo details at http://boundarydevices.com/6q_bootscript ; setenv stdin serial,usbkbd bootdelay=1 bootdevs=sata mmc usb clearenv=if sf probe || sf probe || sf probe 1 ; then sf erase 0xc0000 0x2000 && echo restored environment to factory default ; fi console=ttymxc1 cpu=6Q ethact=FEC ethaddr=00:19:b8:01:97:1a ethprime=FEC fdt_addr=0x11000000 fdt_high=0xffffffff initrd_high=0xffffffff loadaddr=0x12000000 loadsplash=if sf probe ; then sf read ${splashimage} c2000 ${splashsize} ; fi stdin=serial,usbkbd stdout=serial,vga upgradeu=for dtype in ${bootdevs}; do for disk in 0 1 ; do ${dtype} dev ${disk} ;for fs in fat ext2 ; do ${fs}load ${dtype} ${disk}:1 10008000 /6x_upgrade && source 10008000 ; done ; done ; done usbnet_devaddr=00:19:b8:00:00:02 usbnet_hostaddr=00:19:b8:00:00:01 usbrecover=setenv ethact usb_ether; setenv ipaddr 10.0.0.2; setenv netmask 255.255.255.0; setenv serverip 10.0.0.1; setenv bootargs console=ttymxc1,115200; tftpboot 10800000 10.0.0.1:uImage-${board}-recovery&& tftpboot 12800000 10.0.0.1:uramdisk-${board}-recovery.img && bootm 10800000 12800000 wlmac=00:19:B8:01:97:1b Environment size: 1556/8188 bytes U-Boot >
2014-09-30 CuBox-i1にシリアルをつける
netbsd/imx6のデバッグのためCuBox-i1を買った。テスト用なので一番安いやつ。
EtherのPHYが10/100でNITROGEN6Xと違うのでRMIIのデバッグになるかなと思って買ったのだが
consoleのUARTアドレスを変えてahcisataをコメントアウトしただけで動いてしまったので
あんまりデバッグにならず。
のは置いといて、CuBox-iはCuBoX-i1,i2,i2eX,i2ultra,i4proなど
色々ラインナップがあります。
ただしシリアルコンソール(中にUSB変換が入っていてmicro USBポートからUSB serialが見える)
が取れるのは一部の機種のようです。
一番安いモデルのCuBox-i1には当然シリアル/USB変換は付いてなかったのですが
「どーせ分解したらUARTのピンが出てるんでしょ」と思って買いました。
で開けたんですが、見当たりませんでした。ガーン。
落ち着いてCuBox-iのwikiを見たら、シリアルまわりの回路図があり、
そこにUARTのTX/RXがTP1、TP2という情報が!

基板上の位置はこのへん

というわけで、基板のTP1/TP2に秋月で買ったFT232RLをつけて無事UARTがとれるようになりました。
自分用メモ http://www.solid-run.com/wiki/U-Boot dd if=SPL of=/dev/sd0d bs=1k seek=1 dd if=u-boot.img of=/dev/sd0d bs=1k seek=42
2014-09-20 NetBSD/evbarm NITROGEN6X - i.MX6 processor
というわけで手元でちまちま作業してたのですが、MULTIPROCESSORで安定してbootするまでできました。
MULTIPROCESSORでbootした後はよく落ちます(これはsys/arch/armのせいで移植自体に問題はない…はず)
single processorなら問題ない感じ。
github
あたりは普通に使えると思います。もうちょっとcleanupしてそのうち本家にcommitします。
MULTIPROCESSORでbootした後はよく落ちます(これはsys/arch/armのせいで移植自体に問題はない…はず)
single processorなら問題ない感じ。
github
- UART
- Ethernet
- SATA
- USB
- GPIO
あたりは普通に使えると思います。もうちょっとcleanupしてそのうち本家にcommitします。
2014-09-20 about KERNEL_BASE_* on evbarm
evbarmの移植してるとこんがらがってくるのが KERNEL_BASE_PHYS、KERNEL_BASE_VIRT、KERNEL_BASE_EXT です。
KERNEL_BASE_PHYS カーネルの物理開始アドレス
KERNEL_BASE_VIRT カーネルの論理開始アドレス
KERNEL_BASE_EXT カーネルが使用可能な論理開始アドレス
です。
例えば、とあるボードは物理実装メモリが512Mbyte。
メモリマップは以下のようになっている場合を考えます。
uboot等のROMモニタが0x10000000にロードされ動作すると、ユーザプログラム
(この場合カーネル)のロードアドレスは(ubootの都合により)0x10080000等の
半端なアドレスとなります。そのため、netbsdのカーネルは0x10080000にロード
され、0x10080000から実行されることになります。
この場合、
とします。
KERNEL_BASE_VIRT は、カーネルの論理アドレスなので、netbsd側でつじつまが
あっていれば他のアドレスの場合もありえます(※)
「あれ、kernel が 0x10800000 = 0x80800000 にロードされるならば、メモリが
実装されているはずの 0x10000000〜0x10800000 の領域は無駄になるんじゃないの?」
と思った人はなかなかスルドイです。
この領域も当然もったいないので、実は当然ちゃんと使われます。
そのへんは arm32_bootmem_init() がうまくやってくれて、
arm32_bootmem_init() に、実メモリ実装範囲 0x10000000〜0x30000000、および
kernelの開始番地 0x10800000 を渡すと、実メモリの先頭からkernel開始番地の
空き領域 0x10000000〜0x10800000 をフリーページとして登録してくれて、
malloc(9)等で使えるようになります。VERBOSE_INIT_ARM を付けてコンパイルすると
起動時にそのへんの情報が表示されます。
さて、(※) で指摘した、kernelの論理アドレスを0x80000000ではなく他のアドレスに
したい場合はKERNEL_BASE_EXT を定義します。
例えば KERNEL_BASE_EXT = 0xC0000000 にすると、netbsd の userland プログラムの
論理アドレスは 0x00000000〜、kernel の開始アドレスが 0xC0000000〜 になります。
この場合、netbsd kernelで使える論理メモリ領域は
となり、この領域がkernelのtext、stackやMMU用のテーブル、malloc(9)、bus_space_map、
pool allocator等で使われます。
evbarmの場合、KERNEL_BASE は sys/arch/evbarm/include/vmparam.h でデフォルトでは
0x80000000 に定義されています。上記のようにこれを 0xC0000000 に変えたい場合は、
#define KERNEL_BASE_EXT 0xC0000000 すると、
のように定義されなおすわけです。
KERNEL_BASE_PHYS カーネルの物理開始アドレス
KERNEL_BASE_VIRT カーネルの論理開始アドレス
KERNEL_BASE_EXT カーネルが使用可能な論理開始アドレス
です。
例えば、とあるボードは物理実装メモリが512Mbyte。
メモリマップは以下のようになっている場合を考えます。
0x00000000 +----------------+ | I/O、ROM等 | | | 0x10000000 +----------------+ | メインメモリ | | 512Mbyte | | | | | 0x30000000 +----------------+ | | | 未使用 | | | 〜〜〜〜〜〜〜〜〜 〜〜〜〜〜〜〜〜〜 | | | | 0xA0000000 +----------------+ | I/O、ROM等 | | | 0xFFFFFFFF +----------------+
uboot等のROMモニタが0x10000000にロードされ動作すると、ユーザプログラム
(この場合カーネル)のロードアドレスは(ubootの都合により)0x10080000等の
半端なアドレスとなります。そのため、netbsdのカーネルは0x10080000にロード
され、0x10080000から実行されることになります。
この場合、
KERNEL_BASE_PHYS =0x10800000 KERNEL_BASE_VIRT =0x80800000 KERNEL_BASE =0x80000000
とします。
KERNEL_BASE_VIRT は、カーネルの論理アドレスなので、netbsd側でつじつまが
あっていれば他のアドレスの場合もありえます(※)
「あれ、kernel が 0x10800000 = 0x80800000 にロードされるならば、メモリが
実装されているはずの 0x10000000〜0x10800000 の領域は無駄になるんじゃないの?」
と思った人はなかなかスルドイです。
この領域も当然もったいないので、実は当然ちゃんと使われます。
そのへんは arm32_bootmem_init() がうまくやってくれて、
arm32_bootmem_init() に、実メモリ実装範囲 0x10000000〜0x30000000、および
kernelの開始番地 0x10800000 を渡すと、実メモリの先頭からkernel開始番地の
空き領域 0x10000000〜0x10800000 をフリーページとして登録してくれて、
malloc(9)等で使えるようになります。VERBOSE_INIT_ARM を付けてコンパイルすると
起動時にそのへんの情報が表示されます。
NetBSD/evbarm (nitrogen6) booting ... initarm: Configuring system (4 cpus, hatched 0xe), CLIDR=1110000003 CTR=0x83338003 arm32_bootmem_init: memstart=0x10000000, memsize=0x40000000, kernelstart=0x10800000 arm32_bootmem_init: kernelend=0x10e50000 arm32_bootmem_init: adding 129240 free pages: [0x10e50000..0x4fffffff] (VA 0x80e50000) arm32_bootmem_init: adding 1024 free pages: [0x10000000..0x107fffff] (VA 0x80000000) arm32_kernel_vm_init: 0 L2 pages are needed to map 0x6a0000 kernel bytes
さて、(※) で指摘した、kernelの論理アドレスを0x80000000ではなく他のアドレスに
したい場合はKERNEL_BASE_EXT を定義します。
例えば KERNEL_BASE_EXT = 0xC0000000 にすると、netbsd の userland プログラムの
論理アドレスは 0x00000000〜、kernel の開始アドレスが 0xC0000000〜 になります。
この場合、netbsd kernelで使える論理メモリ領域は
0xC0000000〜0xFFFFFFFFの0x40000000=1Gbyte
となり、この領域がkernelのtext、stackやMMU用のテーブル、malloc(9)、bus_space_map、
pool allocator等で使われます。
evbarmの場合、KERNEL_BASE は sys/arch/evbarm/include/vmparam.h でデフォルトでは
0x80000000 に定義されています。上記のようにこれを 0xC0000000 に変えたい場合は、
#define KERNEL_BASE_EXT 0xC0000000 すると、
=== sys/arch/evbarm/include/vmparam.h === /* * The line between user space and kernel space * Mappings >= KERNEL_BASE are constant across all processes */ #ifdef KERNEL_BASE_EXT #define KERNEL_BASE KERNEL_BASE_EXT #else #define KERNEL_BASE 0x80000000 #endif
のように定義されなおすわけです。
2014-02-20 cvsの闇
T#は時間。T1<T2<T3<T4<T5。
CASE1
T1 cvs import 1.1 1.1.1.1 T2 cvs import 1.1.1.2 T3 cvs import 1.1.1.3
だった場合、maintrunk で cvs update -DT3 とすると、1.1.1.3 が checkout される。(普通)
CASE2
T1 cvs import 1.1 1.1.1.1 T2 cvs import 1.1.1.2 T3 cvs commit 1.2 T4 cvs import 1.1.1.3
だった場合、cvs update -DT4 とすると、1.2 が checkout される。(いわゆるimport branchに対するmaintrunkの上書き)
さて、CASE1と似ているが、1.1を最初にcommitしてあった状態からimportした場合がCASE3。
CASE3
T1 cvs commit 1.1 T2 cvs import 1.1.1.1 T3 cvs import 1.1.1.2 T4 cvs import 1.1.1.3
この場合は、cvs update -DT4 とすると、1.1 が checkout される。
CASE1とCASE3は1.1と1.1.1.1のタイムスタンプしか違わなくて、実際これを見ている様子。
(rcsfileのtimestampを直接書換えたらCASE1になった)
さて、それではCASE3の状態から cvs admin -o 1.1.1.1 するとどうなるでしょう…
CASE4
T1 cvs commit 1.1 T3 cvs import 1.1.1.2 T4 cvs import 1.1.1.3
ここでcvs update -DTT4すると、1.1ではなく1.1.1.3 がcheckoutされた…。
cvsよくわからないです><
ということを調べながらcvs2gitツールを作っている今日この頃でした。
2013-07-24 raidframeチューニングふたたび
3T×5を買ってきてNetBSDのraidframeでRAID5を組んだのでメモっておく。NetBSD 6.99.22/amd64。
いつもハマるのがraid.confのSectPerSuの値とnewfsのblock-size/fragment-size。
ちょっと変えるだけで劇的に速度が変わるとか罠杉だろう。
SectPerSU は raid0.conf の↓の値。
2T overなので gpt を使う。gpt add -b 64 -s 5860533068 -t raid wd2 〜 wd6 とかやって、4k alignment にちゃんと合わせておく。
あとは上記SectPerSUの値とnewfsのblock-sizeとfragment-sizeを決める。
以前raidframeにした時は手作業で試してたのだが、さすがにアレなのでscript作ってブン回す。
以下、newfs、dd、tarで展開、rm、sync、tarで展開にかかった合計の秒数。
…raidのblocksize以下になると遅くなるのは当然だが、それでもいまいち傾向がよくわからない。
あまり深く考えるのはやめて、一番速かった SectPerSU=16、newfs -b 64k -f 32k で使うことにしよう。
1ファイル平均16kb無駄になるんで、うちの環境の場合11Tのうち0.5Tくらい無駄になる予感。
いつもハマるのがraid.confのSectPerSuの値とnewfsのblock-size/fragment-size。
ちょっと変えるだけで劇的に速度が変わるとか罠杉だろう。
SectPerSU は raid0.conf の↓の値。
START layout 16 1 1 5
2T overなので gpt を使う。gpt add -b 64 -s 5860533068 -t raid wd2 〜 wd6 とかやって、4k alignment にちゃんと合わせておく。
あとは上記SectPerSUの値とnewfsのblock-sizeとfragment-sizeを決める。
以前raidframeにした時は手作業で試してたのだが、さすがにアレなのでscript作ってブン回す。
以下、newfs、dd、tarで展開、rm、sync、tarで展開にかかった合計の秒数。
SectPerSU=16 -f 2k 4k 8k 16k 32k 64k --------------- --------------- ------- ------- ------- ------- -------- newfs -b 16k 1116 1036 922 1024 newfs -b 32k 296 257 297 100 newfs -b 64k 268 280 89 114
SectPerSU=32 -f 2k 4k 8k 16k 32k 64k --------------- --------------- ------- ------- ------- ------- -------- newfs -b 16k 905 735 686 452 newfs -b 32k 473 307 293 331 newfs -b 64k 670 406 433 559
SectPerSU=64 -f 2k 4k 8k 16k 32k 64k --------------- --------------- ------- ------- ------- ------- -------- newfs -b 16k 1010 671 542 509 newfs -b 32k 505 411 369 353 newfs -b 64k 456 337 303 353
SectPerSU=128 -f 2k 4k 8k 16k 32k 64k --------------- --------------- ------- ------- ------- ------- -------- newfs -b 16k 961 626 509 417 newfs -b 32k 514 376 395 309 newfs -b 64k 465 395 349 404
…raidのblocksize以下になると遅くなるのは当然だが、それでもいまいち傾向がよくわからない。
あまり深く考えるのはやめて、一番速かった SectPerSU=16、newfs -b 64k -f 32k で使うことにしよう。
1ファイル平均16kb無駄になるんで、うちの環境の場合11Tのうち0.5Tくらい無駄になる予感。
2013-06-18 NITROGEN6X
ずっと放置してたNITROGEN6Xをさわりだす。
以前はしもとさんからもらったパッチをあてて適当に修正したら a9_start() までは来た。
「@」が a9_start() の先頭付近にある XPUTC(#64) によるもので、とりあえずここで止まった。
XPUTC(#65) (「A」が出力されるはず…)にも来てないということは armv7_icache_inv_all が動いてないのか。謎。
U-Boot 2009.08-00495-g10adc6d (Apr 24 2012 - 13:27:04) CPU: Freescale i.MX 6 family 0.0V at 792 MHz Temperature: can't get valid data! mx6q pll1: 792MHz mx6q pll2: 528MHz mx6q pll3: 480MHz mx6q pll8: 50MHz ipg clock : 66000000Hz ipg per clock : 66000000Hz uart clock : 80000000Hz cspi clock : 60000000Hz ahb clock : 132000000Hz axi clock : 264000000Hz emi_slow clock: 29333333Hz ddr clock : 528000000Hz usdhc1 clock : 200000000Hz usdhc2 clock : 200000000Hz usdhc3 clock : 200000000Hz usdhc4 clock : 200000000Hz nfc clock : 24000000Hz Board: MX6Q-SABRELITE:[ POR] Boot Device: I2C I2C: ready DRAM: 1 GB MMC: FSL_USDHC: 0,FSL_USDHC: 1 JEDEC ID: 0xbf:0x25:0x41 Reading SPI NOR flash 0xc0000 [0x2000 bytes] -> ram 0x276009b8 SUCCESS In: serial Out: serial Err: serial Checking for recovery command file... ** Bad partition 6 ** Card did not respond to voltage select! ** Bad partition 6 ** MMC Device 2 not found MMC Device 2 not found ** Block device MMC 2 not supported Net: got MAC address from IIM: 00:19:b8:**:**:** FEC0 [PRIME] MX6Q SABRELITE U-Boot > printenv bootdelay=3 baudrate=115200 ipaddr=192.168.1.103 serverip=192.168.1.101 netmask=255.255.255.0 loadaddr=0x10800000 rd_loadaddr=0x11000000 netdev=eth0 ethprime=FEC0 bootargs_base=setenv bootargs console=ttymxc1,115200 video=mxcfb0:dev=ldb,LDB-XGA,if=RGB666 video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24 bootargs_nfs=setenv bootargs ${bootargs} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp rw rootwait enable_wait_mode=off bootcmd_net=dhcp && run bootargs_base bootargs_nfs && bootm bootargs_mmc=setenv bootargs ${bootargs} root=/dev/mmcblk0p1 rootwait rw bootcmd_mmc=for disk in 0 1 ; do mmc dev ${disk} ;for fs in fat ext2 ; do ${fs}load mmc ${disk}:1 10008000 /6q_bootscript && source 10008000 ; done ; done clearenv=sf probe 1 && sf erase 0xc0000 0x2000 && echo restored environment to factory default upgradeu=for disk in 0 1 ; do mmc dev ${disk} ;for fs in fat ext2 ; do ${fs}load mmc ${disk}:1 10008000 /6q_upgrade && source 10008000 ; done ; done bootfile=uImage nfsroot=/your/nfs/dir bootcmd=run bootcmd_mmc ethact=FEC0 stdin=serial stdout=serial stderr=serial MX6Q SABRELITE U-Boot > tftpboot netbsd.bin Found phy at 6 FEC: Link is Up 796d Using FEC0 device TFTP from server 10.0.0.1; our IP address is 10.0.0.2 Filename 'n'. Load address: 0x10800000 Loading: ################################################################# ################################################################# ############################## done Bytes transferred = 2340672 (23b740 hex) MX6Q SABRELITE U-Boot > go 10800000 ## Starting application at 0x10800000 ... @
以前はしもとさんからもらったパッチをあてて適当に修正したら a9_start() までは来た。
「@」が a9_start() の先頭付近にある XPUTC(#64) によるもので、とりあえずここで止まった。
XPUTC(#65) (「A」が出力されるはず…)にも来てないということは armv7_icache_inv_all が動いてないのか。謎。
2013-04-26 PenguinDrum
2013-04-10 EdgeRouterLite

U-Boot 1.1.1 (UBNT Build ID: 4493936-g009d77b) (Build time: Sep 20 2012 - 15:48:51) BIST check passed. UBNT_E100 r1:2, r2:12, serial #: DC9FDB29ABD5 Core clock: 500 MHz, DDR clock: 266 MHz (532 Mhz data rate) DRAM: 512 MB Clearing DRAM....... done Flash: 4 MB Net: octeth0, octeth1, octeth2 USB: (port 0) scanning bus for devices... 1 USB Devices found scanning bus for storage devices... Device 0: Vendor: Prod.: USB DISK 2.0 Rev: PMAP Type: Removable Hard Disk Capacity: 3700.6 MB = 3.6 GB (7579008 x 512) 0 Octeon ubnt_e100# help ? - alias for 'help' askenv - get environment variables from stdin autoscr - run script from memory base - print or set address offset bootelf - Boot from an ELF image in memory bootloaderupdate - Update the bootloader in flash bootloadervalidate - Validate the bootloader image bootoct - Boot from an Octeon Executive ELF image in memory bootoctelf - Boot a generic ELF image in memory. NOTE: This command does not support simple executive applications, use bootoct for those. bootoctlinux - Boot from a linux ELF image in memory cmp - memory compare coninfo - print console devices and informations cp - memory copy crc32 - checksum calculation dhcp - invoke DHCP client to obtain IP/boot params echo - echo args to console erase - erase FLASH memory ext2load- load binary file from a Ext2 filesystem ext2ls - list files in a directory (default /) fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatloadalloc - load binary file from a dos filesystem, and allocate a named bootmem block for file data fatls - list files in a directory (default /) flinfo - print FLASH memory information freeprint - Print list of free bootmem blocks go - start application at address 'addr' gunzip - Uncompress an in memory gzipped file help - print online help itest - return true/false on integer compare loadb - load binary file over serial line (kermit mode) loop - infinite loop on address range md - memory display md5 - MD5 hash calculation mii - MII utility commands mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) namedalloc - Allocate a named bootmem block namedfree - Free a named bootmem block namedprint - Print list of named bootmem blocks nm - memory modify (constant address) ping - send ICMP ECHO_REQUEST to network host printenv- print environment variables protect - enable or disable FLASH write protection read64 - read 64 bit word from 64 bit address read64b - read 8 bit word from 64 bit address read64l - read 32 bit word from 64 bit address read64s - read 16 bit word from 64 bit address read_cmp - read and compare memory to val reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage setenv - set environment variables sleep - delay execution for some time tftpboot- boot image via network using TFTP protocol ubntw - ubntw commands usb - USB sub-system version - print monitor version write64 - write 64 bit word to 64 bit address write64b - write 8 bit word to 64 bit address write64l - write 32 bit word to 64 bit address write64s - write 16 bit word to 64 bit address Octeon ubnt_e100# printenv bootcmd=fatload usb 0 $loadaddr vmlinux.64;bootoctlinux $loadaddr coremask=0x3 root=/dev/sda2 rootdelay=15 rw rootsqimg=squashfs.img rootsqwdir=w mtdparts=phys_mapped_flash:512k(boot0),512k(boot1),64k@3072k(eeprom) bootdelay=0 baudrate=115200 download_baudrate=115200 nuke_env=protect off $(env_addr) +$(env_size);erase $(env_addr) +$(env_size) autoload=n ethact=octeth0 loadaddr=0x9f00000 numcores=2 stdin=serial stdout=serial stderr=serial env_addr=0x1fbfe000 env_size=0x2000 flash_base_addr=0x1f800000 flash_size=0x400000 uboot_flash_addr=0x1f880000 uboot_flash_size=0x70000 flash_unused_addr=0x1f8f0000 flash_unused_size=0x310000 bootloader_flash_update=bootloaderupdate Environment size: 675/8188 bytes
ちなみにBigEndianでした。(ubootから適当なアドレスに何か値をwrite64してmd.bすればすぐわかる)
NetBSDのmips64/octeon対応状況は、mips64コア自体はok、octeon SoCはまだ、のままなのかな。
octeon自体はOpenBSD,FreeBSDに入っている。
OpenBSDはしゅうう先生ががんばってsgiとIIJのSEILからもってきたのがベース、FreeBSDはCavium Network由来のがベースになっている、と…
2012-07-25 kobo
koboを買ってきたので、(電源入れる前に)バラしてシリアルを付けた。TXやRXのシルクは大いなる罠で、USBコネクタ側にあるシルク印刷の無い4つのランドがUART1(console=ttymxc0)でした。騙された!
シリアルのスピードは115200bps。

U-Boot 2009.08-dirty-svn (12 13 2011 - 16:52:29) CPU: Freescale i.MX50 family 1.1V at 800 MHz mx50 pll1: 800MHz mx50 pll2: 400MHz mx50 pll3: 216MHz ipg clock : 66666666Hz ipg per clock : 66666666Hz uart clock : 24000000Hz ahb clock : 133333333Hz axi_a clock : 400000000Hz axi_b clock : 200000000Hz weim_clock : 100000000Hz ddr clock : 200000000Hz esdhc1 clock : 80000000Hz esdhc2 clock : 80000000Hz esdhc3 clock : 80000000Hz esdhc4 clock : 80000000Hz Board: MX50 RDP board Boot Reason: [POR] Boot Device: SD I2C: ready DRAM: 256 MB MMC: FSL_ESDHC: 0, FSL_ESDHC: 1 In: serial Out: serial Err: serial MMC read: dev # 0, block # 1023, count 1 partition # 0 ... 1 blocks read: OK MMC read: dev # 0, block # 1024, count 1 partition # 0 ... 1 blocks read: OK [only 1 key] 0 keys,0x00,0x00 0 keys,0x00,0x00 0 keys,0x00,0x00 0 keys,0x00,0x00 ram p=70000000,size=268435456 MMC read: dev # 0, block # 1023, count 1 partition # 0 ... 1 blocks read: OK MMC read: dev # 0, block # 1024, count 1 partition # 0 ... 1 blocks read: OK MMC read: dev # 0, block # 18431, count 1 partition # 0 ... 1 blocks read: OK MMC read: dev # 0, block # 14335, count 1 partition # 0 ... 1 blocks read: OK MMC read: dev # 0, block # 14336, count 1979 partition # 0 ... 1979 blocks read: OK Kernel RAM visiable size=255M->255M Hit any key to stop autoboot: 0 MMC read: dev # 0, block # 2047, count 1 partition # 0 ... 1 blocks read: OK cmd=mmc read 0 0x778205a0 0x7ff 0x1 no kernel image signature ! cmd=mmc read 0 0x70800000 0x800 0x1800 MMC read: dev # 0, block # 2048, count 6144 partition # 0 ... 6144 blocks read: OK ## Booting kernel from Legacy Image at 70800000 ... Image Name: Linux-2.6.35.3-850-gbc67621+ Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1904568 Bytes = 1.8 MB Load Address: 70008000 Entry Point: 70008000 Loading Kernel Image ... OK OK Starting kernel ... Uncompressing Linux... done, booting the kernel. epdc_init_sequence(994) : epd_power_on request fail ! 1+0 records in 1+0 records out 512 bytes (512B) copied, 0.002489 seconds, 200.9KB/s cannot open /dev/null dosfsck 3.0.6, 04 Oct 2009, FAT32, LFN /dev/mmcblk0p3: 110 files, 1262/348630 clusters FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive! (none) login: ApplicationBase::switchTranslator::loading locale: ":/translations/trans_en_US" Translator is empty! Do you have translation files for this locale? sh: you need to specify whom to kill sh: you need to specify whom to kill sh: you need to specify whom to kill sh: you need to specify whom to kill sh: you need to specify whom to kill > WebSyncScheduler: scheduleTimer: No need to schedule a sync > Warning: You haven't called pageView yet: "5(Settings*Set%20View%20Type*List)" > FSCheckThread: dbMalformed: false fsCorrupted: false sh: you need to specify whom to kill sh: you need to specify whom to kill sh: you need to specify whom to kill sh: you need to specify whom to kill (none) login: root login[727]: root login on 'ttymxc0' [root@(none) /]# ApplicationBase::switchTranslator::loading locale: ":/translations/trans_en_US" Translator is empty! Do you have translation files for this locale? [root@(none) /]# [root@(none) /]# [root@(none) /]# ps PID USER TIME COMMAND 1 root 0:00 init 2 root 0:00 [kthreadd] 3 root 0:00 [ksoftirqd/0] 4 root 0:00 [events/0] 5 root 0:00 [khelper] 8 root 0:00 [async/mgr] 9 root 0:00 [pm] 63 root 0:00 [usb_wakeup thre] 64 root 0:00 [usb_wakeup thre] 112 root 0:00 [sync_supers] 114 root 0:00 [bdi-default] 116 root 0:00 [kblockd/0] 128 root 0:00 [mxc_spi.2] 136 root 0:00 [khubd] 153 root 0:00 [kmmcd] 210 root 0:00 [swapper] 214 root 0:00 [zq_calib] 220 root 0:00 [kswapd0] 267 root 0:00 [aio/0] 277 root 0:00 [crypto/0] 369 root 0:00 [kapmd] 415 root 0:00 [kconservative/0] 418 root 0:00 [mxc_chg] 420 root 0:00 [pmic_battery.1] 425 root 0:00 [esdhc_wq/0] 428 root 0:00 [esdhc_wq/0] 430 root 0:00 [esdhc_wq/0] 445 root 0:00 [submit/0] 450 root 0:00 [mmcqd] 456 root 0:00 [jbd2/mmcblk0p1-] 457 root 0:00 [ext4-dio-unwrit] 460 root 0:00 [flush-179:0] 474 root 0:00 /sbin/udevd -d 714 root 0:00 /bin/sh /etc/init.d/on-animator.sh 717 root 0:00 [submit/0] 725 root 0:01 /usr/local/Kobo/nickel -qws 727 root 0:00 -sh 763 root 0:00 zcat /etc/images/on-1.raw.gz 764 root 0:00 /usr/local/Kobo/pickel showpic 1 766 root 0:00 ps 768 root 0:00 [dd] [root@(none) /]#
放置してると10〜20秒くらい(?)でsleepに入ってしまうので、rootで入ってpsして
/usr/local/Kobo/nickel -qws をkillしてやるとそのまま使える。linuxさわる場合はどうぞ。
で、肝心のubootだが、uboot promptに落ちることができなかった。キー入力してもautobootが止まらない。
^CやESCやその他もろもろを押しっぱなしにしてもダメだった。
色々試すべくリセットスイッチ(=基板実装面のUSBコネクタの近くにあるタクトスイッチ)を押しまくってたら、
SDカードが壊れたのかlinux kernelがbootしなくなった。
Starting kernel ... Uncompressing Linux... done, booting the kernel. epdc_init_sequence(994) : epd_power_on request fail ! Kernel panic - not syncing: No init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance. [<800294ac>] (unwind_backtrace+0x0/0xf0) from [<80290e00>] (panic+0x6c/0xe0) [<80290e00>] (panic+0x6c/0xe0) from [<80024588>] (init_post+0xac/0xd4) [<80024588>] (init_post+0xac/0xd4) from [<800084a4>] (kernel_init+0x124/0x168) [<800084a4>] (kernel_init+0x124/0x168) from [<800259c0>] (kernel_thread_exit+0x0/0x8)
ガーン。
しかしどうやらkoboはMX50のSDHC bootモードでSDCardからubootを実行してるようだ。SDカードを抜くとubootさえ起動しなかった。
http://github.com/kobolabs/Kobo-Reader にあるu-bootを自分で作りなおしてSDカードに書けばいくらでもいじくれる様子。flashメモリじゃないということは文鎮の恐れもないし! これはもう買うしかないんじゃね?(シルシル風に)
さっそくはしもとさんがオレオレu-bootで立ち上げてた様子。https://twitter.com/h_kenken/status/228446056084537345
ちなみにi.MX50xのデータシートはこちら。NetWalkerとメモリマップが違うけどデバイスの一つ一つはだいたい一緒。
2012-07-11 NetBSD on さくらVPS
いろいろハマったけどなんとか入ったのでメモっておく。
神戸さんのこのページ http://www.back-street.net/netbsd-sakura-vps3.html を参考にしたのだが、さくらVPSの仕様が変わったのか、
BIOSbootからカーネルが読めなくなっていた。しょうがないのでgrubからNetBSDをbootする方式でちょっと強引にインストールすることにする。
デフォルトのCentOS 6はgpt+ext4という構成で、いろいろ面倒なので、CentOS 5を選んで、一旦普通にインストールする。
CentOS5はfdisk+ext3なので、NetBSDからも簡単に見えるのである。
やろうとしていることは以下の通り。
さくらVPSでCentOS5のインストール直後
これを↓のようにするのが目的
最終的にGRUBからnetbsdをbootさせて使う。
*** How to install ***
さくらVPS用(KVM用)にpatchを当てたNetBSD一式(releaseおよびinstall-image)を作る。
神戸さんのこのページを参照。http://www.back-street.net/netbsd-sakura-vps3.html
パッチを当てた状態で、
として、netbsd-INSTALL.gz と netbsd-GENERIC.gz を作る。
Linuxから、/boot/grub/grub.conf を編集して以下の行を追加。上で作った netbsd-*.gz を /boot にコピーしておく。
あとは GRUBから NetBSD-install で立ち上げて、fdisk管理テーブルやMBR領域を壊さないようにfdisk partition 1のLinux領域をNetBSDで上書きするようにインストールするだけ。
楽ちん。
インストールが終わったら、fdisk[0] のgrub領域をmount_ext2fsでmountして、新しいkernelを置いてgrubからboot。ちょっとめんどくさいけど、とくに問題なし。
神戸さんのこのページ http://www.back-street.net/netbsd-sakura-vps3.html を参考にしたのだが、さくらVPSの仕様が変わったのか、
BIOSbootからカーネルが読めなくなっていた。しょうがないのでgrubからNetBSDをbootする方式でちょっと強引にインストールすることにする。
デフォルトのCentOS 6はgpt+ext4という構成で、いろいろ面倒なので、CentOS 5を選んで、一旦普通にインストールする。
CentOS5はfdisk+ext3なので、NetBSDからも簡単に見えるのである。
やろうとしていることは以下の通り。
さくらVPSでCentOS5のインストール直後
[HD] [fdisk] 0 GRUB(20Mbyteくらい。ext3) 1 Linux(残りの領域。Linux本体。ext3) 2 unused 3 unused
これを↓のようにするのが目的
[HD] [fdisk] 0 GRUB(20Mくらい。ext3) 1 NetBSD 2 unused 3 unused
最終的にGRUBからnetbsdをbootさせて使う。
*** How to install ***
さくらVPS用(KVM用)にpatchを当てたNetBSD一式(releaseおよびinstall-image)を作る。
神戸さんのこのページを参照。http://www.back-street.net/netbsd-sakura-vps3.html
パッチを当てた状態で、
./build.sh -U -m i386 -T ~/work/i386/tools -D ~/work/i386/tree -O ~/work/i386/obj -R ~/work/release release ./build.sh -U -m i386 -T ~/work/i386/tools -D ~/work/i386/tree -O ~/work/i386/obj -R ~/work/release install-image
として、netbsd-INSTALL.gz と netbsd-GENERIC.gz を作る。
Linuxから、/boot/grub/grub.conf を編集して以下の行を追加。上で作った netbsd-*.gz を /boot にコピーしておく。
title NetBSD-install kernel /netbsd-INSTALL.gz console=com console_speed=115200 title NetBSD-GENERIC kernel /netbsd-GENERIC.gz console=com console_speed=115200 title NetBSD kernel /netbsd console=com console_speed=115200 root=ld
あとは GRUBから NetBSD-install で立ち上げて、fdisk管理テーブルやMBR領域を壊さないようにfdisk partition 1のLinux領域をNetBSDで上書きするようにインストールするだけ。
楽ちん。
インストールが終わったら、fdisk[0] のgrub領域をmount_ext2fsでmountして、新しいkernelを置いてgrubからboot。ちょっとめんどくさいけど、とくに問題なし。
2012-03-16 Aterm WM3600R
分解したけどあんま面白くなかった。あわよくばシリアル出力見れるかなーと思ったんだけど1mgを削る世界(?)は甘くありませんでした。





シールド開けてみたいけどライフラインで調子悪くなると嫌なのでなのでやりません :-P
2011-10-12 NetBSD/FON2405E #2
というわけで、いつのまにやらNetBSD本家にRT3050対応のコードが入っていたので、bootさせてみる…が、何も考えてないのでダメだった。
もう一台FON2405Eをゲットしたので、秋月のFT232RLをハンダ付けして、シリアル出した状態にして沖さんに投棄。
並行して、以前沖さんが作ってくれたRT3052対応のpatchあてて、options CONSPEED=57600 を追加したら、見事bootしたー。
ohci0のattachで固まったけど、ここまで動いてしまえばすぐに追えるだろう。マズマズだな。
NetBSD使いのみんなも
U-Boot 1.1.3 (Jan 6 2010 - 07:10:30) RT3052 # tftp 80010000 netbsd.bin netboot_common, argc= 3 NetTxPacket = 0x81FE4DC0 Trying Eth0 (10/100-M) ETH_STATE_ACTIVE!! Using Eth0 (10/100-M) device TFTP from server 10.10.10.3; our IP address is 10.10.10.200 Filename 'netbsd.bin'. TIMEOUT_COUNT=10,Load address: 0x80010000 Loading: Got ARP REPLY, set server/gtwy eth addr (00:02:2a:dd:58:24) Got it T # first block received ################################################################ ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ############# done Bytes transferred = 3059056 (2ead70 hex) NetBootFileXferSize= 002ead70 RT3052 # go 80010000 ## Starting application at 0x80010000 ... Enabled early console pmap_steal_memory: seg 0: 0x3 0x3 0x10 0x10 pmap_steal_memory: seg 0: too small for 142 pages pmap_steal_memory: seg 1: 0x339 0x339 0x1fff 0x1fff Loaded initial symtab at 0x80288610, strtab at 0x802b11cc, # entries 9799 Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The NetBSD Foundation, Inc. All rights reserved. Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of California. All rights reserved. NetBSD 5.99.56 (RT3050) #0: Wed Oct 12 21:01:51 JST 2011 ryo@moveq:/src/cvs/NetBSD/sys/arch/evbmips/compile/RT3050 total memory = 32768 KB avail memory = 28856 KB mainbus0 (root): Ralink System Bus cpu0 at mainbus0: 320.00MHz (hz cycles = 1600000, delay divisor = 160) cpu0: MIPS 24KE (0x1964c) Rev. 76 with software emulated floating point cpu0: 32 TLB entries, 256MB max page size cpu0: 32KB/32B 4-way set-associative L1 instruction cache cpu0: 16KB/32B 4-way set-associative write-back L1 data cache rwdog0 at mainbus0: Ralink watchdog controller rwdog0: max period 40 sec. rwdog0: KTICKLE mode, period -30 sec. rgpio0 at mainbus0: Ralink GPIO controller gpio0 at rgpio0: 98 pins ri2c0 at mainbus0: Ralink I2C controller iic0 at ri2c0: I2C bus com0 at mainbus0: Au1X00 UART, working fifo com0: console ohci0 at mainbus0: OHCI USB controller ohci0:
2011-09-29 CTIO
クティオのスペルはctioと書くようだ。

ピン配置は写真左から、VCC,RX,GND,TX。38400bps。
とりあえずシリアルは取れたが、Ether生えてないんだよなぁ。どうしよう。kermitやらs-recordでserial経由で送れるっぽいのでなんとかなるか。
U-Boot 1.1.4 (Jan 23 2009 - 12:09:13) U-Boot code: 00000000 -> 0001A50C BSS: -> 0001F45C CPU Clock: 200 MHz 1.8V Vdd Output: 1.793 2.5V Vdd Output: 2.531 RAM Configuration: Bank #0: 00000000 32 MB Flash Manufacturer: EON Flash Device: MXLV640BB(8MB) Flash: 8 MB In: serial Out: serial Err: serial Hit any key to stop autoboot: 0 Star Dorado2 # ? ? - alias for 'help' autoscr - run script from memory base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console erase - erase FLASH memory flinfo - print FLASH memory information go - start application at address 'addr' help - print online help iminfo - print header information for application image imls - list all images found in flash itest - return true/false on integer compare loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv- print environment variables protect - enable or disable FLASH write protection rarpboot- boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage setenv - set environment variables sleep - delay execution for some time tftpboot- boot image via network using TFTP protocol version - print monitor version Star Dorado2 # version U-Boot 1.1.4 (Jan 23 2009 - 12:09:13) Star Dorado2 # bdinfo arch_number = 0x0000038E env_t = 0x00000000 boot_params = 0x00000100 DRAM bank = 0x00000000 -> start = 0x00000000 -> size = 0x02000000 ethaddr = 00:0A:0B:0C:0D:10 ip_addr = 192.168.0.1 baudrate = 38400 bps Star Dorado2 # printenv bootargs=/dev/mtdblock3 ro cpufreq=200M rootfstype=squashfs console=ttyS0,38400 bootcmd=go 0x10040000 bootdelay=3 baudrate=38400 ethaddr=00:0a:0b:0c:0d:10 ipaddr=192.168.0.1 serverip=192.168.0.100 netmask=255.255.255.0 stdin=serial stdout=serial stderr=serial Environment size: 261/65532 bytes Star Dorado2 # pci Scanning PCI devices on bus 0 BusDevFun VendorId DeviceId Device Class Sub-Class _____________________________________________________________ 00.00.00 0xeeee 0x0000 Does not fit any class 0x00 Star Dorado2 # iminfo ## Checking Image at 00100000 ... Bad Magic Number Star Dorado2 # flinfo Bank # 1: EON MX29LV640BB (64Mbit) Size: 8 MB in 135 Sectors Sector Start Addresses: 10000000 (RO) 10002000 (RO) 10004000 (RO) 10006000 (RO) 10008000 (RO) 1000A000 (RO) 1000C000 (RO) 1000E000 (RO) 10010000 (RO) 10020000 (RO) 10030000 10040000 10050000 10060000 10070000 10080000 10090000 100A0000 100B0000 100C0000 100D0000 100E0000 100F0000 10100000 10110000 10120000 10130000 10140000 10150000 10160000 10170000 10180000 10190000 101A0000 101B0000 101C0000 101D0000 101E0000 101F0000 10200000 10210000 10220000 10230000 10240000 10250000 10260000 10270000 10280000 10290000 102A0000 102B0000 102C0000 102D0000 102E0000 102F0000 10300000 10310000 10320000 10330000 10340000 10350000 10360000 10370000 10380000 10390000 103A0000 103B0000 103C0000 103D0000 103E0000 103F0000 10400000 10410000 10420000 10430000 10440000 10450000 10460000 10470000 10480000 10490000 104A0000 104B0000 104C0000 104D0000 104E0000 104F0000 10500000 10510000 10520000 10530000 10540000 10550000 10560000 10570000 10580000 10590000 105A0000 105B0000 105C0000 105D0000 105E0000 105F0000 10600000 10610000 10620000 10630000 10640000 10650000 10660000 10670000 10680000 10690000 106A0000 106B0000 106C0000 106D0000 106E0000 106F0000 10700000 10710000 10720000 10730000 10740000 10750000 10760000 10770000 10780000 10790000 107A0000 107B0000 107C0000 107D0000 107E0000 107F0000 Star Dorado2 # coninfo List of available devices: serial 80000003 SIO stdin stdout stderr Star Dorado2 #
EOF