Wednesday, December 28, 2011

Serial Port on BlackArmor NAS

I found my old Samsung x426 USB cell phone programmer cable as I was cleaning out my home office. I might have mentioned this cable earlier when I wrote about adding a serial console to the BlackArmor NAS.  The cable is a really old style one that has a weird connector for the cell phone way before the mini-USB became standard. The interesting thing about this cable is that it has a serial to USB converter chip (2303HXC 0546) that does the magic of converting serial to USB. That is why that thing was ridiculously expensive ($35) when I bought it back in the day.

Why this is even on my radar as possible is that the website CrapNAS had an entry for how to connect a serial or USB cable so you can watch the Linux boot up as a serial console session. They specify two different ways to do this. For the serial connection, they specify a MAX3232 as necessary.  The USB connection has a schematic that includes a 2303HX. I'm not sure what the difference is between that and my 2303HXC so I will be doing some reading before I cut into the cable and get out the soldering iron.

Why am I even messing around with a serial console?  Because as I am planning to mess around with the lower level system, I should have a back out plan if I do something wrong. A serial console on the device gives me more options during the boot up even if I cannot connect via a network connection.

As far as getting time to work on the compiler toolchain, I've been relaxing over the holiday break with family, cleaning my messy home office and have not even booted up the virtual machine since my last post. I intend to get back to it someday.

Thursday, December 22, 2011

Seagate Black Armor NAS

Yeah it's been hectic at work and lots to do in domestic life as well so this hobby project hasn't gotten much attention. Christmas break is coming however and I'm planning on getting some time to work on it. I think most Open Source projects or hobbies get a boost over the holidays.

Merry Xmas & Happy New Year in case I don't get back here before the holidays.

Sunday, December 4, 2011

Newlib error during compile

Earlier I was working on the problem with compiling using the arm-elf-gcc on very basic programs.  After some work, I found the base problem is that the libc replacement from newlib are not being picked up at compile time and properly using the syscalls mechanism. Hardwired hacks to work around it produced an executable but something is still wrong with how the compiler was built.

I've distilled the error down to a single search.

Google Search: "/lib/libc.a(lib_a-exit.o): In function `exit':" "newlib/libc/stdlib/exit.c:65: undefined reference to `_exit'"

Several other people appear to have run into the same problem, so I'll be reading up on the problem and see what solutions exist.

Saturday, December 3, 2011

Compilation failures

The problem is that I can get an ARM executable but not sure why the default system is not working to produce a basic HelloWorld.

