APC8750にNetBSD/evbarmを移植するための記録 8/15
initarmをトライアンドエラーで動かそうと試みるも、うまく動かず、またまた諦めそうになる。
そもそも母体にしたのはNetBSD6系のソースだったので、気分転換に最新のソースを見てみました。すると、initarm_commonというinitarmで行う共通の処理をまとめた関数を使っていて、initarm本体はコンパクトに書かれていることに気づきました。
よくわからない自分があてずっぽうでいじるより、共通部分は任せてしまったほうが動きそうな気がするので、急きょ-currentでコンパイルできるように書き換えてしまいました。
すると、initarmでやることは対してなくなってしまい、最低限いじる部分はDRAMの容量とその開始アドレスぐらいになってしまいました。SDRAMがどこにあるのかはapc_start.Sでも悩んだのですが、とりあえず0x0から始めるようにしてしまっているので、ここでも0x0で始めることにしてしまいました。
すると、NetBSDのバナーまでたどり着くことができました!
その時の様子はhttp://www.tokuda.net/diary/0798に書いたとおりです。
そもそも母体にしたのはNetBSD6系のソースだったので、気分転換に最新のソースを見てみました。すると、initarm_commonというinitarmで行う共通の処理をまとめた関数を使っていて、initarm本体はコンパクトに書かれていることに気づきました。
よくわからない自分があてずっぽうでいじるより、共通部分は任せてしまったほうが動きそうな気がするので、急きょ-currentでコンパイルできるように書き換えてしまいました。
すると、initarmでやることは対してなくなってしまい、最低限いじる部分はDRAMの容量とその開始アドレスぐらいになってしまいました。SDRAMがどこにあるのかはapc_start.Sでも悩んだのですが、とりあえず0x0から始めるようにしてしまっているので、ここでも0x0で始めることにしてしまいました。
すると、NetBSDのバナーまでたどり着くことができました!
その時の様子はhttp://www.tokuda.net/diary/0798に書いたとおりです。
コメント(0件)
- TB-URL http://www.tokuda.net/diary/0823/tb/
APC8750にNetBSD/evbarmを移植するための記録 8/9
BeagleBone Blackを買って遊んだり、JNUG総会&BoFを欠席して懇親会だけ参加してみたり、納涼もんご祭りに遊びに行ったり、OSC京都でLuna見たり、そんなこんなで3か月ほど間が空きました。
さて、initarmまで来たら、次はprintfを動かすのが大きなマイルストンです。
そのための第一歩として、コンソールの初期化ルーチンであるconsinitを実装しなければなりません。
この時点でなぜかシリアルインタフェースが16550互換だと信じ込んでおり、evbarm/armの下にある16550関連のソースを読み比べて、シンプルなhdlg_machdep.cのconsinitをまねてcomドライバを呼ぶ処理を書いてみました。
そして...
NetBSD/evbarm (APC) booting ...からはprintfで出力されております。
printfが動いた感動を味わう。
さて、initarmまで来たら、次はprintfを動かすのが大きなマイルストンです。
そのための第一歩として、コンソールの初期化ルーチンであるconsinitを実装しなければなりません。
この時点でなぜかシリアルインタフェースが16550互換だと信じ込んでおり、evbarm/armの下にある16550関連のソースを読み比べて、シンプルなhdlg_machdep.cのconsinitをまねてcomドライバを呼ぶ処理を書いてみました。
そして...
U-Boot 1.1.4 (Dec 5 2012 - 19:23:59) WonderMedia Technologies, Inc. U-Boot Version : 0.28.00.00 U-Boot code: 03F80000 -> 03FCEE38 BSS: -> 03FF0A88 boot from spi flash. SF0: ManufID = C2, DeviceID = 2013 (Missing or Unknown FLASH) Use Default - Total size = 8MB, Sector size = 64KB SF1: ManufID = FF, DeviceID = FFFF (Missing or Unknown FLASH) Use Default - Total size = 8MB, Sector size = 64KB flash: Bank1: FF800000 -- FFFFFFFF Bank2: FF000000 -- FF7FFFFF Flash: 16 MB sfboot: NAND init:env nand config fail, use default flash id list info pllb=0x2270001, spec_clk=0x140a0cff T1=2, clk1=18, div1=9, Thold=1, tREA=20+delay(9) T2=1, clk2=36, div2=18, Thold2=1, comp=1 Tim1=442368 , Tim2=589824 T2 is greater and not use T=2, clk=18, divisor=9, Thold=0x601 divisor is set 0x9, NFC_timing=0x2424 USE_HW_ECC ECC12bit 2048 MB In: serial Out: serial Err: serial Abort WMT Display Logo Function WMT # WMT # WMT # WMT # WMT # set serverip 192.168.0.10 WMT # tftpboot 1000000 netbsd.bin EEP-less strapping = TRUE TFTP from server 192.168.0.10; our IP address is 192.168.0.2 Filename 'netbsd.bin'. Load address: 0x1000000 Loading: ####################################T ############################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################ done Bytes transferred = 2489792 (25fdc0 hex) WMT # go 1000000 ## Starting application at 0x01000000 ... 01000328 NetBSD 00000000 00000000 01473863 00000412 00000000 00000412 00000014 00000412 c0000000 00000000 01473863 0000041e 00003000 0000041e 00000014 0000041e fe000000 d8000000 010fffff 00000412 00003f80 d8000412 00000010 00000412 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 NetB1S NetBSD/evbarm (APC) booting ... initarm: Configuring system ... physmemory: 0 pages at 0x00000000 -> 0xffffffff Allocating page tables Creating L1 page table at 0x01274000 Mapping kernel pmap_map_chunk: pa=0x0 va=0xc0000000 size=0x119b000 resid=0x119b000 prot=0x3 cache=1 SSSSSSSSSSSSSSSSSLLLLLLLLLPPPPPPPPPPP pmap_map_chunk: pa=0x119b000 va=0xc119b000 size=0xd9000 resid=0xd9000 prot=0x3 cache=1 PPPPPLLLLLLLLLLLLLPPPP Constructing L2 page tables pmap_map_chunk: pa=0x1282000 va=0xc1282000 size=0x1000 resid=0x1000 prot=0x3 cache=1 P pmap_map_chunk: pa=0x1283000 va=0xc1283000 size=0x1000 resid=0x1000 prot=0x3 cache=1 P pmap_map_chunk: pa=0x1284000 va=0xc1284000 size=0x1000 resid=0x1000 prot=0x3 cache=1 P pmap_map_chunk: pa=0x1285000 va=0xc1285000 size=0x1000 resid=0x1000 prot=0x3 cache=1 P pmap_map_chunk: pa=0x1286000 va=0xc1286000 size=0x2000 resid=0x2000 prot=0x3 cache=1 PP pmap_map_chunk: pa=0x1274000 va=0xc1274000 size=0x4000 resid=0x4000 prot=0x3 cache=2 PPPP pmap_map_chunk: pa=0x1278000 va=0xc1278000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x1279000 va=0xc1279000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x127a000 va=0xc127a000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x127b000 va=0xc127b000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x127c000 va=0xc127c000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x127d000 va=0xc127d000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x127e000 va=0xc127e000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x127f000 va=0xc127f000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P pmap_map_chunk: pa=0x1280000 va=0xc1280000 size=0x1000 resid=0x1000 prot=0x3 cache=2 P devmap: d8000000 -> d8ffffff @ fe000000 pmap_map_chunk: pa=0xd8000000 va=0xfe000000 size=0x1000000 resid=0x1000000 prot=0x3 cache=0 SSSSSSSSSSSSSSSS Physical Virtual Num Starting Ending Starting Ending Pages SDRAM: 0x00000000 0xffffffff 0xc0000000 0xbfffffff 0 text section: 0x00000000 0x0119a473 0xc0000000 0xc119a473 4507 data section: 0x011a0000 0x0125fdc0 0xc11a0000 0xc125fdc0 192 bss section: 0x0125fdc0 0x01273864 0xc125fdc0 0xc1273864 21 L1 page directory: 0x01274000 0x01277fff 0xc1274000 0xc1277fff 4 Exception Vectors: 0x01281000 0x01281fff 0xffff0000 0xffff0fff 1 FIQ stack: 0x01282000 0x01282fff 0xc1282000 0xc1282fff 1 IRQ stack: 0x01283000 0x01283fff 0xc1283000 0xc1283fff 1 ABT stack: 0x01284000 0x01284fff 0xc1284000 0xc1284fff 1 UND stack: 0x01285000 0x01285fff 0xc1285000 0xc1285fff 1 SVC stack: 0x01286000 0x01287fff 0xc1286000 0xc1287fff 2 Message Buffer: 0x01288000 0x01288fff 1 Free Memory: 0x01289000 0xffffffff 0xc1289000 0xbfffffff 1043831 switching to new L1 page table @0x1274000...OK. freestart = 0x01289000, free_pages = 1043831 (0x000fed77) bootstrap done. init subsystems: stacks vectors undefined page panic: uvm_page_physload: start >= end Undefined instruction in kernel Stopped in pid 0.1 (system) at c100e5b8:うぉーっ、printfが動いた!
NetBSD/evbarm (APC) booting ...からはprintfで出力されております。
printfが動いた感動を味わう。
- TB-URL http://www.tokuda.net/diary/0822/tb/
APC8750にNetBSD/evbarmを移植するための記録 5/8
MMUをonにするところで挫折しては以前から何の進歩もないのでしぶとくデバッグを続けていたところ、デバッグルーチンがレジスタを上書きしていたのにやっと気づいた。
ついにapc_machdep.cのinitarmに飛び込んだ!
たった一文字アットマークが表示されるだけなのだけど、とても嬉しい。
やっぱり無精をせずにレジスタまで意識しながら読まないとダメなのだなぁと思い知らされました。
apc_start.Sでは0xD8200000つまり物理アドレス(PA)に値を書き込めばシリアルから出力されますが、apc_machdep.cでは仮想アドレス(VA)でアクセスする必要があるのですね。
initarmの冒頭で次のように書くとシリアルにアットマークが出力されます。
ついにapc_machdep.cのinitarmに飛び込んだ!
たった一文字アットマークが表示されるだけなのだけど、とても嬉しい。
やっぱり無精をせずにレジスタまで意識しながら読まないとダメなのだなぁと思い知らされました。
apc_start.Sでは0xD8200000つまり物理アドレス(PA)に値を書き込めばシリアルから出力されますが、apc_machdep.cでは仮想アドレス(VA)でアクセスする必要があるのですね。
initarmの冒頭で次のように書くとシリアルにアットマークが出力されます。
*(volatile int *)0xfe200000 = 0x40;
- TB-URL http://www.tokuda.net/diary/0821/tb/
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が使えないため、何がどうなっているのかわからない。
いつもここで詰まってしまう。
- TB-URL http://www.tokuda.net/diary/0820/tb/