APC8750にNetBSD/evbarmを移植するための記録 3/25 ~ 3/31
■3/25
NetBSDカーネルを読み込ませるにはu-bootを使わねば、ということでu-bootで何ができるか調べる。helpと入力するとコマンド一覧が表示される。
WMT # help
? - 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
dhcp - invoke DHCP client to obtain IP/boot params
diskboot- boot from IDE device
show -
dmacp - dma memory copy
echo - echo args to console
erase - erase FLASH memory
exit - exit script
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
fatstore - store binary file to a dos filesystem
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print online help
icrc32 - checksum calculation
ide - IDE sub-system
iloop - infinite loop on address range
imd - i2c memory display
iminfo - print header information for application image
imls - list all images found in flash
imm - i2c memory modify (auto-incrementing)
ims - set i2c device context from memory
imw - memory write (fill)
inm - memory modify (constant address)
iprobe - probe to discover valid I2C chip addresses
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
memory bit operation :
Format : mbit <parameter>
md - memory display
mii - MII utility commands
mm - memory modify (auto-incrementing)
mmcinit - init mmc card
mmcinit 0 -- init mmc device 0
mmcinit 1 -- init mmc device 1
mmcinit 2 -- init mmc device 2
mmcread - read data from SD/MMC card
<dev_id> <addr> <block_num> <bytes>
-read data from SD/MMC card block address 'block_num' on 'dev_id'
to memory address 'addr' size is 'bytes'
mmcwrite - write data to SD/MMC card
<dev_id> <addr> <block_num> <bytes>
-write data to SD/MMC card block address 'block_num' on 'dev_id'
from memory address 'addr' size is 'bytes'
mtest - simple RAM test
mw - memory write (fill)
nandrw - NAND sub-system
nboot - boot from NAND device
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
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
sdwaitins - wait sd card inserted or removed
sdwaitins 0 -- waiting removed
sdwaitins 1 -- waiting inserted
setenv - set environment variables
sleep - delay execution for some time
test - minimal test like /bin/sh
textout - show text to the screen
textout x y "str" color
color is 24bit Hex, R[23:16], G[15:8], B[7:0]
for example: textout 0 0 "hello world" FFFFFF
tftpboot- boot image via network using TFTP protocol
usb - USB sub-system
usbboot - boot from USB device
version - print monitor version
WMT #
コマンドをGoogle検索をしているなかで、清水さんがFONにNetBSDを移植している日記を発見。u-bootのコマンドラインからmm.lでメモリに直接値を書き込む技を知る。これを応用すれば、シリアル出力をつかさどるアドレスにmm.lで値を書き込むことによって文字が表示される。
APCはどのアドレスに書けばよいのかLinuxのソースをあたったところ、UART0のアドレスが0xD8200000であることを知る。
(https://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/mach-wmt/include/mach/wmt_mmap.h#L149)
WMT # mm.l d8200000 d8200000: 0000003a ? 40 @d8200004: 0000000d ? .この場合、40という値を書き込むことで、シリアルからASCIIコードの@が出力されている。これでシリアルへの出力はできそうだ。
次はカーネルをどう読ませるかだが、u-bootにtftpbootがある。help tftpbootで使い方が出る。
WMT # help tftpboot tftpboot [loadAddress] [bootfilename]それはよいのだが、どこからファイルを持ってくるのかわからない。が、検索すれば何でも出てくる時代、tftpサーバの指定方法がset serverip [IPアドレス]で可能であることを知る。
とりあえず、TFTPを使ってカーネルをロードし、goコマンドでNetBSDカーネルが実行できそうだ。ということで、RPiをコピーして、色々削りまくって、カーネルがリンクできるところまでやっつける。
最初に実行されるのは、apc_start.Sなので、そこでmm.lと同様のことをすれば文字は出る。
と、evbarm/netwalker/netwalker_start.Sを見るとアセンブラで書かれた文字出力ルーチン(print_r3)があるではないか。シリアルのアドレスをちょっと調整すると動くようになった。アセンブリ言語音痴の自分にとってはよいお手本になった。armadillo_start.Sにもprint_r3がある。こっちが先かな?
print_r3を見るとステータスレジスタを確認して、出力してよい、というビットが立つまで待つ処理がある。mm.lコマンドで一文字出す分には気にする必要はないが、シリアルにたくさんの文字を文字を出力する際には必要なのだろう。
同じことをするためにはシリアルのステータスレジスタの情報が必要で、これらは、kernel/arch/arm/mach-wmt/include/mach/wmt_uart.h
に書かれている。ステータスレジスタは#define UART0_URUSR_ADDRで定義されており、
TXがビジーかどうか確認するのは#define URUSR_TXDBSYで定義されている。
putc_r0:
stmfd sp!, {r0, r1, r2, lr}
ldr r1, Luart0adr
1: /* wait */
ldr r2, [r1, #0x1c] /* load status register */
tst r2, #0x2 /* TX busy? (r2 & 0x0002) if busy then Z=0*/
bne 1b /* if(Z==0) goto 1b */
/* output */
strb r0, [r1, #0x00]
ldmfd sp!, {r0, r1, r2, pc}
■3/31
apc_start.Sのprint_r3を使ってどこまで進んだかを表示させつつデバッグを進める。例によって、MMUをonにするところから先に行けない。MMUをonにすると、デバッグ用のprint_r3が使えないため、何がどうなっているのかわからない。
いつもここで詰まってしまう。
コメント(0件)
- TB-URL http://www.tokuda.net/diary/0820/tb/