メッセージ欄

分類 【NetBSD】 で検索

一覧で表示する

NetBSD on NUC (D54250WYK)
2014/05/18(日) 17:35 NetBSD はてブ情報 はてブに登録 はてブ数

少し前ですがNUC(D54250WYK)を買いました。

インストールCD+外付けCD-ROM driveですんなりとインストールができました。
最初はxhciをdisableにしないとUSBキーボードが使えないような気がしたのですが、気のせいだったようです。

6.1.4ではオンボードNICを認識しませんでしたが、6.99.40では問題なし。

新しいCPUとSSDの威力でパワーはすごいです。

toolsを作るのに6分、GENERICカーネルを作るのに2分44秒。
bcベンチは... すいません、忘れてました。
===> Summary of results:
         build.sh command:    ./build.sh -j 8 tools
         build.sh started:    Wed May  7 03:55:39 JST 2014
         NetBSD version:      6.1.4
         MACHINE:             amd64
         MACHINE_ARCH:        x86_64
         Build platform:      NetBSD 6.99.40 amd64
         HOST_SH:             /bin/sh
         No $TOOLDIR/bin/nbmake, needs building.
         Bootstrapping nbmake
         TOOLDIR path:        /root/614/usr/src/obj/tooldir.NetBSD-6.99.40-amd64
         DESTDIR path:        /root/614/usr/src/obj/destdir.amd64
         RELEASEDIR path:     /root/614/usr/src/obj/releasedir
         Created /root/614/usr/src/obj/tooldir.NetBSD-6.99.40-amd64/bin/nbmake
         Updated makewrapper: /root/614/usr/src/obj/tooldir.NetBSD-6.99.40-amd64/bin/nbmake-amd64
         Tools built to /root/614/usr/src/obj/tooldir.NetBSD-6.99.40-amd64
         build.sh ended:      Wed May  7 04:01:39 JST 2014
===> .

===> Summary of results:
         build.sh command:    ./build.sh -j 8 kernel=GENERIC
         build.sh started:    Wed May  7 04:16:39 JST 2014
         NetBSD version:      6.1.4
         MACHINE:             amd64
         MACHINE_ARCH:        x86_64
         Build platform:      NetBSD 6.99.40 amd64
         HOST_SH:             /bin/sh
         TOOLDIR path:        /root/614/usr/src/obj/tooldir.NetBSD-6.99.40-amd64
         DESTDIR path:        /root/614/usr/src/obj/destdir.amd64
         RELEASEDIR path:     /root/614/usr/src/obj/releasedir
         Updated makewrapper: /root/614/usr/src/obj/tooldir.NetBSD-6.99.40-amd64/bin/nbmake-amd64
         Building kernel without building new tools
         Building kernel:     GENERIC
         Build directory:     /root/614/usr/src/sys/arch/amd64/compile/obj/GENERIC
         Kernels built from GENERIC:
          /root/614/usr/src/sys/arch/amd64/compile/obj/GENERIC/netbsd
         build.sh ended:      Wed May  7 04:19:23 JST 2014
===> .
いつものdmesgを残しておきます。
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
    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 6.99.40 (GENERIC) #0: Mon May  5 10:38:35 UTC 2014
        builds@b2.netbsd.org:/home/builds/ab/HEAD/amd64/201405050910Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC
total memory = 8120 MB
avail memory = 7868 MB
timecounter: Timecounters tick every 10.000 msec
timecounter: Timecounter "i8254" frequency 1193182 Hz quality 100
                                                                    (                                 )
