From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bart Veer To: sgj0@yahoo.com Cc: ecos-discuss@sourceware.cygnus.com Subject: [ECOS] Re: How big is ecos kernel? Date: Mon, 25 Oct 1999 09:23:00 -0000 Message-id: <199910251623.RAA29065@sheesh.cygnus.co.uk> References: <19991021111359.18863.rocketmail@web504.yahoomail.com> X-SW-Source: 1999-10/msg00083.html >>>>> "Slawek" == Slawek Grajewski writes: Slawek> Hi, I'm looking for the information of how big (in KBs) Slawek> the ecos kernel is after compilation. I realize that it Slawek> depends on target and compilation options, but I'm still Slawek> interested in some numbers. Is it 256KB, more ... less? This is a very hard question to answer, and not just because there are dependencies on the target and on the compilation options. There is not really any such entity as "the eCos kernel". Instead eCos involves a number of different packages, which are combined to provide the necessary functionality. A bare bones system consists of an architectural HAL package containing the processor-specific code, a platform HAL package for board-specific code, and an infrastructure package. Depending on the target this may only involve some hundreds of bytes, but the functionality is limited to bootstrap and then transferring control to the application. More likely you will want to use some additional packages and get greater functionality. These include device drivers, the C library, and the maths library. In addition there is a kernel package which implements functionality usually associated with RTOS's such as threads, mutexes, semaphores, and so on. The kernel package is not stand-alone, it depends on functionality provided elsewhere and especially on the HAL packages. The kernel provides its own API. It is possible to layer a standard API on top: the current release includes an implementation of the uITRON standard, others such as POSIX are planned. Using one of these compatibility layers makes it easier to port code, at the cost of increased code size. When you build eCos you do not end up with a single kernel image. Instead you have a library, libtarget.a, which you link with your application code. At link-time any functionality that is not required, directly or indirectly by your application, is eliminated. For example if your application does not need dynamic memory allocation then the relevant code will not get linked in to your application. Cygnus has enhanced the GNU linker to operate at the grain of individual linkable entities such as functions and variables, in order to eliminate overheads. In addition eCos is a highly-configurable system, often giving you control over what happens at a very fine grain. For example, by default the kernel thread structure contains support for per-thread data. If your application does not need this then you can configure this out, saving a word of memory for each thread object. A while back one of my colleagues did some analysis, reproduced below, indicating that a "typical" kernel would be about 25K. This would be for the HAL, infrastructure and kernel packages, but not the C library or the maths library. Also the test program uses most kernel functionality, so your application might need less kernel code. The measurements were done for only one target. For a more exact answer, there is no real substitute for downloading eCos and trying it out for yourself. You can write a dummy piece of code that just makes calls to all the kernel and other functions you might need, link it with eCos in its default configuration and built for the particular target you are interested in, and look at the size of the resulting executable. Make sure that you use e.g. the arm-elf-size command to examine the final executable rather than the file size, because the latter contains lots of debug and other information that is only used on the host. Bart Veer // eCos net maintainer ------------------------------------------------------------------------ Here are some sizes of system objects and executables for POWERPC. Kernel Object Sizes ------------------- All sizes in bytes: Thread 168 (+ its stack, of course) Semaphore 8 Mutex 12 Condition variable 8 Message box 56 (10 item queue size @ 4bytes/item) Flag variable 8 Fixed memory pool 36 (+ the memory it manages) Variable memory pool 44 (+ the memory it manages) Interrupt 28 Cyclic alarm 40 Oneshot alarm 40 Counter 24 (the thing alarms hang off) The Realtime Clock 64 (one special counter that ticks off hardware) Executable Sizes ---------------- A maximal kernel that supports both the uITRON and native C APIs in full contains about 56k of code. A complex test program that uses most features of the uITRON API, linked with selective linking, uses a more typical kernel of about 41k. A complex test program that uses most features of the native C APIs, linked with selective linking, uses a more typical kernel of about 25k. Justification follows ("show your working"): We will look at the sizes of a couple of tests, plus the uITRON compatibility functions. tm_basic is a kernel native C API test that uses most kernel features: fully linked executable: install/tests/kernel/tm_basic object for "app" part: kernel/current/tests/kernel_tm_basic.o test7 is a uITRON testcase that uses most uITRON features: fully linked executable: install/tests/uitron/test7 object for "app" part: compat/uitron/current/tests/uitron_test7.o uITRON functions: compat/uitron/current/src/uitron_uit_func.o Selective linking text data bss filename 45016 4492 51216 install/tests/kernel/tm_basic 20048 84 44672 kernel/current/tests/kernel_tm_basic.o 48952 3428 43768 install/tests/uitron/test7 8644 176 1000 compat/uitron/current/tests/uitron_test7.o 15520 4 0 compat/uitron/current/src/uitron_uit_func.o So we can infer that the size of: a typical kernel is 45k - 20k = 25k. a typical uITRON kernel is 49k - 8.5k = 40.5k. the uITRON layer code is 15.5k; this tallies above. Normal linking (only the final executables differ) text data bss filename 60460 4500 51216 install/tests/kernel/tm_basic 57200 3444 43768 install/tests/uitron/test7 So we can infer that the size of: a kernel is 60.5k - 20k = 40.5k. a uITRON kernel is 57k - 8.5k = 48.5k. the uITRON kernel will not use the native C API (4.5k), binary semaphores (1k), and mutexes (2k); these add up to 7.5k, so, by adding that 7.5k to the uITRON kernel size we get a maximal size for a kernel which supports both uITRON *and* native C APIs: a maximal kernel is 48.5k + 7.5k = 56k this tallies nicely with adding the uITRON layer to a C API supporting kernel with all functionality included: a C API + uITRON kernel is 15.5k + 40.5k = 56k So 56k is a sensible upper bound for kernel size; though very complex test programs which use a broad spread of features in fact use a considerably smaller subset if selective linking is enabled. Note: the uITRON compatibility layer is comparatively large because of all the error checking - usually of constant arguments - that is required by the uITRON specification; if the error checking of "normally constant" arguments is disabled by configuration (a sensible thing to do once an app is debugged) the size of the compatibility function set is reduced to 12k.