[Kernel] Analyzing linux kernel Oops report easily…

In Linux, usually, kernel crashes with so-called Oops report.
This Oops report includes lots of useful information for debugging.

Therefore, I have seen lots of developer suffering from analyzing register, memory and stack dump in the report.
To analyze dumped information, memory information should be matched with source code.
But, this is not easy process.
So, I want to introduce the way to do this easily.

Main concept is, we can make tool to parse Oops report and pass these to debugging tool.
Here is introduction of my case.
I uses TRACE32 software – ARM simulator for debugging tool.
What I did is, implementing simple Perl script that parses Oops report and make cmm file that set register and memory information given by the report.
For example, auto generated cmm file is like this.

R.S cpsr 0x20000013
R.S r0 0x0
R.S r1 0x0
...
D.S 0xc035a248 %long 0xe3a02000
D.S 0xc035a24c %long 0xe3a03020
...

It’s time to use TRACE32 PowerView for ARM to analyze the report.
Launching t32marm with simulator mode -> Loading issued ‘vmlinux’ -> Runnig auto-generated cmm script
Finally, I can see stack frame with local variables and interpreted memory information by virtue of T32.

I’m sorry not to share parsing tool – Perl script – due to … as you know, something like legal issue… (I hate this.)
I hope this post is helpful for others…

[Kernel] Debugging/Controlling GPIO at user space on Linux Kernel.

To use sysfs, enable kernel config : CONFIG_GPIO_SYSFS
Core files related with this : gpiolib.c at Kernel
sysfs nodes can be found at /sys/class/gpio

[ Prerequisite ]
writing value to ‘/sys/class/gpio/export’ uses ‘gpio_request()’ function at gpiolib in kernel.
So, if given gpio is already requested by other owner, exporting is failed.
Therefore, gpio should not be owned by others in kernel to control gpio at user space.

[ How to use at user space ]
Assumption : current working directory is ‘/sys/class/gpio

#> echo [gpio num] > export
=> export give gpio to sysfs. gpioN link is newly created if gpio number is valid one.

#> cd gpioN
=> Then, several nodes (active_low, direction, value etc) can be found.
Writing or reading following nodes, is one of useful way to debug/control gpio at user space.
(attribute functions for each node are defined at gpiolib.c)

[ Detail Example ]

* at /sys/class/gpio
export, unexport : gpio number
#> echo 86 > export
#> echo 86 > unexport

* at /sys/class/gpio/gpioN
direction : in, out, low, high
value : 0, 1
edge : none, rising, falling, both
active_low : 0, 1
#> echo in > direction
#> echo 1 > value
#> echo both > edge

< See gpio.txt of Kernel document for details about each sysfs node. >

[C/C++] Tips for OOP – module initialization.

OOP SW design is usually compose of one main control routine (henceforth MCR) and lots of sub modules.
But, MCR don’t need to (must not need to) know inside implementation of every sub modules.
Sometimes, MCR don’t need to know even existence of some sub modules.
The problem is, most sub modules require initialization.
How can sub modules whose existence is now known, be initialized.
Due to this issue, principle of information hiding is sometimes broken.
Let’s see below example.

FILE : main.c
-------------
int main(int argc, char* argv[]) {
        ...

}

FILE : moduleA.c
----------------
...

FILE : moduleB.c
----------------
...

Assume that, each module requires initialization and main.c don’t need to know existence of each module.
How can we resolve this issue?
Easiest way is calling initialization function of each module with damaging principle of information hiding little bit, like mentioned above.

FILE : main.c
-------------
extern void moduleA_init();
extern void moduleB_init();

int main(int argc, char* argv[]) {
        ...
        moduleA_init();
        moduleB_init();
        ...
}

FILE : moduleA.c
----------------
...
void moduleA_init() { ... }

FILE : moduleB.c
----------------
...
void moduleB_init() { ... }

At above code, main.c becomes to know existence of moduleA and moduleB.
That is, in terms of modules, principle of information hiding is damaged although it’s very little.
Additionally, global symbol space is dirtier.
Regarding maintenance, whenever new module is added, modifying main.c is unavoidable.
But, main.c doesn’t have any dependency on newly added module.
With this and that, this way is uncomfortable.
How can we clean up these?
Using constructor leads us to better way.