mainbus0 (root)
ACPI: RSDP 0xf0490 000024 (v02  INTEL)
ACPI: XSDT 0xdbb15080 000084 (v01 INTEL  D54250WY 00000015 AMI  00010013)
ACPI: FACP 0xdbb24a08 00010C (v05 INTEL  D54250WY 00000015 AMI  00010013)
ACPI: DSDT 0xdbb15198 00F870 (v02 INTEL  D54250WY 00000015 INTL 20120711)
ACPI: FACS 0xdbc91080 000040
ACPI: APIC 0xdbb24b18 000072 (v03 INTEL  D54250WY 00000015 AMI  00010013)
ACPI: FPDT 0xdbb24b90 000044 (v01 INTEL  D54250WY 00000015 AMI  00010013)
ACPI: LPIT 0xdbb24bd8 00005C (v01 INTEL  D54250WY 00000015 AMI. 00000005)
ACPI: SSDT 0xdbb24c38 0004F7 (v01 INTEL  D54250WY 00000015 INTL 20120711)
ACPI: SSDT 0xdbb25130 000AD8 (v01 INTEL  D54250WY 00000015 INTL 20120711)
ACPI: MCFG 0xdbb25c08 00003C (v01 INTEL  D54250WY 00000015 MSFT 00000097)
ACPI: HPET 0xdbb25c48 000038 (v01 INTEL  D54250WY 00000015 AMI. 00000005)
ACPI: SSDT 0xdbb25c80 000315 (v01 INTEL  D54250WY 00000015 INTL 20120711)
ACPI: SSDT 0xdbb25f98 003004 (v01 INTEL  D54250WY 00000015 INTL 20091112)
ACPI: DMAR 0xdbb28fa0 000190 (v01 INTEL  D54250WY 00000015 INTL 00000001)
ACPI: CSRT 0xdbb29130 0000C4 (v01 INTEL  D54250WY 00000015 INTL 20100528)
ACPI: All ACPI Tables successfully acquired
cpu0 at mainbus0 apid 0: Intel(R) Core(TM) i5-4250U CPU @ 1.30GHz, id 0x40651
cpu1 at mainbus0 apid 2: Intel(R) Core(TM) i5-4250U CPU @ 1.30GHz, id 0x40651
cpu2 at mainbus0 apid 1: Intel(R) Core(TM) i5-4250U CPU @ 1.30GHz, id 0x40651
cpu3 at mainbus0 apid 3: Intel(R) Core(TM) i5-4250U CPU @ 1.30GHz, id 0x40651
ioapic0 at mainbus0 apid 2: pa 0xfec00000, version 0x20, 40 pins
acpi0 at mainbus0: Intel ACPICA 20131218
acpi0: X/RSDT: OemId <INTEL ,D54250WY,00000015>, AslId <AMI ,00010013>
ACPI: SSDT 0xdbb05c18 0003D3 (v01  PmRef  Cpu0Cst 00003001 INTL 20120711)
ACPI: SSDT 0x0 0003D3 (v01  PmRef  Cpu0Cst 00003001 INTL 20120711)
ACPI: SSDT 0xdbb05618 0005AA (v01  PmRef    ApIst 00003000 INTL 20120711)
ACPI: SSDT 0x0 0005AA (v01  PmRef    ApIst 00003000 INTL 20120711)
ACPI: SSDT 0xdbb04d98 000119 (v01  PmRef    ApCst 00003000 INTL 20120711)
ACPI: SSDT 0x0 000119 (v01  PmRef    ApCst 00003000 INTL 20120711)
acpi0: SCI interrupting at int 9
timecounter: Timecounter "ACPI-Safe" frequency 3579545 Hz quality 900
hpet0 at acpi0: high precision event timer (mem 0xfed00000-0xfed00400)
timecounter: Timecounter "hpet0" frequency 14318180 Hz quality 2000
acpiec0 at acpi0 (H_EC, PNP0C09-1)acpiec0: unable to evaluate _GPE: AE_NOT_FOUND
TPMX (PNP0C01) at acpi0 not configured
FWHD (INT0800) at acpi0 not configured
LDRC (PNP0C02) at acpi0 not configured
attimer1 at acpi0 (TIMR, PNP0100): io 0x40-0x43,0x50-0x53 irq 0
CWDT (INT3F0D) at acpi0 not configured
SIO1 (PNP0C02) at acpi0 not configured
RMSC (PNP0C02) at acpi0 not configured
SIRC (PNP0C02) at acpi0 not configured
PDRC (PNP0C02) at acpi0 not configured
acpivga0 at acpi0 (GFX0): ACPI Display Adapter
acpiout0 at acpivga0 (DD01, 0x0100): ACPI Display Output Device
acpiout1 at acpivga0 (DD02, 0x0002): ACPI Display Output Device
acpiout2 at acpivga0 (DD03, 0x0300): ACPI Display Output Device
acpiout3 at acpivga0 (DD04, 0x0301): ACPI Display Output Device
acpiout4 at acpivga0 (DD05, 0x0302): ACPI Display Output Device
acpiout5 at acpivga0 (DD06, 0x0303): ACPI Display Output Device
acpiout6 at acpivga0 (DD07, 0x0304): ACPI Display Output Device
acpiout7 at acpivga0 (DD08, 0x0305): ACPI Display Output Device
acpiout8 at acpivga0 (DD09, 0x0009): ACPI Display Output Device
acpiout9 at acpivga0 (DD0A, 0x000a): ACPI Display Output Device
acpiout10 at acpivga0 (DD0B, 0x000b): ACPI Display Output Device
acpiout11 at acpivga0 (DD0C, 0x000c): ACPI Display Output Device
acpiout12 at acpivga0 (DD0D, 0x000d): ACPI Display Output Device
acpiout13 at acpivga0 (DD0E, 0x000e): ACPI Display Output Device
acpiout14 at acpivga0 (DD0F, 0x000f): ACPI Display Output Device
acpiout15 at acpivga0 (DD1F, 0x0400): ACPI Display Output Device
acpiout15: brightness levels: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
acpivga0: unknown output device acpiout0
acpivga0: unknown output device acpiout1
acpivga0: unknown output device acpiout2
acpivga0: unknown output device acpiout3
acpivga0: unknown output device acpiout4
acpivga0: unknown output device acpiout5
acpivga0: unknown output device acpiout6
acpivga0: unknown output device acpiout7
acpivga0: unknown output device acpiout8
acpivga0: unknown output device acpiout9
acpivga0: unknown output device acpiout10
acpivga0: unknown output device acpiout11
acpivga0: unknown output device acpiout12
acpivga0: unknown output device acpiout13
acpivga0: unknown output device acpiout14
acpivga0: connected output devices:
acpivga0:   0x0400 (acpiout15): Unknown Output Device, head 0
acpibut0 at acpi0 (PWRB, PNP0C0C-170): ACPI Power Button
acpifan0 at acpi0 (FAN0, PNP0C0B-0): ACPI Fan
acpifan1 at acpi0 (FAN1, PNP0C0B-1): ACPI Fan
acpifan2 at acpi0 (FAN2, PNP0C0B-2): ACPI Fan
acpifan3 at acpi0 (FAN3, PNP0C0B-3): ACPI Fan
acpifan4 at acpi0 (FAN4, PNP0C0B-4): ACPI Fan
acpitz0 at acpi0 (TZ00)
acpitz0: active cooling level 0: 100.0C
acpitz0: active cooling level 1: 55.0C
acpitz0: active cooling level 2: 0.0C
acpitz0: active cooling level 3: 0.0C
acpitz0: active cooling level 4: 0.0C
acpitz0: levels: critical 105.0 C
acpitz1 at acpi0 (TZ01): cpu0 cpu1 cpu2 cpu3
acpitz1: levels: critical 105.0 C, passive 108.0 C, passive cooling
ACPI: Enabled 5 GPEs in block 00 to 7F
ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S1_] (20131218/hwxface-646)
ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S2_] (20131218/hwxface-646)
pci0 at mainbus0 bus 0: configuration mode 1
pci0: i/o space, memory space enabled, rd/line, rd/mult, wr/inv ok
pchb0 at pci0 dev 0 function 0: vendor 0x8086 product 0x0a04 (rev. 0x09)
vga0 at pci0 dev 2 function 0: vendor 0x8086 product 0x0a26 (rev. 0x09)
wsdisplay0 at vga0 kbdmux 1: console (80x25, vt100 emulation)
wsmux1: connecting to wsdisplay0
drm at vga0 not configured
hdaudio0 at pci0 dev 3 function 0: HD Audio Controller
hdaudio0: interrupting at ioapic0 pin 16
hdaudio0: RIRB timeout
hdaudio0: RIRB timeout
xhci0 at pci0 dev 20 function 0: vendor 0x8086 product 0x9c31 (rev. 0x04)
xhci0: interrupting at ioapic0 pin 16
xhci0: xHCI version 1.0
usb0 at xhci0: USB revision 2.0
vendor 0x8086 product 0x9c3a (miscellaneous communications, revision 0x04) at pci0 dev 22 function 0 not configured
wm0 at pci0 dev 25 function 0: I218 V Ethernet Connection (rev. 0x04)
wm0: interrupting at ioapic0 pin 20
wm0: PCI-Express bus
wm0: FLASH
wm0: Ethernet address XX:XX:XX:XX:XX:XX
ihphy0 at wm0 phy 2: i217 10/100/1000 media interface, rev. 5
ihphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 1000baseT-FDX, auto
hdaudio1 at pci0 dev 27 function 0: HD Audio Controller
hdaudio1: interrupting at ioapic0 pin 22
hdafg0 at hdaudio1: Realtek product 0x0283
hdafg0: DAC00 2ch: HP Out [Jack]
hdafg0: ADC01 2ch: Mic In [Jack]
hdafg0: ADC02 2ch: Mic In [Built-In]
hdafg0: 2ch/2ch 44100Hz 48000Hz 96000Hz 192000Hz PCM16 PCM20 PCM24 AC3
audio0 at hdafg0: full duplex, playback, capture, independent
ehci0 at pci0 dev 29 function 0: vendor 0x8086 product 0x9c26 (rev. 0x04)
ehci0: interrupting at ioapic0 pin 23
ehci0: BIOS has given up ownership
ehci0: EHCI version 1.0
usb1 at ehci0: USB revision 2.0
pcib0 at pci0 dev 31 function 0: vendor 0x8086 product 0x9c43 (rev. 0x04)
ahcisata0 at pci0 dev 31 function 2: vendor 0x8086 product 0x9c03 (rev. 0x04)
ahcisata0: interrupting at ioapic0 pin 19
ahcisata0: 64-bit DMA
ahcisata0: AHCI revision 1.30, 2 ports, 32 slots, CAP 0xc734ff01<PSC,SSC,PMD,SAM,ISS=0x3=Gen3,SCLO,SAL,SALP,SNCQ,S64A>
atabus0 at ahcisata0 channel 3
ichsmb0 at pci0 dev 31 function 3: vendor 0x8086 product 0x9c22 (rev. 0x04)
ichsmb0: interrupting at ioapic0 pin 18
iic0 at ichsmb0: I2C bus
isa0 at pcib0
lpt0 at isa0 port 0x378-0x37b irq 7
com0 at isa0 port 0x3f8-0x3ff irq 4: ns16550a, working fifo
pckbc0 at isa0 port 0x60-0x64
pckbc: cmd word write error
pcppi0 at isa0 port 0x61
midi0 at pcppi0: PC speaker
sysbeep0 at pcppi0
fdc0 at isa0 port 0x3f0-0x3f7 irq 6 drq 2
attimer1: attached to pcppi0
acpicpu0 at cpu0: ACPI CPU
acpicpu0: C1: FFH, lat   1 us, pow  1000 mW
acpicpu0: C2: FFH, lat  67 us, pow   500 mW
acpicpu0: P0: FFH, lat  10 us, pow 15000 mW, 1901 MHz, turbo boost
acpicpu0: P1: FFH, lat  10 us, pow 15000 mW, 1900 MHz
acpicpu0: P2: FFH, lat  10 us, pow 13939 mW, 1800 MHz
acpicpu0: P3: FFH, lat  10 us, pow 13047 mW, 1700 MHz
acpicpu0: P4: FFH, lat  10 us, pow 12172 mW, 1600 MHz
acpicpu0: P5: FFH, lat  10 us, pow 11172 mW, 1500 MHz
acpicpu0: P6: FFH, lat  10 us, pow 10334 mW, 1400 MHz
acpicpu0: P7: FFH, lat  10 us, pow  9516 mW, 1300 MHz
acpicpu0: P8: FFH, lat  10 us, pow  8712 mW, 1200 MHz
acpicpu0: P9: FFH, lat  10 us, pow  7789 mW, 1100 MHz
acpicpu0: P10: FFH, lat  10 us, pow  7021 mW, 1000 MHz
acpicpu0: P11: FFH, lat  10 us, pow  6270 mW,  900 MHz
acpicpu0: P12: FFH, lat  10 us, pow  5537 mW,  800 MHz
acpicpu0: P13: FFH, lat  10 us, pow  4688 mW,  779 MHz
coretemp0 at cpu0: thermal sensor, 1 C resolution
acpicpu1 at cpu1: ACPI CPU
coretemp1 at cpu1: thermal sensor, 1 C resolution
acpicpu2 at cpu2: ACPI CPU
acpicpu3 at cpu3: ACPI CPU
timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
timecounter: Timecounter "TSC" frequency 1895739780 Hz quality 3000
xhci0: xhci_new_device up 0xfffffe810e7d2a20 portno 0
xhci0: xhci_new_device hub 0xfffffe810eacb888
xhci0: xhci_new_device hub 0x0
xhci0: xhci_new_device rhport 0
xhci0: xhci_open addr 0 depth 0 port 0 speed 3
uhub0 at usb0: NetBSD xHCI Root Hub, class 9/0, rev 2.00/1.00, addr 0
uhub0: 9 ports with 9 removable, self powered
xhci0: xhci_open addr 0 depth 0 port 0 speed 3
uhub1 at usb1: vendor 0x8086 EHCI root hub, class 9/0, rev 2.00/1.00, addr 1
uhub1: 8 ports with 8 removable, self powered
ahcisata0 port 3: device present, speed: 6.0Gb/s
xhci0: root_hub 0x0
wd0 at atabus0 drive 0
wd0: <Crucial_CT256M550SSD3>
wd0: drive supports 16-sector PIO transfers, LBA48 addressing
wd0: 238 GB, 496149 cyl, 16 head, 63 sec, 512 bytes/sect x 500118192 sectors
wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 6 (Ultra/133)
wd0(ahcisata0:3:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 6 (Ultra/133) (using DMA)
uhub2 at uhub1 port 1: vendor 0x8087 product 0x8000, class 9/0, rev 2.00/0.04, addr 2
uhub2: single transaction translator
uhub2: 8 ports with 8 removable, self powered
umass0 at uhub2 port 1 configuration 1 interface 0
umass0: BUFFALO Optical Drive, rev 2.00/2.00, addr 3
umass0: using ATAPI over Bulk-Only
atapibus0 at umass0: 2 targets
cd0 at atapibus0 drive 0: <BUFFALO, Optical Drive, 2.00> cdrom removable
uhidev0 at uhub2 port 3 configuration 1 interface 0
uhidev0: Microsoft MicrosoftM-BM-. Nano Transceiver v2.0, rev 2.00/6.34, addr 4, iclass 3/1
ukbd0 at uhidev0: 8 modifier keys, 6 key codes
wskbd0 at ukbd0 mux 1
wskbd0: connecting to wsdisplay0
uhidev1 at uhub2 port 3 configuration 1 interface 1
uhidev1: Microsoft MicrosoftM-BM-. Nano Transceiver v2.0, rev 2.00/6.34, addr 4, iclass 3/1
uhidev1: 28 report ids
uhid0 at uhidev1 reportid 18: input=0, output=0, feature=1
uhid1 at uhidev1 reportid 22: input=4, output=0, feature=0
uhid2 at uhidev1 reportid 23: input=0, output=0, feature=1
ums0 at uhidev1 reportid 26: 5 buttons, W and Z dirs
wsmouse0 at ums0 mux 0
uhid3 at uhidev1 reportid 28: input=3, output=0, feature=0
uhidev2 at uhub2 port 3 configuration 1 interface 2
uhidev2: Microsoft MicrosoftM-BM-. Nano Transceiver v2.0, rev 2.00/6.34, addr 4, iclass 3/0
uhidev2: 8 report ids
uhid4 at uhidev2 reportid 3: input=1, output=0, feature=0
uhid5 at uhidev2 reportid 4: input=1, output=0, feature=0
uhid6 at uhidev2 reportid 7: input=7, output=0, feature=0
uhid7 at uhidev2 reportid 8: input=1, output=0, feature=0
uhidev3 at uhub2 port 4 configuration 1 interface 0
uhidev3: vendor 0x0566 product 0x3029, rev 2.00/1.01, addr 5, iclass 3/1
ukbd1 at uhidev3: 8 modifier keys, 6 key codes
wskbd1 at ukbd1 mux 1
wskbd1: connecting to wsdisplay0
uhidev4 at uhub2 port 4 configuration 1 interface 1
uhidev4: vendor 0x0566 product 0x3029, rev 2.00/1.01, addr 5, iclass 3/0
uhidev4: 2 report ids
uhid8 at uhidev4 reportid 1: input=2, output=0, feature=0
uhid9 at uhidev4 reportid 2: input=1, output=0, feature=0
Kernelized RAIDframe activated
pad0: outputs: 44100Hz, 16-bit, stereo
audio1 at pad0: half duplex, playback, capture
boot device: wd0
root on wd0a dumps on wd0b
root file system type: ffs
wsdisplay0: screen 1 added (80x25, vt100 emulation)
wsdisplay0: screen 2 added (80x25, vt100 emulation)
wsdisplay0: screen 3 added (80x25, vt100 emulation)
wsdisplay0: screen 4 added (80x25, vt100 emulation)

APC8750にNetBSD/evbarmを移植するための記録 4/29
2014/04/29(火) 19:36 NetBSD はてブ情報 はてブに登録 はてブ数

さて、タイマードライバの実装が終わったので、これまで/sbin/initに手を入れていた部分を戻していきます。

手を入れていたところは、
  1. nanosleepをすっとばしていた
  2. busy loopを作って、そのなかでsleepを読んでいた
という二か所。片方づつ元に戻していったところ、ちゃんと動くようになっていました。

やりました!

次に、sleepコマンドをramdisk.fsに入れ込んで、実際sleep 10で10秒間スリープするかを確認してみました。

こちらも、ほぼちゃんと動いているように思えます。ほぼ、というのは近くのデジタル時計の秒表示でざっくり測ったレベル、という意味です。

OSのシステムタイマがいろいろなところに影響しているのがよくわかりました。

これで、必要最低限のドライバである、シリアルコンソール・割り込みコントローラ・システムタイマが揃いました。

割り込みコントローラは二つあるうちの一つしか動いていないし、なぜかカーネルデバッガに落ちた時に最後の入力が延々と発生し続ける、などとおかしなところは多々ありますが。

APC8750にNetBSD/evbarmを移植するための記録 4/27
2014/04/27(日) 19:28 NetBSD はてブ情報 はてブに登録 はてブ数

wmt_tmr.cのつづきです。

cpu_initclocksが終わったので、delay, clockhandler, bcm2835_get_timecountという三つの関数を実装していきます。

まずは、delayです。

bcm2835_tmr.cを見てみると、タイマーレジスタから値を取って、delayさせたいマイクロ秒数経過するまでループする(つまりdelayする)、という処理のようです。

今回の場合、参照すべきタイマーレジスタはどれでしょうか。
あらためて、レジスタ名を見てみます。
https://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/mach-wmt/include/mach/wmt_pmc.h#L89
 * OSM0_REG OS Timer Match Register 0
 *
 * OSM1_REG OS Timer Match Register 1
 *
 * OSM2_REG OS Timer Match Register 2
 *
 * OSM3_REG OS Timer Match Register 3
 *
 * OSCR_REG OS Timer Count Register.
 *
 * OSTS_REG OS Timer Status Register.
 *
 * OSTW_REG OS Timer Watchdog enable Register.
 *
 * OSTI_REG OS Timer Interrupt enable Register.
 *
 * OSTC_REG OS Timer Control Register.
 *
 * OSTA_REG OS Timer Access status Register.
カウンタを扱いそうなのは、OS Timer Count RegisterつまりOSCRじゃないかなぁと。

ふたたび、Linuxのソースを見てみます。

https://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/kernel/time.c#L558
/* wmt_read_oscr()
 *
 * Return the current count of OS Timer.
 *
 * Note: This function will be call by other driver such as hwtimer
 *       or watchdog, but we don't recommand you to include this header,
 *       instead with using extern...
 *       Move it to other appropriate place if you have any good idea.
 */
inline unsigned int wmt_read_oscr(void)
{
	/*
	 * Request the reading of OS Timer Count Register.
	 */
	OSTC_VAL |= OSTC_RDREQ;

	/*
	 * Polling until free to reading.
	 * Although it looks dangerous, we have to do this.
	 * That means if this bit not worked, ostimer fcuntion
	 * might be not working, Apr.04.2005 by Harry.
	 */
	while (OSTA_VAL & OSTA_RCA)
		;

	return OSCR_VAL;
}
現在のカウンタを取ってくる関数ですね。
read要求を行い、read可能になるまで待ってから、カウントレジスタ(OSCR)を返している、と。

NetBSDのbcm2835_tmr.cでは現在のカウンタ取得は、
    163 	last = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCM2835_STIMER_CLO);
