OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Oct 22, 2019 10:09 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Design of a basic module loader
PostPosted: Thu Nov 11, 2004 2:56 pm 
Im at the point where I want to start loading my system drivers as as modules and I am looking for some ideas on how to design a simple module loader. At this point Im not too concerned with different object formats, elf, coff, pe.

I have a few ideas but most of them require the use of a executable object format.

What steps do I need to take in order to write a basic module loader?

Thanks in advance.


Top
  
 
 Post subject: Re:Design of a basic module loader
PostPosted: Thu Nov 11, 2004 5:55 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 22, 2004 11:00 pm
Posts: 1076
I dont know if it was the right way or not, but I always aproached this as doing a linker. I more or less post-linked/relocated objects in memory. my main exec format had imports/exports/relocs etc. so then there became no difference from loadong a binary or a module...

the hard bit was interfacing into the kernel and all that goes with that :)

_________________
-- Stu --


Top
 Profile  
 
 Post subject: Re:Design of a basic module loader
PostPosted: Thu Nov 11, 2004 8:27 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

beyondsociety wrote:
Im at the point where I want to start loading my system drivers as as modules and I am looking for some ideas on how to design a simple module loader. At this point Im not too concerned with different object formats, elf, coff, pe.

I have a few ideas but most of them require the use of a executable object format.

What steps do I need to take in order to write a basic module loader?


I do the opposite to "df". My modules are all loaded at fixed addresses, and I made up a simple binary file format for them (same as the DOS *.com format, except it's 32 bit and there's a simple header at the start).

To start a module the kernel uses normal file IO to load the first 128 bytes (enough for the header) and checks if it's a valid module (and that the OS has enough resources, the user has permission, etc to run it). Then the kernel creates a new process and spawns a thread within the new process. This spawned thread runs more kernel code that also uses file IO to load the binary file into the process's address space (or eventually, optionally memory maps the file - when I get time to write the code), and uses "retf" to jump to it's entry point. The new thread becomes the first thread for the process/module.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re:Design of a basic module loader
PostPosted: Fri Nov 12, 2004 9:39 am 
I think module loader depends on your kernel architechture,
if you want to have a monolitic kernel you will use df methode
if you want a microkernel you have to do something like brendan methode

(correct me if i'm wrong)


Top
  
 
 Post subject: Re:Design of a basic module loader
PostPosted: Fri Nov 12, 2004 9:56 am 
Offline
Member
Member
User avatar

Joined: Fri Oct 22, 2004 11:00 pm
Posts: 1076
I didnt say anything about micro or monolithic.

whether each module gets its own task/process space or you load many inside a single address space or not doesnt alter what I said.

_________________
-- Stu --


Top
 Profile  
 
 Post subject: Re:Design of a basic module loader
PostPosted: Mon Nov 15, 2004 4:12 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
aladdin wrote:
I think module loader depends on your kernel architechture,
if you want to have a monolitic kernel you will use df method
if you want a microkernel you have to do something like brendan method


hum. i don't think we should talk about "loading modules" for a microkernel system that loads a new service. Reason is the new service will only invoke the microkernel and will only do it through a collection of well-defined interrupts (or system traps or whatever).

Thus the "linkage" actually occurs in the "syscall.h" and in the system library or something where you will write the ASM stub and hardcode the parameters passing rules for the system calls.

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Design of a basic module loader
PostPosted: Mon Nov 15, 2004 4:31 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
beyondsociety wrote:
What steps do I need to take in order to write a basic module loader?


Knowing what you have to load: your module will have to include information about the size of the code to be loaded and the amount of space your module requires (e.g. don't forget the BSS section)

Knowing where you will load it: the easiest is to build your module so that it has a 'target address' that will be free at run-time. If you have enough virtual address, you can easily slice your kernel space so that each module has its own slice. However, this is not very eay-to-upgrade-later and thus i'd rather advocate for a relocation list, here. Check out the "Linkers and Loaders", it's not such a complex concept.

Knowing what you can use: your module is likely to need access to kernel (or other modules) functions. This is usually the symbol table. You can decide that there are N 'symbols' pointing towards structures/functions and pass the address of the table where those symbols are stored to your module's initialization function.

Code:
  #define kprint kernelptrs[0]
  #define kalloc kernelptrs[1]
  ...

  function *kernelptrs=NULL;

  status init(function *imports) {
      kernelptrs=imports;
   }


That table could also be an associative array of name=>pointer that the module loader will use to patch the executable.

Telling what you can do: the last step is to be able to export features (such as open/close/read/write for a device). You can for instance return an "object" structure that will contain pointers to functions that will perform what is expected, etc.

Code:

//-- module.h
struct itable {
   int id;
   void* vtable;
};

#define END_OF_INTERFACES 0

void* search_itable_for_id(int id);

//-- blockdev.h
struct block_device_interface {
    status (*open)(options);
    status (*close)();
    status (*read)(address, size, buffer);
    status (*write)(address, size, buffer);
};

#define BLOCK_DEVICE_INTERFACE 0xb10c

//-- module.c

status myOpen(...) {...}

...

struct block_device_interface myBlockDevice {
   open: myOpen,
   close: myClose,
   read: myRead,
   write: myWrite,
};

itable myInterfaces[]={
   { BLOCK_DEVICE_INTERFACE, &myBlockDevice },
   { END_OF_INTERFACES, NULL}
};

itable* init(functions* import) {
   ... do stuff ...
   return myInterfaces;
}

_________________
Image May the source be with you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group