Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Kirkwood hang on boot; possibly uninitialised bss



Hi all,

I'm using NetBSD-current on a D-Link DNS-325 NAS. It's a Marvell
Kirkwood 88F6281, which appears to be supported by the evbarm port
according to the kernel source.

My problem is a hang when booting.

I've made myself a kernel using the sys/arch/evbarm/conf/DNS323
configuration. The DNS-323 is actually a different SoC, but
I believe this is discovered by mvsoc_model(), and I can confirm
that kirkwood_intr_bootstrap() is called.

In other words, I think makeoptions BOARDTYPE="dns323" and
options EVBARM_BOARDTYPE=dns323 are not actually used, and
therefore that using the DNS323 on a 325 machine is okay.


Booting from U-boot:

  Marvell>> tftpboot 2000000 netbsd.gz.ub; bootm 2000000

  [snip]

  Bytes transferred = 2117011 (204d93 hex)
  ## Booting image at 02000000 ...
     Image Name:   NetBSD/dns323 6.99.7
     Created:      2012-05-21  22:17:58 UTC
     Image Type:   ARM NetBSD Kernel Image (gzip compressed)
     Data Size:    2116947 Bytes =  2 MB
     Load Address: 00008000
     Entry Point:  00008000
     Verifying Checksum ... OK
     Uncompressing Kernel Image ... OK
  ## Transferring control to NetBSD stage-2 loader (at address 00008000) ...

  [silence]

Poking around in sys/arch/evbarm/marvell/marvell_machdep.c I found the
hang occurs on the first printf(). I presume because consinit() is not
yet called. So I borrowed some code to let me write to the serial port
directly, and I'm using that for debugging:

  #define KW_UART0       (0xf1012000)
  #define KW_THR         (0x0)
  #define KW_LSR         (0x14)
  #define KW_LSR_THRE    (0x1<<5) /* Transmit enable */

  #define KW_DBG(c)                                     \
  do {                                                  \
      volatile uint8_t *kw_base = (uint8_t *) KW_UART0; \
      while ((kw_base[KW_LSR] & KW_LSR_THRE) == 0)      \
          ;                                             \
      kw_base[KW_THR] = (uint8_t)(c);                   \
  } while (0)

  #define KW_PUTS(s)                    \
  do {                                  \
      const char *kw_p;                 \
      for (kw_p = (s); *kw_p; kw_p++) { \
          KW_DBG(*kw_p);                \
      }                                 \
  } while (0)

Scattering a few calls to that in marvell_machdep.c, for the first call
to consinit:

  ...
  KW_PUTS("H CONSINIT BEING CALLED\n\r");
  consinit();
  KW_PUTS("I CONSINIT DONE\n\r");
  ...

And inside consinit:

  void
  consinit(void)
  {
      static int consinit_called = 0;

      if (consinit_called != 0) {
          KW_PUTS("CI 0 called already\n\r");
          return;
      }

      consinit_called = 1;

      ...
  }

Prints the following on boot:

  ## Transferring control to NetBSD stage-2 loader (at address 00008000) ...
  H CONSINIT BEING CALLED
  CI 0 called already
  I CONSINIT DONE

So here I presume consinit_called isn't having its static storage
initialised to 0, as I would expect. nm marvell_machdep.o says
consinit_called does indeed live in the data segment:

  000004a4 T consinit
  00000000 d consinit_called.9898

And gcc's marvell_machdep.s corresponds:

      .data
      .align  2
      .set    .LANCHOR0,. + 0
      .type   consinit_called.9898, %object
      .size   consinit_called.9898, 4
  consinit_called.9898:
      .space  4

So I believe the data segment is not being initialised correctly.
Unfortunately this is where I fall short; I have no idea where to look
next, or what to do about it.

Any suggestions, please?


Incidentally, gcc is compiling with -fno-zero-initialized-in-bss which
I presume is correct, because (I think) the bss initialisation is done
by the kernel during load. Is that right?

Thanks,

-- 
Kate


Home | Main Index | Thread Index | Old Index