というレジスタ読み込み一発でとってきていますが、今回は先のwmt_read_oscr関数のように、ちょっとした手順を踏んでからカウンタの値を取ってくる必要があるようです。

こんな感じで現在のカウンタを取る関数を作ってみました。
uint32_t
get_current(void)
{
        struct wmttmr_softc *sc = wmttmr_sc;

        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TC,
          bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TC) | OSTC_RDREQ);

        while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TA) & OSTA_RCA) {
                ;
        }

        return bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_CR);
}
さて、元に戻ってdelayです。ほぼ、bcm2835_tmr.cのdelayと同じになりました。
void
delay(unsigned int n)
{
        struct wmttmr_softc *sc = wmttmr_sc;
        uint32_t last, curr;
        uint32_t delta, usecs;

        KASSERT(sc != NULL);
        last = get_current();
        delta = usecs = 0;
        while (n > usecs) {
                curr = get_current();
                /* Check to see if the timer has wrapped around. */
                if (curr < last)
                        delta += curr + (UINT32_MAX - last);
                else
                        delta += curr - last;

                last = curr;

                if (delta >= counts_per_usec) {
                        usecs += delta / counts_per_usec;
                        delta %= counts_per_usec;
                }
        }
}
あぁ、これでdelayをインチキなしで動作させることができる、はずです。

