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/