Functions in constructor are executed before main function.
So, it is very useful for this case.
Easiest way is setting every initialization function as constructor.
But, in this case, we cannot control the moment when module is initialized at.
Therefore, it is better that each module’s initialization function is registered to MCR, and MCR calls these registered function at right moment.
Following pseudo code is simple implementation of this concept.

FILE : main.c
-------------
void register_initfn(void (*fn)()) {
        list_add(initfn_list, fn);
}

int main(int argc, char* argv[]) {
        ...
        /* initialize modules */
        foreach(initfn_list, fn)
                (*fn)();
        ...
}

FILE : module.h
---------------
extern void register_initfn(void (*fn)());
#define MODULE_INITFN(fn)                               \
        static void __##fn##__() __attribute__ ((constructor)); \
        static void __##fn##__() { register_initfn(&fn); }

FILE : moduleA.c
----------------
...
#include "module.h"
...
static void _myinit() { ... }
MODULE_INITFN(_myinit)

FILE : moduleB.c
----------------
...
#include "module.h"
...
static void _myinit() { ... }
MODULE_INITFN(_myinit)

Now, MCR don’t need to know existence of each modules.
And, MCR can also control the moment of each module’s initialization.
In addition, adding new module doesn’t require any modification of MCR side.
It is closer to OOP’s concept, isn’t it?

We can improve this concept by customizing memory section.
Here is rough description of this.

* Declare special memory section for initializer function.
    - In gcc, ld script should be modified.

* Put initializer function into this section.
    - __attribute__ ((__section__("xxxx"))) can be used.

* MCR can read this section and call these functions at appropriate moment.

Actually, this way is better than using constructor in terms of SW design.
Linux kernel uses this concept in it’s driver model.
(For deeper analysis, kernel source code can be good reference.)
But, in many cases, using this concept may lead to over-engineering.
So, if there isn’t any other concern, using constructor is enough.

[C/C++] Encapsulation tip in C.

Usually, pointer of not-opened-structure is used to hide module’s information.
C dummies may use ‘void*’ to do this. But, it’s not good way.
Let’s see following example.
(Following codes are test in GCC4.4 with ‘-Wall’ option.

typedef void module_t;             /* <-- *1 */
typedef struct _sModule module_t;  /* <-- *2 */

module_t* create_module(int arg);
int       do_something(module_t* m, int arg);
...
do_something((int*)m, 1); /* <-- *a */

Pointer of any type can be casted to ‘void*’, and ‘void*’ can be casted to pointer of any type without warning.
So, in case of (*1), (*a) doesn’t generate any warning. That is, it is NOT TYPE SAFE (in compile time).
But, in case of (*2), GCC give warning like “… incompatible pointer type …”. It’s TYPE SAFE.
And, interestingly, compiler doesn’t complain anything about (*2) because, compiler doesn’t need to know size of ‘struct _sModule’.
Only pointer is used. So, knowing size of pointer type is enough and compiler already know it.
So, in terms of syntax, it’s ok too!

[C/C++] Tips and Memos

* Boolean to integer – C.

Let’s think about the function that return 0 if false, otherwise 1.

 => Naive way : return (e)? 1: 0;

C doesn’t support boolean type. Instead, 0 is false, non 0 is true in C.
There is no fixed value to represent TRUE.
But, as defined by 4.5/4, boolean true is promoted to 1, boolean false to 0.
So, we can improve this to

 => Better way : return !!(e);

And this way is also useful because we can get fixed integer value – integer 1 – for TRUE boolean value.

* The ORDER that function PARAMETERS are EVALUATED, is NOT SPECIFIED.
The only requirement is “Those should be fully evaluated before function is called.”

[Tips] Cyclic Queue

It’s very-well-known tip for cyclic queue!
Here is pseudo code!
(Even if this is very -well-known and not difficult to think of, it’s worth to remind.)

TYPE Q
    item[SZ] // queue array
    i        // current index
...

FUNC addQ (q, item)
// This is Naive way.
    item[q.i] = item
    if (q.i >= SZ) than q.i = 0

// This is well-known way
    item[q.i] = item
    q.i &= SZ-1 // For this, SZ should be (2^n (n>0))