次は、clockhandler関数です。

NetBSDのbcm2835_tmr.cのclockhandlerを見てみます。
    186 /*
    187  * clockhandler:
    188  *
    189  *	Handle the hardclock interrupt.
    190  */
    191 static int
    192 clockhandler(void *arg)
    193 {
    194 	struct bcm2835tmr_softc *sc = bcm2835tmr_sc;
    195 	struct clockframe *frame = arg;
    196 	uint32_t curr, status;
    197 
    198 	status = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
    199 	    BCM2835_STIMER_CS);
    200 
    201 	if (!(status & BCM2835_STIMER_M3))
    202 		return 0;
    203 
    204 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_STIMER_CS, status);
    205 
    206 	hardclock(frame);
    207 
    208 	curr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCM2835_STIMER_CLO);
    209 
    210 	curr += counts_per_hz;
    211 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_STIMER_C3, curr);
    212 
    213 	return 1;
    214 }
うーん、タイマーステータスを読んで、書き戻し、現在時刻にcounts_per_hzを足してSTIMER_C3に書き込んでいるという感じかなぁ。ちょっとよくわかりません。

Linux側ではhttps://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/kernel/time.c#L718が割り込み処理っぽいですね。
static irqreturn_t
wmt_timer_interrupt(int irq, void *dev_id)
{
	unsigned int next_match;

	do {
		do_leds();
		timer_tick();

		/* Clear match on OS Timer 1 */
		OSTS_VAL = OSTS_M1;
		next_match = (OSM1_VAL += LATCH);
		do_set_rtc();
	} while ((signed long)(next_match - wmt_read_oscr()) <= 0);

	/* TODO: add do_profile()  */
//	do_profile(regs);

	return IRQ_HANDLED;
}
ふーむ、レジスタ操作だけ見るとOS Timer 1のMatchをクリアして、OS Timer Match Register 1(OSTS_M1) を更新しているだけです。あとはきっとタイマー割り込みで共通的な処理 (do_leds, timer_tick, do_set_rtc) を読んでいるのでしょう。

あっ、つまりタイマー割り込みで共通的な処理っていうのは、NetBSDでいうところの
    206 	hardclock(frame);
ってことか。

だとすると、OSTS_M1、OSM1_VALを更新する処理をもらってくるだけでよさそうな気がしてきました。念のため、OSM1_VALを更新する際、OSTA_MWA1もチェックしています。これはinitclocksでもそういう風にしていたのをまねました。
static int
clockhandler(void *arg)
{
        struct wmttmr_softc *sc = wmttmr_sc;
        struct clockframe *frame = arg;
        uint32_t curr;
        hardclock(frame);
        while(bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TA) & OSTA_MWA1)
                ;
        curr = get_current();
        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TS, OSTS_M1);
        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_M1, curr + counts_per_hz);

        return 1;
}
最後は、bcm2835_get_timecountあらためwmt_get_timecountです。

これは、これまでの想定から、カウントレジスタ(OSCR)を返してあげればよいだけで、すでにget_current関数で実装済みです。

