APC8750にNetBSD/evbarmを移植するための記録 8/15
2014/01/04(土) 27:56 NetBSD はてブ情報 はてブに登録 はてブ数

initarmをトライアンドエラーで動かそうと試みるも、うまく動かず、またまた諦めそうになる。

そもそも母体にしたのはNetBSD6系のソースだったので、気分転換に最新のソースを見てみました。すると、initarm_commonというinitarmで行う共通の処理をまとめた関数を使っていて、initarm本体はコンパクトに書かれていることに気づきました。

よくわからない自分があてずっぽうでいじるより、共通部分は任せてしまったほうが動きそうな気がするので、急きょ-currentでコンパイルできるように書き換えてしまいました。

すると、initarmでやることは対してなくなってしまい、最低限いじる部分はDRAMの容量とその開始アドレスぐらいになってしまいました。SDRAMがどこにあるのかはapc_start.Sでも悩んだのですが、とりあえず0x0から始めるようにしてしまっているので、ここでも0x0で始めることにしてしまいました。

すると、NetBSDのバナーまでたどり着くことができました!

その時の様子はhttp://www.tokuda.net/diary/0798に書いたとおりです。

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/0823/tb/

APC8750にNetBSD/evbarmを移植するための記録 8/9
2014/01/04(土) 27:01 NetBSD はてブ情報 はてブに登録 はてブ数

BeagleBone Blackを買って遊んだり、JNUG総会&BoFを欠席して懇親会だけ参加してみたり、納涼もんご祭りに遊びに行ったり、OSC京都でLuna見たり、そんなこんなで3か月ほど間が空きました。

さて、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
2014/01/04(土) 13:57 NetBSD はてブ情報 はてブに登録 はてブ数

MMUをonにするところで挫折しては以前から何の進歩もないのでしぶとくデバッグを続けていたところ、デバッグルーチンがレジスタを上書きしていたのにやっと気づいた。

ついに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
2014/01/04(土) 13:42 NetBSD はてブ情報 はてブに登録 はてブ数

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/