LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-06-2010, 07:48 AM   #1
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Rep: Reputation: 22
LKM: how to setup a stack?


I need to call some other functions in "int init_module(void)" and module.
So I need a stack.
How can I setup a stack (1kB) for my module in C?
 
Old 09-06-2010, 08:38 AM   #2
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Hi,

do you mean something like this?
http://en.wikipedia.org/wiki/Stack_%28data_structure%29
 
Old 09-06-2010, 08:43 AM   #3
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Original Poster
Rep: Reputation: 22
Yes.
 
Old 09-06-2010, 10:12 AM   #4
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Original Poster
Rep: Reputation: 22
Quote:
Originally Posted by crts View Post
Hi,

do you mean something like this?
Do you know how to define a stack that it is handled right by ld (gnu binutils ld, gcc) and setup right for use?
 
Old 09-06-2010, 02:27 PM   #5
ArthurSittler
Member
 
Registered: Jul 2008
Distribution: Slackware
Posts: 124

Rep: Reputation: 31
stack setup is done by C compiler

Your example was written in C. Among many other things done by the compiler as it generates the machine-code translation of your source code, the compiler sets up the user stack for your program. This stack is used to handle the return address from each called subroutine, the parameters, and the local automatic variables used within the subroutine. That is, you do not need to set up the stack, the compiler and linker and loader set up a stack for you. This involves initializing the stack segment register and the stack pointer register, along with allocating some address space for the stack. The allocated space should be initialized to all zeros somewhere along the way, probably by writing a zero dword to some address and block copying the zero dword through the entire block allocated to the stack. Setting up the preamble code and exit code is a large part of the reason that a simple hello, world program is as large as it is. The actual part of the program that prints hello, world is twenty bytes or so from your source code and perhaps a hundred bytes or so from the required routine in the stdio library.

If you wish to look at the assembly language code generated by a simple program, you can tell cc to keep the assembly language output in file and look at it with a text editor. For this you may wish to use an even simpler program than hello, world, something like
Code:
void main(void)
{
    return;
};
Your system may require a more complicated declaration for main(), in which case you may need to make the program slightly more complicated. I hope you get the idea.

The references in the previous responses involve setting up a stack of program data items. This typically involves defining a struct which contains a pointer to its own type to link it into the stack, and data and/or pointers to data that you want the stack to contain.

I hope this is not too confusing. I am just trying to make a distinction between the hardware machine-level stack implemented with the stack pointer register and the user-level implementation of data stacks.
 
Old 09-06-2010, 04:00 PM   #6
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Original Poster
Rep: Reputation: 22
Quote:
Originally Posted by ArthurSittler View Post
Your example was written in C. Among many other things done by the compiler as it generates the machine-code translation of your source code, the compiler sets up the user stack for your program.
Sorry, we are talking about LKM (Loadable Kernel Module) here.
But maybe you can say how to define the stack so it get maybe 1 kilo byte big no more or less so I get a working stack in my LKM (GDT or LDT task).
The stack have to be setup by ld (mem) and maybe a kernel function.
Oh, wait maybe a syscall can do it? ... - No.
Yes, it could be a multicore (4-core) issue that the kernel's stack is in an other core than the module is loaded to. That it could explain, why the stack did work some time.

Does anybody know something about this issue? - and maybe a solution or how to setup a working stack? (hint: ENTER does not work, because it needs a working stack)

Can the kernel be configured to only load modules into its core?

Last edited by bastl; 09-06-2010 at 04:01 PM.
 
Old 09-06-2010, 06:26 PM   #7
ArthurSittler
Member
 
Registered: Jul 2008
Distribution: Slackware
Posts: 124

Rep: Reputation: 31
Allocate memory and manipulate it as a stack

obsolete -- please refer to edited version

Last edited by ArthurSittler; 09-06-2010 at 11:46 PM. Reason: replaced by later copy of post
 
Old 09-06-2010, 11:40 PM   #8
ArthurSittler
Member
 
Registered: Jul 2008
Distribution: Slackware
Posts: 124

Rep: Reputation: 31
Allocate memory and manipulate it as a stack

I recommend Linux Device Drivers by Corbett, Rubini, and Kroah-Hartman (ISBN 978-0-596-00590-0). They address the problem of limited kernel stack. They point out that the stack for the entire kernel may be as small as 4096 bytes, so one must be careful to use it sparingly. If you need large data structures in your module, then you should attempt to allocate the memory you need with kmalloc when the module is loaded and handle it yourself.

I sometimes make stacks by defining a list node structure which includes a pointer to its own type and contains fields for data. An empty stack is simply a structure including a NULL pointer to a list node and fields for book keeping. Then I allocate an array of such structs. I usually define an unused-node stack and push all the nodes in the array on that unused-nodes stack. As I need nodes for data, I pop them from the unused-nodes stack, fill the data fields, and insert them in the in-use stack or, more often, an in-use queue. When the data consumer has used the data, it can be popped from the in-use stack or dequeued from the in-use queue and pushed back onto the unused-nodes stack.

