syncthing: Unable to execute on WD My Cloud (armv7l)

I wanted to install syncthing on my WD My Cloud but I get an error. I think this is related to #412

The machine is:

SpaceShip:~# uname -a
Linux SpaceShip 3.2.26 #1 SMP Tue Jun 17 15:53:22 PDT 2014 wd-2.2-rel armv7l GNU/Linux

and the error is:

SpaceShip:~/syncthing-linux-armv7-v0.10.4# ./syncthing
unexpected fault address 0x38456c
fatal error: fault
[signal 0xb code=0x2 addr=0x38456c pc=0x38456c]

goroutine 16 [running]:
runtime.throw(0x753342)
    /usr/local/go/src/pkg/runtime/panic.c:520 +0x5c fp=0x414d1eb0 sp=0x414d1ea4
runtime.sigpanic()
    /usr/local/go/src/pkg/runtime/os_linux.c:240 +0xf8 fp=0x414d1ebc sp=0x414d1eb0
code.google.com/p/snappy-go/snappy.init()
    ?:0 fp=0x414d1ec0 sp=0x414d1ec0
github.com/syndtr/goleveldb/leveldb.init()
    /home/jenkins/.jenkins/jobs/syncthing/workspace/src/github.com/syncthing/syncthing/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/version.go:436 +0x74 fp=0x414d1ef0 sp=0x414d1ec0
github.com/syndtr/goleveldb/leveldb.init()
    /home/jenkins/.jenkins/jobs/syncthing/workspace/src/github.com/syncthing/syncthing/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/version.go:436 +0x74 fp=0x414d1f20 sp=0x414d1ef0
github.com/syncthing/syncthing/internal/files.init()
    /home/jenkins/.jenkins/jobs/syncthing/workspace/src/github.com/syncthing/syncthing/internal/files/set.go:231 +0x90 fp=0x414d1f4c sp=0x414d1f20
created by _rt0_go
    /usr/local/go/src/pkg/runtime/asm_arm.s:72 +0xb0

goroutine 19 [finalizer wait]:
runtime.park(0x484a0, 0x7584b4, 0x757039)
    /usr/local/go/src/pkg/runtime/proc.c:1369 +0x5c
runtime.parkunlock(0x7584b4, 0x757039)
    /usr/local/go/src/pkg/runtime/proc.c:1385 +0x40
runfinq()
    /usr/local/go/src/pkg/runtime/mgc0.c:2644 +0xa0
runtime.goexit()
    /usr/local/go/src/pkg/runtime/proc.c:1445

goroutine 20 [syscall]:
os/signal.loop()
    /usr/local/go/src/pkg/os/signal/signal_unix.go:21 +0x24
created by os/signal.init·1
    /usr/local/go/src/pkg/os/signal/signal_unix.go:27 +0x48

I tried to downgrade to a Firmware Version < 4 but it didn’t work. Is it somehow possible to build a release that works on the infrastructure of WD My Cloud?

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 26 (2 by maintainers)

Most upvoted comments

For anyone coming here from a Google search, the problem is that firmwares from version 4 onwards use 64K pages rather than 4K. To build Go binaries for the WD My Cloud you need to apply the following patch go’s source code, then build for linux/arm.

diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c
index f091979..02f6f06 100644
--- a/src/cmd/5g/gsubr.c
+++ b/src/cmd/5g/gsubr.c
@@ -36,7 +36,7 @@
 // TODO(rsc): Can make this bigger if we move
 // the text segment up higher in 5l for all GOOS.
 // At the same time, can raise StackBig in ../../runtime/stack.h.
-long unmappedzero = 4096;
+long unmappedzero = 65536;

 void
 clearp(Prog *p)
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
index 639f4c5..6f90acd 100644
--- a/src/cmd/5g/peep.c
+++ b/src/cmd/5g/peep.c
@@ -756,7 +756,7 @@ findinc(Flow *r, Flow *r2, Adr *v)
            p = r1->prog;
            if(p->as == AADD)
            if(isdconst(&p->from))
-           if(p->from.offset > -4096 && p->from.offset < 4096)
+           if(p->from.offset > -65536 && p->from.offset < 65536)
                return r1;
        default:
            return nil;
@@ -865,7 +865,7 @@ xtramodes(Graph *g, Flow *r, Adr *a)
               (p1->from.type == D_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
                ((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
               (p1->from.type == D_CONST &&
-               p1->from.offset > -4096 && p1->from.offset < 4096))
+               p1->from.offset > -65536 && p1->from.offset < 65536))
            if(nochange(uniqs(r1), r, p1)) {
                if(a != &p->from || v.reg != p->to.reg)
                if (finduse(g, r->s1, &v)) {
@@ -1625,5 +1625,5 @@ smallindir(Addr *a, Addr *reg)
 {
    return reg->type == D_REG && a->type == D_OREG &&
        a->reg == reg->reg &&
-       0 <= a->offset && a->offset < 4096;
+       0 <= a->offset && a->offset < 65536;
 }
diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c
index c6f60ee..679a06c 100644
--- a/src/cmd/5l/obj.c
+++ b/src/cmd/5l/obj.c
@@ -91,7 +91,7 @@ archinit(void)
        if(INITDAT == -1)
            INITDAT = 0;
        if(INITRND == -1)
-           INITRND = 4096;
+           INITRND = 65536;
        break;
    case Hnacl:
        elfinit();
diff --git a/src/runtime/arch1_arm.go b/src/runtime/arch1_arm.go
index 6662eae..b2e84b8 100644
--- a/src/runtime/arch1_arm.go
+++ b/src/runtime/arch1_arm.go
@@ -9,7 +9,8 @@ const (
    _BigEndian        = 0
    _CacheLineSize    = 32
    _RuntimeGogoBytes = 60
-   _PhysPageSize     = 65536*goos_nacl + 4096*(1-goos_nacl)
-   _PCQuantum        = 4
-   _Int64Align       = 4
+   //_PhysPageSize     = 65536*goos_nacl + 4096*(1-goos_nacl)
+   _PhysPageSize = 65536
+   _PCQuantum    = 4
+   _Int64Align   = 4
 )
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
index b127345..2f912dd 100644
--- a/src/syscall/syscall_linux_arm.go
+++ b/src/syscall/syscall_linux_arm.go
@@ -6,7 +6,7 @@ package syscall

 import "unsafe"

-func Getpagesize() int { return 4096 }
+func Getpagesize() int { return 65536 }

 func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }

Note that this will break ARM builds for 4K sized pages.

I disagree, but you may ask Go devs to see if they accept contributions in this sense. I’m fairly certain that if someone offers to do the work and maintain it there’s not much reason to say no. Considering this is a free project and that there’s both a hardware and time cost (in my experience emulated system such as qemu-user didn’t work) to implement either solution, I’d not expect it to happen on its own, but only if users contribute.