static u_int
wmttmr_get_timecount(struct timecounter *tc)
{
        uint32_t curr;
        curr = get_current();

        return curr;
}
これで、ひととおり書き換えたことになります。さて、ちゃんとdelayとかsleepが動いてくれるんでしょうかねぇ。

APC8750にNetBSD/evbarmを移植するための記録 4/26
2014/04/26(土) 17:51 NetBSD はてブ情報 はてブに登録 はてブ数

前回が昨年の10/23ということで、実に半年の月日が流れました。

なんとかそれっぽく見えるになったのですが、/sbin/initに手を入れて無理やり動かしていたり、まだまだちゃんとしていません。

なにより、タイマードライバが手抜きというか、コンパイル通るだけの代物なので、なんとかちゃんとしたものにしたいと。そうすれば、delayも呼べるようになるし。

ということで、wmt_tmr.cの原型となったbcm2835_tmr.cを読んでみます。

実は、最初はRTC (real-time clock) のドライバを書くのかと思っていたのです。タイマー = 時計、つまりRTCだろうと。

ところがbcm2835_tmr.cを読んでもRTCという文字列は出てきません。あらためてWikipediaでRTCを調べてみると、RTCは年月日時分秒という意味での時計であって、CPUクロックやシステムクロックを供給するものではない、ということがわかりました。それどころか、RTCへの書き込みは遅いので、いったんRTCから現在時刻を取得した後は、CPUの高精度なタイマーを使って、それ以降の時間を管理しているということがわかりました。

ということで、ここでいうタイマーはCPUが持っているタイマーである、つまり、いままでタイマーの割り込み番号をRTCに合わせていたのですが、まったくの間違いだということです。

それであ、真のタイマーはどこか、正しい割り込み番号はどこか、ということでLinuxのソースをあさります。

https://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/mach-wmt/include/mach/irqs.h

をみると
#define IRQ_OST0 36 /* OS Timer match 0 */
#define IRQ_OST1 37 /* OS Timer match 1 */
#define IRQ_OST2 38 /* OS Timer match 2 */
#define IRQ_OST3 39 /* OS Timer match 3 */
と書かれています。きっとこれでしょうね。しかし、四つもあるのはなんでしょうか。

さて、NetBSDに話を戻して、あらためてbcm2835_tmr.cを眺めてみましょう。

matchとattachは、大したことはしていなさそうで、ちょっとした置換だけでそのまま使えそうです。

あとはcpu_initclocks, delay, clockhandler, bcm2835_get_timecountという四つの関数で構成されています。

名前から想像するに、cpu_initclocksはinitなので初期化ルーチン、delayはdelay(9)の本体、clockhandlerはhandlerなので割り込みが起こった時に呼ばれるルーチン、bcm2835_get_timecountはタイマーの値を取得する、って感じかなぁ。

まずは、初期化ルーチンであるcpu_initclocksを見てみます。
    129 void
    130 cpu_initclocks(void)
    131 {
    132 	struct bcm2835tmr_softc *sc = bcm2835tmr_sc;
    133 	void *clock_ih;
    134 	uint32_t stcl;
    135 
    136 	KASSERT(sc != NULL);
    137 
    138 	bcm2835tmr_timecounter.tc_priv = sc;
    139 
    140 	counts_per_hz = BCM2835_STIMER_HZ / hz;
    141 
    142 	stcl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCM2835_STIMER_CLO);
    143 	stcl += counts_per_hz;
    144 
    145 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_STIMER_C3, stcl);
    146 	clock_ih = bcm2835_intr_establish(BCM2835_INT_TIMER3, IPL_CLOCK,
    147 	    clockhandler, NULL);
    148 	if (clock_ih == NULL)
    149 		panic("%s: unable to register timer interrupt", __func__);
    150 
    151 	tc_init(&bcm2835tmr_timecounter);
    152 }
うーん。bus_space_read_4でレジスタから値を読んで、bcm2835_intr_establishで割り込みコントローラとお話しして、tc_initというのを読んでるということぐらいしかわかりません。

initつまり初期化処理がこの関数の目的で、きっと初期化はデバイス固有でしょうからLinuxのソースを見てから考えることにします。

初期化処理を探すにあたっては、OS Timerのレジスタを触っているところだろう、ということでhttps://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/mach-wmt/include/mach/wmt_pmc.h#L423に定義されているOS Timer周りのレジスタ名から検索で絞り込んでみました。
#define OSM0_VAL (REG32_VAL(OSM0_ADDR))
#define OSM1_VAL (REG32_VAL(OSM1_ADDR))
#define OSM2_VAL (REG32_VAL(OSM2_ADDR))
#define OSM3_VAL (REG32_VAL(OSM3_ADDR))
#define OSCR_VAL (REG32_VAL(OSCR_ADDR))
#define OSTS_VAL (REG32_VAL(OSTS_ADDR))
#define OSTW_VAL (REG32_VAL(OSTW_ADDR))
#define OSTI_VAL (REG32_VAL(OSTI_ADDR))
#define OSTC_VAL (REG32_VAL(OSTC_ADDR))
#define OSTA_VAL (REG32_VAL(OSTA_ADDR))
Linuxでの初期化処理に該当するのは、おそらく、https://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/kernel/time.c#L804にあるtime_init関数でしょう。
void __init time_init(void)
{
	unsigned int i = 0;
	struct timespec tv;

	if (system_timer->offset == NULL)
		system_timer->offset = dummy_gettimeoffset;

	/* system_timer->init(); */
	/* Stop ostimer. */
	OSTC_VAL = 0;

	if (wmt_rtc_on) {
		rtc_init();
		gettimeoffset = wmt_gettimeoffset;
		set_rtc       = wmt_set_rtc;     /* draft, need to verify */
		tv.tv_nsec    = 0;
		tv.tv_sec     = wmt_get_rtc_time();
	} else {
		gettimeoffset = wmt_gettimeoffset;
		tv.tv_nsec    = 0;
		tv.tv_sec     = 0;
	}

	do_settimeofday(&tv);

	/* Set initial match */
	while (OSTA_VAL & OSTA_MWA1)
		;
	OSM1_VAL = 0;

	/* Clear status on all timers. */
	OSTS_VAL = OSTS_MASK;     /* 0xF */

	/* Use OS Timer 1 as kernel timer because watchdog may use OS Timer 0. */
	i = setup_irq(IRQ_OST1, &wmt_timer_irq);

	/* Enable match on timer 1 to cause interrupts. */
	OSTI_VAL |= OSTI_E1;

	/* Let OS Timer free run. */
	OSTC_VAL = OSTC_ENABLE;

	/* Initialize free-running timer and force first match. */
	while (OSTA_VAL & OSTA_CWA)
		;
	OSCR_VAL = 0;
}
OS Timer0をwatchdogで使い、OS Timer1をカーネルタイマで使う、というコメントがあります。なるほど、複数の役割のタイマが必要だから、OS Timerが四つもあるのですね。

初期化は次のステップで実装されているようです。
  1. OS Timerを止める (OSTC_VAL = 0)
  2. OS Timer1のマッチレジスタが書き込み可能になるまで待つ (while (OSTA_VAL & OSTA_MWA1))
  3. OS Timer1のマッチレジスタに0を入れる(OSM1_VAL = 0)
  4. すべてのOS Timerのステータスをクリアする(OSTS_VAL = OSTS_MASK)
  5. OS Timer1の割り込みをセットアップ(setup_irq(xxx))
  6. OS Timer1の割り込みをenableにする
  7. OS Timerを有効にする(OSTC_VAL = OSTC_ENABLE)
  8. カウンタが書き込み可能になるまで待つ (while (OSTA_VAL & OSTA_CWA))
  9. カウンタに0を書き込む
これを、NetBSDで実装すればよさそうです。レジスタの読み書きはbus_space_read/writeで、割り込みのセットアップは先のbcm2835_intr_establishに相当する処理でしょう。

ところで、bcm2835_tmr.cの140行目にあるOS Timerの周波数は今回どうすればよいのでしょう。
    140 	counts_per_hz = BCM2835_STIMER_HZ / hz;
おそらく、https://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/mach-wmt/include/mach/timex.h#L25にあるとおり、3MHzというのがそれっぽいです。
/*
 * WMT SoC timer parameters
 */
#define CLOCK_TICK_RATE 3000000
#define CLOCK_TICK_FACTOR 80
ほぼ丸コピーで芸がないですが、こんな感じになりました。
cpu_initclocks(void)
{
        struct wmttmr_softc *sc = wmttmr_sc;
        void *clock_ih;

        KASSERT(sc != NULL);

        wmttmr_timecounter.tc_priv = sc;

        counts_per_hz = WMT_OSTMR_HZ / hz;

        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TC, 0); /* stop os timer */

        while(bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TA) & OSTA_MWA1)
                ;
        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_M1, counts_per_hz);

        /* clear status on all timers */
        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TS, 0xF);
        clock_ih = wmt_intr_establish(sc->sc_intr, IPL_CLOCK,
            clockhandler, NULL);
        if (clock_ih == NULL)
                panic("%s: unable to register timer interrupt", __func__);

        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TI, OSTI_E1); /* enable intr timer1 */

        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TC, OSTC_ENABLE); /* enable os timer */

        /* Initaialize counter register */
        while(bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TA) & OSTA_CWA)
                ;
        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_CR, 0);

        bus_space_write_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TC,
          bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TC) | OSTC_RDREQ);
        while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, WMT_OSTMR_TA) & OSTA_RCA) {
                ;
        }
        tc_init(&wmttmr_timecounter);
}

APC8750にNetBSD/evbarmを移植するための記録 10/23
2014/02/14(金) 22:06 NetBSD はてブ情報 はてブに登録 はてブ数

ちょっと10日ほど冷却期間をおいて再開です。

currentのVMをつくって、そこで再開した。6.99.24であります。
ソースを更新したからって、先に進むなどという幸運はなく。

/sbin/initが
pid1072pid0wait for single-user shell failed: m; restartingpid1073pid0wait for single-user shell failed: m; restartingproc: table is full - increase kern.maxproc or NPROC
pid-1
などと言って果てていた件。

init.cを読んでみるとforkのところが怪しい。

forkのあと、pid==0ならという条件文をpid !=0と、変えてみるとpid0, pid2が動いていることがわかる。しかし、pid==0だとするとpid2だけしか動いていないように見える。