The book keeping fields in the stacks and queues may include synchronization objects to prevent corruption by interleaved accesses of data producers and consumers if these can be in independent threads.

On the other hand, there should be enough stack to handle any reasonable number of calls in a kernel module. You do have use of the kernel stack. Deeply nested recursion in kernel modules could possibly crash the system and cause loss of information.
 
Old 09-07-2010, 03:54 AM   #9
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Original Poster
Rep: Reputation: 22
Quote:
Originally Posted by ArthurSittler View Post
They point out that the stack for the entire kernel may be as small as 4096 bytes...
I sometimes make stacks...
On the other hand, there should be enough stack to handle any reasonable number of calls in a kernel module. You do have use of the kernel stack.
Yes, I know that a kernel stack is very small but it should take 10 bytes for a call in any case, else an interrupt would crash the core on return.
If you make stacks yourself how do you set the stack (GDT, LDT) that SS gets the right entrance? And it should be done before my init function is called from the kernel.
Problem characteristics:
- module loads
- init function is called by the kernel
- init function does call other functions(values)
- values never reach the called functions
- even with hard coded stack handel (push pop) it does not work
- it doesn't make difference in which way the module is loaded
 
Old 09-07-2010, 09:01 PM   #10
ArthurSittler
Member
 
Registered: Jul 2008
Distribution: Slackware
Posts: 124

Rep: Reputation: 31
at least dozens of levels of stack should be available

Yes, you should expect that you have at least dozens or hundreds of levels of stack available to your kernel module. You should not run out of stack space even with a long parameter list.

How are you tracing the parameters? My first line of attack is sprinkling printk() calls through the routines. If the calling routine reports the parameters before the call, and the called routine immediately reports the parameters on entry, the values should match.

Another issue is that any allocation by kmalloc() can fail, just as any call to malloc() can fail out in user code. I presume you are testing the allocation for failure.

My discussion of stack implementation relates only to stacks of local data. You should not need to manipulate the system stack. I believe it is possible to allocate larger system stack when you configure a system. If you do allocate more kernel memory to the stack, you remove it from availability for any other use.
 
Old 09-08-2010, 05:17 AM   #11
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Original Poster
Rep: Reputation: 22
Quote:
Originally Posted by ArthurSittler View Post
How are you tracing the parameters?
printk()
Another issue is that any allocation by kmalloc() can fail
You should not need to manipulate the system stack.
My parameters are func(int, int32, char) it should have enough space for these on the stack.
ESP has also a good value!
Yes, I use printk() for debugging.
I don't allocate memory anywhere it is all linked memory and only a view bytes.
That with the stack is only a thing of debugging to get more hints and to work out the problem.
I searched through the stack 100 bytes up and down - nowhere my parameters!
ESP, EBP, EBX don't point to or have possible C values. The only values on the stack are right set return values. Even if I exchange the parameter by assembler the stack looks the same - zeroed.
I can imagine that linux kernel has to do something with it. Maybe the kernel doesn't want to alow function calls while module initialization - security manner. In this case I have to code directly in the kernel's code.
My task is to programm a new feature into the kernel and I first wanted to test it as module. It is also faster like to reboot all the time.
 
Old 09-08-2010, 08:56 AM   #12
ArthurSittler
Member
 
Registered: Jul 2008
Distribution: Slackware
Posts: 124

Rep: Reputation: 31
separate stack pointer and data size conflicts in kernel mode

The kernel has its own separate stack pointer which overlays the user stack pointer while the processor is in kernel mode. Thus, it may be futile to look at the stack frame for your data. It is on a different stack. You might try writing a dummy routine in the kernel module which prints the parameters with printk() and then calls the kernel routine you really wanted to call.

There is a considerable hazard that the data types in the kernel may be a different size than the data types in user space. In kernel mode, you can always be certain of the size and types of the following data types defined in <asm/types.h> included by <linux/types.h>:
Code:
 u8,  s8  unsigned and signed  8 bits
u16, s16  unsigned and signed 16 bits
u32, s32  unsigned and signed 32 bits
u64, s64  unsigned and signed 64 bits
Casting your data to one of these types for all kernel-mode routines should ensure that you avoid size mismatch. A size mismatch would cause a stack imbalance, which would cause the symptoms you described. C may treat char as int, so you may wish to avoid the 8-bit types outside of I/O routines involving 8-bit data devices.

These types are Linux specific. This hinders porting modules to other Unix systems.

Floating point is not generally supported in kernel routines.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Ubuntu Linux solution stack implementation, Part 4: Solution stack setup and integration LXer Syndicated Linux News 0 08-18-2010 03:50 AM
single 8K process stack vs 4K process stack and a seperate 4K interrupt stack charvak Linux - Kernel 1 03-17-2010 06:58 PM
Difference b/t Kernel stack and User stack hazzyb Linux - Software 2 09-29-2008 07:40 PM
LKM talking to another LKM? Ljunge Programming 4 11-13-2007 01:29 PM
LXer: Self-configuring WiFi stack eases device setup LXer Syndicated Linux News 0 05-02-2006 05:54 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:11 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration