I have multiple boards which were having different screen sizes(4",7",12" etc...). I need this info at multiple places in the Linux Kernel during boot time. We can know the device screen size by reading values on two input lines. I don't want to read every time these lines whenever I want to know the device screen size. I want to read these lines once at the beginning(maybe in the board file) and store it in a global variable. Check this global variable value where ever I need the screen size. Can anyone suggest where I can declare this global variable or any better way for this?
-
Object oriented programming says the data should be encapsulated (in a function) instead of using a global variable. – sawdust Dec 23 '22 at 17:05
-
@sawdust Thanks for making me think in the direction of using Object oriented concepts in C. My understanding based on your comment is that declare a set/get functions to modify/access the variable. In the C++ examples related to encapsulation, the variable is declared as private so that the variable can't be accessed directly(it can be accessed only through set/get functions). In C, is there any way to restrict the variable same as C++ private(i.e it can't be accessed directly, but can be accessed only through set/get functions). – Ravi A Dec 27 '22 at 05:48
-
For the matter of fact, the Linux kernel has a global variable for the framebuffer. You may (re-)use it. (Hint: look at the implementation of EFI early console) – 0andriy Dec 27 '22 at 18:20
-
1"*In C, is there any way to restrict the variable ...*" -- Only in a limited way. See description of "static global variable" in https://stackoverflow.com/questions/572547/what-does-static-mean-in-c/572550#572550 Within the code module, you still have direct access to the variable, and therefore could bypass the "encapsulation" of the data. When the language doesn't enforce OOP and/or structured style, you have to use self-discipline to implement them. – sawdust Dec 28 '22 at 04:08
-
There are several ways to for data to be "shared" in the kernel, but I'm a bit confused by the statement that you are reading values on "input lines" from kernel space at boot time. How does your kernel read these input values at boot time? – Robert McLean Dec 28 '22 at 16:46
-
@RobertMcLean These "input lines" are gpios. So using Kernel's gpio functions we can read the gpio values. – Ravi A Dec 30 '22 at 01:09
1 Answers
So you've given some thought to your problem and you think a "global" variable in the Linux kernel is the fastest/best solution. Where a "global" variable is a variable that one module defines and initializes and other modules can also read and modify it. You can do that by exporting the symbol with the EXPORT_SYMBOL macro.
As an example, look at this file on lines 54 and 55 the symbol drm_debug
is declared as an unsigned int
and exported for other driver modules to use. The other modules need to be informed about that symbol's existance before they can use it. In this case, that happens in this header file on line 781. So when another file or module wants to use that symbol, that source file includes the header, and then it just uses the variable as if it were declared in that file. If you don't want to create a header file for your "personal" global variables, you can just add that "extern" as a 1-liner to your global scope declarations for that source code file, and it will have the same effect.
In addition to exporting variables, you can also export functions in the same fashion. If you grep for "EXPORT_SYMBOL" in your kernel most of the hits are going to be functions. When you pass around a variable there is the chance that one module might change it at an inopportune moment when another module might be reading it causing undesired outcomes. I like to think of the function as a "read only" version of a variable, so only one module can change it, but everyone else can see it. Having one module being "responsible" for reading and interpreting the GPIO and then sharing that information with other modules to me seems to fit better with the exported function than with the exported variable.
Lastly, whenever you start sharing symbols in the kernel, you should give thought to the name of the global variable you choose. For example, don't take something that's already taken or likely to be taken.

- 196
- 1
- 8