$ cat test.c
int main (){return 0;}
$ arm-elf-gcc test.c -o test
...
/home/mcgarrah/DevelToolbin/binaries/arm-4.4.6/bin/../lib/gcc/arm-elf/4.4.6/../../../../arm-elf/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text+0x54): undefined reference to `_exit'
collect2: ld returned 1 exit status

$ arm-elf-gcc test.c -o test -v
This spews a couple of pages of additional output which points me to something called the "Using built-in specs" and lots of directory path information for various things like include files and libraries. These all look about right. A directory /DevelToolbin/binaries/arm-4.4.6/arm-elf/lib has some interesting lib files in it.

$ arm-elf-gcc test.c -o test ~/DevelToolbin/binaries/arm-4.4.6/arm-elf/lib/redboot-syscalls.o
$ file test
test: ELF 32-bit LSB executable, ARM, version 1, statically linked, not stripped

When you are facing a missing library like the above issue, you typically just have to find the right library and add it to your build.  In this case we are missing something so fundamental that we need to figure out why it is broken or will hit future issues.

While finding the above syscall libraries, I noticed some files called specs files which are:
  • linux.specs
  • rdimon.specs
  • rdpmon.specs
  • redboot.specs
RDP, RDI, RedBoot and Linux are all syscall (system call) protocols. A syscall protocol describes how a libc (standard C library) communicates with the operating system kernel. For our case this library is newlib which uses another syscall protocol called libgloss as an interface between libc and the above syscall protocols.  I'm not sure which protocols are the default but something is not right about this combination.

$ arm-elf-gcc -dumpspecs
This dumps even more output that is even more cryptic but looks important when taken with the above information. There are built-in defaults for GCC that are being overridden by these specs files.

There is an options to change the specs entries from the GCC command line which I use to identify what is happening.

$ arm-elf-gcc test.c -o test -specs=redboot.specs
$ arm-elf-gcc test.c -o test -specs=pid.specs
$ arm-elf-gcc test.c -o test -specs=linux.specs

The pids and redboot files are a very minor difference in a setting so are essentially the same.  Linux is significantly different as a system call interface.

$ arm-elf-gcc test.c -o test -specs=rdimon.specs
$ arm-elf-gcc test.c -o test -specs=rdpmon.specs

Both the RDI and RDP return basically the same error as the above missing library.  So we have identified what is probably the default libraries used by libgloss.

This is just a journey down the rabbit hole. So I need to revisit the newlib build process and see what I did wrong in it.

Update December 4th, 2011 7:30pm: What you see above happens in both the gcc 4.4.6 and gcc 4.3.2 compiled software sets. Same exact problem for both versions of gcc and associated other libraries. I did a full rebuild of the 4.3.2 and did some tracing of the path built into gcc and re-verified paths to all libraries. Same issue still happens. So we have a genuine problem in the build process that is impacting the compiler.  Could be in any place across the binutils, newlib or gcc compilations. So I'll be digging into each. The nice part is it looks like a common problem so if I fix it in the 4.3.2 series then it will probably fix in the 4.4.6 series as well.

Thursday, December 1, 2011

Toolchains compiled

Two full toolchains built and a third that I still think might be made to work.  The first is using older versions of everything and was mostly done as a test to get the build environment working against known sources that are known to build. Even this known build process required some effort to get working in a current OS environment. Those docs, notes and scripts will be coming in the near future.

So to outline what works and not, I give you the following.

Toolchain that comes from older versions of software and the docs from Tom Walsh:
  • binutils-2.19.1a.tar.bz2
  • gcc-4.3.2.tar.bz2 (with a patch from Tom)
  • newlib-1.16.0.tar.gz (with a patch from Tom)
  • insight-weekly-CVS-7.0.50-20091130.tar.bz2
Newest versions that compiled based on Tom's scripts:
  • binutils-2.22.tar.bz2
  • gcc-4.4.6.tar.bz2
  • newlib-1.19.0.tar.gz
  • insight-CVS-20111130.tar.bz2 (pulled from CVS head and required patching by me)
Newest versions that fails to compile in GCC in zlib:
  • binutils-2.22.tar.bz2
  • gcc-4.6.2.tar.bz2
  • newlib-1.19.0.tar.gz
  • insight-CVS-20111130.tar.bz2 (pulled from CVS head and required patching by me)
The issue in GCC is well documented (if you know what you are looking for) as a bug in the "--enabled-multilib" during the build. The zlib library that is packaged with the GCC source fails to build in a cross-compiled configuration. Who knew that GCC packages their own copy of zlib in the GCC sources? There appear to be a couple of solutions which might fix the problem. The first is to just use the native zlib from the host system and pass in "--with-system-zlib" but that feels like a hack instead of a fix. The other is to revert a change in GCC that is documented in a couple of places (Bug45174 and Bug43328). This is a bug in the "configure" phase of the standard "configure;make;make install" but shows up in the "make" stage. So, I'll revisit this as time permits and see about getting the latest GCC 4.6 series working.

The more exciting thing is that it looks like both GCC versions that compiled will compile code to an intermediate state.  That is not proof that it generates a working executable but it is a step in the right direction.

For the GCC 4.3.2 version here is a test showing it compiling a quick test.
$ cat > test.c
int main (){return 0;}
Ctrl-D
$ ./arm-elf-gcc -Os -S test.c
$ cat test.s

        .file   "test.c"

        .text
        .align  2
        .global main
        .type   main, %function
main:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        mov     r0, #0
        bx      lr
        .size   main, .-main
        .ident  "GCC: (GNU) 4.3.2"

For the GCC 4.4.6 version here is a test showing it compiling a quick test.
$ cat > test.c
int main (){return 0;}
Ctrl-D
$ ./arm-elf-gcc -Os -S test.c
$ cat test.s

        .file   "test.c"
        .text
        .align  2
        .global main
        .type   main, %function
main:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        mov     r0, #0
        bx      lr
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.6"

While this is good news, it is not an ARM executable. My followup post will not be so upbeat.

Cross-compiler toolchain update

I've been working on building a toolchain using the notes from OpenHardware Building the ARM GNU 4.3.2 with some success. I finally got the base set of GCC 4.3.2 tools to build successfully. I have not used the resulting GCC to produce an ARM executable or verified the executable works on the Black Armor NAS. Those are tests for tomorrow evening when I can get the NAS setup again on the network. It is currently in a box in the corner.

There were several minor things that needed to be updated and modified to get the scripts and environment to work. I've kept careful notes and will post those in the next couple of days once I've tested the output from the compiler works. I'm also attempting to update the versions of the libraries and software to more current versions as well. The GCC 4.3.2 and associated libraries are several years old and I'm trying to get the GCC 4.6.x to build along with newer newlib, binutils and insight/gdb using the same basic set of notes and scripts. I bumped into a zlib issues in the second phase GCC build that stumped me for the night. I'll hit it again tomorrow. Again, I'm keeping careful notes and build docs for the newer version as well.

The dependencies from the operating system are sometimes a pain to track down for the software. I picked a very stripped down install of Ubuntu. The operating system I am using is Ubuntu Server 11.10 because it is easy to install and update. Any Linux would do but the package names may change. Ubuntu Server has no frills so you add everything you need which means all the libraries like GPM, etc.

So there is some progress and in the next couple of days I'll let you know if the build produces working ARM executables. I'm really excited about getting a working "HelloWorld" out there.