動いている場合も、下記のaccessより先にはいかない。

    678 	if ((pid = fork()) == 0) {
    679 		/*
    680 		 * Start the single user session.
    681 		 */
    682 		if (access(_PATH_CONSTTY, F_OK) == 0)
    683 			setctty(_PATH_CONSTTY);
    684 		else
    685 			setctty(_PATH_CONSOLE);
つまりsetcttyで引っかかっている(無限ループか無限待ちなど)ということ。

んで、setcttyを見てみると、関数の中で
    620 static void
    621 setctty(const char *name)
    622 {
    623 	int fd;
    624 
    625 	(void)revoke(name);
    626 	(void)nanosleep(&dtrtime, NULL);	/* leave DTR low for a bit */
    627 	if ((fd = open(name, O_RDWR)) == -1) {
    628 		stall("can't open %s: %m", name);
    629 		_exit(1);
    630 	}
    631 	if (login_tty(fd) == -1) {
    632 		stall("can't get %s for controlling terminal: %m", name);
    633 		_exit(2);
    634 	}
    635 }
むむ、nanosleepというのを使っているな。

なんか、そういえば、sleepを使うと止まってしまう事象に見舞われたはず。
いやちがう、wmt_com.cのattachでdelayを呼ぶと止まるのだった。
というか、delayとsleepは似たようなものだろうから、きっと呼ぶと止まるのだろう(いい加減だ)。

pid!=0のままsetcttyにコメントを入れて止まる場所を探してみる。
icu: establish_irq: is->is_irq=0x20
icu: establish_irq: is->is_irq=0x30
rn_init: radix functions require max_keylen be set
boot device: <unknown>
root on md0a dumps on md0b
mountroot: trying nfs...
mountroot: trying msdos...
mountroot: trying ffs...
root file system type: ffs
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
init: copying out flags `-s' 3
init: copying out path `/sbin/init' 11
init: pid = 2
init: access ret = 0
init: setctty consttyinit: revoke(name)
init: nanosleep()
init: pid = 0 start busy loop...
やっぱりだ。pid = 2の場合nanosleepまで実行して止まっている。一方、pid = 0はダミーで仕込んだビジーループを全力で回している。

臭いものにはフタということで、nanosleepを#if 0 - #endifで呼ばないようにしてみた。
icu: establish_irq: is->is_irq=0x30
rn_init: radix functions require max_keylen be set
boot device: <unknown>
root on md0a dumps on md0b
mountroot: trying nfs...
mountroot: trying msdos...
mountroot: trying ffs...
root file system type: ffs
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
init: copying out flags `-s' 3
init: copying out path `/sbin/init' 11
init: pid = 2
init: access ret = 0
init: setctty consttyinit: revoke(name)
init: nanosleep()
init: open()
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
erase ^?, werase ^W, kill ^U, intr ^C
wmtcom: ioctl
init: pid = 0 start busy loop...
おぉ、なんか先に進んでいるっぽい。wmtcomのioctlが呼ばれまくっている。中身が実装されていないのでデバック出力している。

が、pid = 2が先に進まない。ビジーループがだめなのかな。

よく考えたら、ビジーループだけにpid0が全力でCPUをつかんで離さないのではないかな? これをsleepなどにかえて、次のプロセスに処理を渡すようにしてやればいいんじゃ?

とりあえず、wmt_tmr.cのdelayにdelayが呼ばれたらデバッグプリントするように仕込むことにした。

なんか知らんが、pid==0の条件に戻して、ビジーループの中でsleepを入れたらsysinstが動いたぞ? これって、/bin/sh経由でうごいているはず。
wmtcom0 at obio0 addr 0xd8200000-0xd820ffff intr 32 : WMT UART
wmtcom:wmtcom_attach_subr 1-1
wmtcom0: console cn_tab->cn_dev=00007000
icu: establish_irq: is->is_irq=0x20
icu: establish_irq: is->is_irq=0x30
rn_init: radix functions require max_keylen be set
boot device: <unknown>
root on md0a dumps on md0b
mountroot: trying nfs...
mountroot: trying msdos...
mountroot: trying ffs...
root file system type: ffs
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
init: copying out flags `-s' 3
init: copying out path `/sbin/init' 11
init: pid = 2 start busy loop...
init: pid = 0
init: access ret = 0
init: setctty consttyinit: revoke(name)
init: nanosleep()
init: open()
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
erase ^?, werase ^W, kill ^U, intr ^C
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl

wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl
wmtcom: ioctl

wmtcom: ioctl




















































 NetBSD/evbarm 6.99.24

 This menu-driven tool is designed to help you install NetBSD to a hard disk,
 or upgrade an existing NetBSD system, with a minimum of work.
 In the following menus type the reference letter (a, b, c, ...) to select an
 item, or type CTRL+N/CTRL+P to select the next/previous item.
 The arrow keys and Page-up/Page-down may also work.
 Activate the current selection from the menu by typing the enter key.



                lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
                xwmtcom: ioctlion messages in English         x
                x b: Messages d'installation en fran軋is      x
                x c: Installation auf Deutsch                 x
                x d: Komunikaty instalacyjne w jezyku polskim x
                x e: Mensajes de instalacion en castellano    x
                mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
シリアルの入力を作れば、もしかするかもしれんぞ。

というか、ramdisk.fsの.profileでsysinstを呼ばないようにしたら、shellが上がってきそうな気がする。

distrib/evbarm/instkernel/ramdisk/dot.profileにls, df, sysctl -aなどと書いたらioctlのログを大量に吐きつつも、ちゃんと実行できるようになった。
わはは!

シリアルドライバの入力を作りたい気分が高まってきた。
冷却期間おいてよかった。

ps見られるとおもしろそうだと思って、ramdisk/listにpsを足してみたがエラーになる。
#      link  obj/ramdiskbin
/usr/src/obj/tooldir.NetBSD-6.99.24-amd64/bin/arm--netbsdelf-gcc    --sysroot=/usr/src/obj/destdir.evbarm   -static  -o ramdiskbin  ramdiskbin.o  -Wl,-rpath-link,/usr/src/obj/destdir.evbarm/lib  -L=/lib cat.cro chmod.cro cp.cro dd.cro df.cro ed.cro ln.cro ls.cro mkdir.cro mv.cro pax.cro ps.cro pwd.cro rm.cro rmdir.cro sh.cro stty.cro sync.cro chown.cro disklabel.cro drvctl.cro fdisk.cro fsck.cro fsck_msdos.cro fsck_ffs.cro gpt.cro ifconfig.cro init.cro mknod.cro mount.cro mount_cd9660.cro mount_ext2fs.cro mount_ffs.cro mount_kernfs.cro mount_msdos.cro mount_nfs.cro mount_tmpfs.cro newfs.cro newfs_ext2fs.cro ping.cro reboot.cro restore.cro route.cro shutdown.cro slattach.cro sysctl.cro swapctl.cro umount.cro ftp.cro tip.cro gzip.cro less.cro sed.cro tset.cro chroot.cro sysinst.cro progress.cro dhcpcd.cro  libhack.o -ledit -lutil -lcurses -lterminfo -lrmt -lcrypt -ll -lm -lz -lprop
ps.cro: In function `donlist$$from$$ps':
:(.text+0x734): undefined reference to `kvm_nlist'
:(.text+0x764): undefined reference to `kvm_read'
:(.text+0x778): undefined reference to `kvm_geterr'
:(.text+0x7a8): undefined reference to `kvm_read'
:(.text+0x7b8): undefined reference to `kvm_geterr'
:(.text+0x7ec): undefined reference to `kvm_read'
:(.text+0x7fc): undefined reference to `kvm_geterr'
:(.text+0x830): undefined reference to `kvm_read'
:(.text+0x840): undefined reference to `kvm_geterr'
ps.cro: In function `command$$from$$ps':
:(.text+0xdd8): undefined reference to `kvm_getenvv2'
:(.text+0xe44): undefined reference to `kvm_getargv2'
ps.cro: In function `_crunched_ps_stub':
:(.text+0x3620): undefined reference to `kvm_openfiles'
:(.text+0x364c): undefined reference to `kvm_openfiles'
:(.text+0x371c): undefined reference to `kvm_getproc2'
:(.text+0x3734): undefined reference to `kvm_geterr'
:(.text+0x37c0): undefined reference to `kvm_getlwps'
:(.text+0x3914): undefined reference to `kvm_getlwps'
collect2: ld returned 1 exit status
psがうごくと楽しそうなんだけどな。ちょっとそれは後にしよう。

勢いでシリアルコンソールのRX部分を実装してみました。

ISR, IERをとりちがえてしまったのとcomintrの中のRXの中でISRを読んでいる部分、最初はループ外で読んでいる奴を使いまわせばよい&ISRを読んでしまうとクリアされてしまうステータスがあるので読んじゃダメなんじゃ? と思っていたが実はそれは間違いで、ISRを呼ばないとループをちゃんと回せない(次の文字に進まない)ことがわかっぱー。

もろもろデバッグプリントを消したり、wmtcomのioctlを無言にしたりして、起動時をそれっぽく出せるようにしてみました。

はい! 来ました!
WMT # set serverip 192.168.0.10; tftpboot 8000; go 8000
EEP-less strapping = TRUE
*** Warning: no boot file name; using 'C0A80002.img'
TFTP from server 192.168.0.10; our IP address is 192.168.0.2
Filename 'C0A80002.img'.
Load address: 0x8000
Loading: #################################################################
         ###########################################T ######################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ################################T #################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ####################T #############################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #####################################################T ############
         #################################################################
         ##################
done
Bytes transferred = 6747520 (66f580 hex)
## Starting application at 0x00008000 ...
00008328
NetBSD
00000000 00000000 0088a74b 00000412
00000000 00000412 00000008 00000412
c0000000 00000000 0088a74b 0000041e
00003000 0000041e 00000008 0000041e
fe000000 d8000000 010fffff 00000412
00003f80 d8000412 00000010 00000412
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
NS
NetBSD/evbarm (APC) booting ...
initarm: Configuring system ...
arm32_bootmem_init: memstart=0, memsize=0x20000000, kernelstart=0x8000
arm32_bootmem_init: kernelend=0x68b000
arm32_bootmem_init: adding 129397 free pages: [0x68b000..0x1fffffff] (VA 0xc068b000)
arm32_bootmem_init: adding 8 free pages: [0..0x7fff] (VA 0xc0000000)
arm32_kernel_vm_init: 2 L2 pages are needed to map 0x6b6000 kernel bytes
arm32_kernel_vm_init: allocating page tables for vectoradd_pages: adding pv 0xc0677cac (pa 0x68b000, va 0xc068b000, 1 pages) at tail
 kerneladd_pages: appending pv 0xc06826ec (0x68c000..0x68ffff) to 0x68b000..0x68bfff
add_pages: appending pv 0xc0677f30 (0x690000..0x690fff) to 0x68b000..0x68ffff
add_pages: appending pv 0xc0677f44 (0x691000..0x691fff) to 0x68b000..0x690fff
 vmadd_pages: appending pv 0xc0677f58 (0x692000..0x692fff) to 0x68b000..0x691fff
add_pages: appending pv 0xc0677f6c (0x693000..0x693fff) to 0x68b000..0x692fff
add_pages: appending pv 0xc0677f80 (0x694000..0x694fff) to 0x68b000..0x693fff
add_pages: appending pv 0xc0677f94 (0x695000..0x695fff) to 0x68b000..0x694fff
add_pages: appending pv 0xc0677fa8 (0x696000..0x696fff) to 0x68b000..0x695fff
add_pages: appending pv 0xc0677fbc (0x697000..0x697fff) to 0x68b000..0x696fff
add_pages: appending pv 0xc0677fd0 (0x698000..0x698fff) to 0x68b000..0x697fff
add_pages: appending pv 0xc0677fe4 (0x699000..0x699fff) to 0x68b000..0x698fff
arm32_kernel_vm_init: allocating stacks
add_pages: appending pv 0xc0678230 (0x69a000..0x69afff) to 0x68b000..0x699fff
add_pages: appending pv 0xc0678244 (0x69b000..0x69bfff) to 0x68b000..0x69afff
add_pages: appending pv 0xc0678258 (0x69c000..0x69cfff) to 0x68b000..0x69bfff
add_pages: appending pv 0xc067826c (0x69d000..0x69dfff) to 0x68b000..0x69cfff
add_pages: appending pv 0xc0678280 (0x69e000..0x69ffff) to 0x68b000..0x69dfff
add_pages: appending pv 0xc067821c (0x6a0000..0x6a1fff) to 0x68b000..0x69ffff
add_pages: appending pv 0xc0677d24 (0x6a2000..0x6a5fff) to 0x68b000..0x6a1fff
Creating L1 page table at 0x0068c000
arm32_kernel_vm_init: adding L2 pt (VA 0xc068b000, PA 0x68b000) for VA 0xffff0000
 (vectors)arm32_kernel_vm_init: adding L2 pt (VA 0xc0690000, PA 0x690000) for VA 0xc0000000 (kernel)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0691000, PA 0x691000) for VA 0xc0400000 (kernel)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0692000, PA 0x692000) for VA 0xc1000000 (vm)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0693000, PA 0x693000) for VA 0xc1400000 (vm)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0694000, PA 0x694000) for VA 0xc1800000 (vm)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0695000, PA 0x695000) for VA 0xc1c00000 (vm)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0696000, PA 0x696000) for VA 0xc2000000 (vm)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0697000, PA 0x697000) for VA 0xc2400000 (vm)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0698000, PA 0x698000) for VA 0xc2800000 (vm)
