14 Replies Latest reply on Jan 19, 2013 8:53 PM by mziwisky

    BareMichael baremetal framework


      BareMichael is a minimalistic, open source baremetal framework for launching your C and/or assembly code on the SCC.  There is just enough code to get each core into 32-bit protected mode with cache enabled, and then jump to your code.  Also included are a subset of the standard C library and a pseudo-terminal program (called MikeTerm) for displaying output from your SCC programs.


      As this is a minimalistic framework, there is no built-in API for message passing, nor any typical OS features such as process/thread abstractions, but there is a good amount of groundwork laid to allow one to design and add in these or other features as needed.


      The latest version can be downloaded from:



      Please see the README (included in the download) for more information.

        • 1. Re: BareMichael baremetal framework

          Hi Mike,


          Thank you very much for providing baremichael. I'm working with your baremichael v4 and I have a few question.

          I may propose some enhancement I want to share how shall I do that?

          Shall I send you patches?

          Could we setup a github for that?


          On a more technical side, could you explain me why you need to have "startup.o" file appear first on the link line?


          The reason I'm asking is because I try to build baremetal applications in which differents

          applications may be easily mapped onto different cores.

          I did this by first modifying your Makefile and adding a sibling main2.c in test directory

          (files are attached to this comment).


          Then in order to ease the use of this for other collegues I decided to try a wrap-up of this uisng CMake (www.cmake.org)

          which enables something like this to be written:


          # Build one application image
             APPNAME "image1"
             LDSCRIPT ${PROJECT_SOURCE_DIR}/compile/ld.script
             IMAGE_ADDRESS ${IMG_ADDR}
             C_SOURCES test/main.c


          # Build another application image
             APPNAME "image2"
             LDSCRIPT ${PROJECT_SOURCE_DIR}/compile/ld.script
             IMAGE_ADDRESS ${IMG_ADDR}
             C_SOURCES test/main2.c


          using those macros you can "compile" several baremetal application and then "map them"

          on specified core using the following (see APPLICATIONS_MAPPING argument)


          # Now we define the map of the application onto the SCC cores.
            MT_TEMPLATE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/compile/appli.mt.in
            MT_FILE ${MT_FILE}
            APPLICATIONS_MAPPING APP;image1;00;18;2F;APP;image2;04;05


          This create the appropriate mt file (and deploy and run scripts) which can further be used by sccMerge.

          I'll post all of this when it's polished a little further.

          So my question why should startup.o appear first on the link line?

          Shouldn't the linker find the symbol whatever the order on the link if there is no duplicate?

          • 2. Re: BareMichael baremetal framework

            Hello Eric,


            First off, sorry for the delay.  Turns out I wasn't subscribed to this thread, so I never got an email about your post.  I've now subscribed so I'll stay up to date on activity here.


            Second, you said you're working with v4 -- please update to v5.  There is no difference in any code, so it should be rather painless -- v5 only adds some acknowledgements in comments that should have been in v4 in the first place.  I've attached a patch file to make this easy for you.  If you `cat` it, you'll see that all it does is modify comments in two header files and in the README.  To apply it, copy bm4to5.patch to your baremichael directory (it's OK if you renamed that directory), `cd` to that directory, and type `patch -p1 -i bm4to5.patch`.  As long as you haven't really messed with include/apic.h, include/scc.h, and README, I think everything should be fine.


            Now, on to your questions.  On the topic of sharing your enhancements -- I'm currently figuring what's going to be easiest.  Ultimately I'll probably set up a public SVN repository, but I'm going to see what my PI thinks first.  I should have something arranged soon, and I'll report back here when I do.


            About putting "startup.o" first on the link line -- the code in boot/getprotected.S ends with a long jump to a hardcoded memory address which is set in the Makefile as "IMG_ADDR = 0x28f00000".  The linker creates a binary file that places the .text section at IMG_ADDR (due to the flag "-Ttext $(IMG_ADDR)"), but it seems that the particular code it places at that address is always the .text section from the first file that is listed, so we must make sure that it looks at startup.o first.  Though I use both the "-e _start" flag for the linker and the line "ENTRY(_start)" in the ld.script file, it seems that these have nothing to do with the placement of the entry point in the image.  That flag and line could probably be removed without harm, but it ain't broke, so I haven't fixed it.  I think perhaps if the output format weren't straight binary, but ELF or something else, then maybe the output file would include information indicating that the program should enter at the function _start(), but because it's straight binary, that info is omitted.


            I've suspected that it's probably easy to load different images to different cores by simply changing the .mt file, but I haven't had a need for it, so I never took the time to try it out, nor mess with the make system to do it elegantly.  But it looks like you're getting it done nicely, and I'd be happy to add in your contributions once you have them in a state you're satisfied with.



            • 3. Re: BareMichael baremetal framework



              Regarding sharing enhancements, I don't anticipate there being many people who will be making a lot of contributions, so for now you can just send me patches.  I'll apply them and add the new tarballs to the Intel SVN repo with the rest of the releases.  If there ends up being a lot more interest in making contributions later on, then I may move everything to a shared space for convenience.



              • 4. Re: BareMichael baremetal framework

                OK right Mike,


                I'll do that. Thank you for your anwsers and feedback.

                • 5. Re: BareMichael baremetal framework

                  Hi everyone,


                  I just started using the Baremichael framework and I have quick (hopefully) regarding the access to the global timestamp counter. According to the documentation of the SCC Kit 1.4.x it should be accessible using the LUT address 0x9f000000 + 0x08228 or 0x8224 but if I try to access it I get an error message. Did anyone successfully access the global timestamp with Baremichael?


                  Thanks a lot in advance!


                  Best regards,



                  • 6. Re: BareMichael baremetal framework

                    Hello Johannes,


                    I don't know anything about a global timestamp counter (what document mentions it?), but the next release of BareMichael will include a getticks() function to read the core's local time stamp counter.  I'm almost ready to release that version (which will include built-in support for RCCE baremetal), but in the meantime, the getticks() function is below:


                    * Read x86 time stamp counter. For timing stuff.
                    * Typical usage:
                    *     unsigned long long start, end;
                    *     start = getticks();
                    *     ... [code to time] ...
                    *     end = getticks();
                    *     printf("Execution time: %u cycles\n", end - start);
                    * Note, libxc does not support printing an unsigned long long (%llu), so a
                    * better usage will check whether the upper half of the result of
                    * (end - start) is 0.
                    unsigned long long getticks()
                        __asm__("pushl   %%ebx;":);
                        __asm__("movl    %%eax,-8(%%ebp);":);
                        __asm__("movl    %%edx,-4(%%ebp);":);
                        __asm__("popl    %%ebx;":);



                    • 7. Re: BareMichael baremetal framework

                      Hi Mike,

                      thanks for the quick response. The global timestamp is mentioned in the documentation of the SCC kit 1.4 (sccKit14x_UsersGuide_Part8.pdf and I think also in the WhatsNew140.pdf) apparently it's an extra entry in the LUT accessing a FPGA register. Thanks for the code to access the local timestamp I'll give it a try tomorrow. One question in baremichael are you setting up the LUTs specifically or is the default configuration used?

                      Best regards


                      • 8. Re: BareMichael baremetal framework



                        I see the problem now -- by default, addresses in the range 0xf9000000 - 0xf9ffffff are unmapped in the pagetable.  As a quick fix, change line 47 in boot/initPaging.c from:

                        MAP(0xe0000000, 0xe0000000, 0xf9000000, PTE_P | PTE_RW | PTE_CD);


                        MAP(0xe0000000, 0xe0000000, 0xfa000000, PTE_P | PTE_RW | PTE_CD);

                        (i.e. the third argument should be 0xfa000000 rather than 0xf9000000)


                        I'll add this to the v6 release, along with some new definitions in include/scc.h for the FPGA registers.  Regarding the LUTs, the default configuration is used.



                        • 9. Re: BareMichael baremetal framework

                          This conversation has spurred me to finalize and release v6.  It's now available in the repository.  Highlights of the new version:


                          -- RCCE support (see the README for instructions).

                          -- Inclusion of pagetable entries for FPGA registers that have been around since sccKit 1.4.0 came out (i.e. addresses 0xf9000000--0xf9ffffff).

                          -- MPB pages now use PMB flag and not CD flag by default.  I.e. MPB space no longer has cache  disabled, and is now marked as MPBT data.

                          -- getticks() function added for reading local x86 timestamp counter.


                          I've also added patches to the repository that can be used to upgrate from version x to version x+1.  Patching might be problematic if you've been working on the framework yourself and modifying files, but in that case the patches at least serve as nice diffs so that you can see the details of what's been changed since the last release.


                          • 10. Re: BareMichael baremetal framework

                            BareMichael v7 is now available.  The only difference between it and v6 is an update to MikeTerm.  The update allows more than one user on a machine to use MikeTerm without problems.


                            Details, if you care for them:  Previously, MikeTerm would call sccDump and store its output to a temporary file, then read from that file and parse the output to determine what to display.  This is problematic because the temporary file would stick around after MikeTerm closed, and it did not have write permissions for other users.  Therefore, when another user would run MikeTerm, it would fail to write to the temporary file, and error out.  The new version uses a more appropriate popen() call to establish a pipe between sccDump and MikeTerm, which eliminates the need for the temporary file.


                            === ONERA extensions ===


                            Also added to the repository is a contribution from Johannes Scheller and Eric Noulard of ONERA.  Their work extends v7 to facilitate non-SIMD programming of the SCC (i.e. loading and running different images on different cores).  It is hosted at http://marcbug.scc-dc.com/svn/repository/trunk/baremetal/baremichael/ONERAtarballs/



                            • 11. Re: BareMichael baremetal framework
                              Richard Lee

                              Hello Michael,


                              I am trying the baremichael v7, and now has two little questions.


                              1. Why do you use the objcopy in the Makefile. I have tried the lines you have commented without objcopy, and it run successfully. But I think it must be some reasons why you use it.

                                  Just curious about it.


                              2. I tried to write a character to the memory position of 0x80000000 in the file startup.S , right before platforminit() was called. And it does not work. Is that because the IDT has been filled in? But I think I only write to the memory region, which may not trigger any interrupt. Is that right?

                                  So why I can not write to the address before platforminit() is called?(I only use a simple mov instruction)


                              I am a student,  interested in the SCC.

                              Thank you in advance!


                              Best regards,


                              • 12. Re: BareMichael baremetal framework

                                Hi Richard,


                                1.  Good question.  It's only for debugging purposes.  I link all the objects into an elf file first, then objcopy that elf to a pure binary file.  The binary is what gets loaded onto the SCC, but I like having the elf file so I can objdump it when debugging.  You can safely skip this step and just link straight to a binary without consequence.


                                2.  When you say it does not work to write a character to 0x80000000, I assume you mean that you try writing it, then run your code, then perhaps use sccDump to try to see that character.  If that's the case, try putting a HLT opcode after your write, so that platforminit doesn't run.  Here's the explanation.  BareMichael communicates with MikeTerm via a bounded buffer.  When you call printf() in BareMichael, the formatted string of characters get written to a location in SCC shared memory (e.g., for core 0, they're written to a buffer starting at 0x80001000), and a head pointer is updated to indicate how far into that buffer you've written.  That head pointer for core 0 is located at 0x80000000.  platforminit() calls initPrintBuf(), which initializes that location to 0, which of course would overwrite any character you had previously written there.  I chose to use shared memory space for the buffer arbitrarily, and partly because I never used that space for anything else in my own work.  If you'd rather have that space for other purposes, it wouldn't be too difficult to change the location of the buffer.  Just make sure you change it in MikeTerm too (this would be the more tedious part, since miketerm.cpp is not a pretty sight!)


                                Hope that helps.  Let me know if you're still confused about anything.



                                • 13. Re: BareMichael baremetal framework
                                  Richard Lee

                                  Hi Mike,


                                  Thanks so much for the reply.

                                  I am now quite clear how baremichael works with your reply and the paper you have published and the code with nice comments.

                                  It is my first time to get in touch with baremetal things, and I've really learnt quite a lot from the work you have done.

                                  Thanks again!




                                  • 14. Re: BareMichael baremetal framework

                                    You're welcome -- happy to hear when people find my work helpful