arm32_kernel_vm_init: adding L2 pt (VA 0xc0699000, PA 0x699000) for VA 0xc2c00000 (vm)
Mapping kernel
arm32_kernel_vm_init: adding chunk for kernel text 0x8000..0x1cffff (VA 0xc0008000)
add_pages: adding pv 0xc0677c98 (pa 0x8000, va 0xc0008000, 456 pages) before pa 0x68b000
arm32_kernel_vm_init: adding chunk for kernel data/bss 0x1d0000..0x68afff (VA 0xc01d0000)
add_pages: appending pv 0xc0677cfc (0x1d0000..0x68afff) to 0x8000..0x1cffff
add_pages: merging pv 0xc0677cac (0x68b000..0x6a5fff) to 0x8000..0x68afff
Listing Chunks
arm32_kernel_vm_init: pv 0xc0677c98: chunk VA 0xc0008000..0xc06a5fff (PA 0x8000, prot 3, cache 1)

Mapping Chunks
arm32_kernel_vm_init: mapping last chunk VA 0xc0008000..0xc06a5fff (PA 0x8000, prot 3, cache 1)
pmap_map_chunk: pa=0x8000 va=0xc0008000 size=0x69e000 resid=0x69e000 prot=0x3 cache=1
PPPPPPPPLLLLLLLLLLLLLLLSSSSSLLLLLLLLLLPPPPPP
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 0x1fffffff 0xc0000000 0xdfffffff 131072
        text section: 0x00008000 0x001cffff 0xc0008000 0xc01cffff 456
        data section: 0x001d0000 0x00677580 0xc01d0000 0xc0677580 1192
         bss section: 0x00677580 0x0068a74c 0xc0677580 0xc068a74c 20
   L1 page directory: 0x0068c000 0x0068ffff 0xc068c000 0xc068ffff 4
   ABT stack (CPU 0): 0x0069a000 0x0069afff 0xc069a000 0xc069afff 1
   FIQ stack (CPU 0): 0x0069b000 0x0069bfff 0xc069b000 0xc069bfff 1
   IRQ stack (CPU 0): 0x0069c000 0x0069cfff 0xc069c000 0xc069cfff 1
   UND stack (CPU 0): 0x0069d000 0x0069dfff 0xc069d000 0xc069dfff 1
  IDLE stack (CPU 0): 0x0069e000 0x0069ffff 0xc069e000 0xc069ffff 2
           SVC stack: 0x006a0000 0x006a1fff 0xc06a0000 0xc06a1fff 2
      Message Buffer: 0x006a2000 0x006a5fff 0xc06a2000 0xc06a5fff 4
   Exception Vectors: 0x006a6000 0x006a6fff 0xffff0000 0xffff0fff 1
         Free Memory: 0x006a7000 0x1fffffff                       129369
         Free Memory: 0x00000000 0x00007fff                       8
switching to new L1 page table @0x68c000...TTBR0=0x68c000 OK
done.
nfreeblocks = 2, free_pages = 129377 (0x1f961)
bootstrap done.
vectors 0xffff0000
init subsystems: stacks vectors undefined page pmap_physload pmap [ Kernel symbol table missing! ]
done.
Loaded initial symtab at 0xc01d4360, strtab at 0xc01f42a0, # entries 8165
pmap_postinit: Allocated 35 static L1 descriptor tables
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
    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 6.99.24 (APC) #5: Thu Oct 24 17:27:18 UTC 2013
        root@oct.localdomain:/usr/obj/sys/arch/evbarm/compile/APC
total memory = 512 MB
avail memory = 495 MB
sysctl_createv: sysctl_create(machine_arch) returned 17
mainbus0 (root)
cpu0 at mainbus0 core 0: ARM1176JZ-S r0p7 (ARM11J V6ZK core)
cpu0: DC enabled IC enabled WB enabled LABT
cpu0: 16KB/32B 4-way L1 Instruction cache
cpu0: 16KB/32B 4-way write-back-locking-C L1 Data cache
vfp0 at cpu0: VFP11
obio0 at mainbus0
wmicu0 at obio0 addr 0xd8140000-0xd814ffff
wmtmr0 at obio0 addr 0xd8100000-0xd810ffff intr 48 : WMT System Timer
wmtcom0 at obio0 addr 0xd8200000-0xd820ffff intr 32 : WMT UART
rn_init: radix functions require max_keylen be set
boot device: <unknown>
root on md0a dumps on md0b
mountroot: trying nfs...
mountroot: trying msdos...
mountroot: trying ffs...
root file system type: ffs
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
init: copying out flags `-s' 3
init: copying out path `/sbin/init' 11
erase ^?, werase ^W, kill ^U, intr ^C

# ls /
.profile        kern            sbin            sysinstmsgs.fr  usr
bin             libexec         sysinst         sysinstmsgs.pl  var
dev             mnt             sysinstmsgs.de  targetroot
etc             mnt2            sysinstmsgs.es  tmp
# ls /usr/sbin
chroot
# ls /usr/bin
cu        gunzip    gzip      more      sed       tip
ftp       gzcat     less      progress  tar       tset
# ls /bin
cat   chmod dd    ed    ls    mv    pwd   rmdir stty
chgrp cp    df    ln    mkdir pax   rm    sh    sync
# echo hello > /foo.txt
# cat /foo.txt
hello
#
いろいろ手抜きしてますが、ちゃんと、入力してその反応を得ることができています。OSが動いてるっぽいように見えるレベルまで来ました。

ここまで来られるとは思ってもいなかったので、すなおにうれしい。