I want to create all my drivers as loadable modules (to make it easier to change them without recompiling the whole kernel)
The problem I have is how to load them into the kernel space.
I have a FAT12 and FDC system in place, so I can load the code from file, but relocation is a problem.
If I load a raw binary, its already been relocated (using JLOC) and won't run properly. If I load an obj or elf format file, I have no idea how to relocate it to make it work.
Any help would be appreciated.
Loadable module help
RE:Loadable module help
The thing I don't understand is why the file needs to be relocated in the first place.
When I look at the .LST file, all the references seem to be relative, not absolute. So procedure calls and jmp's are relative to where the code currently is (IE. "JMP -40" not "JMP CS:200").
One problem I do see, is that data references are absolute, but I could code around this.
Are there any other reason's why code must be relocated properly?
When I look at the .LST file, all the references seem to be relative, not absolute. So procedure calls and jmp's are relative to where the code currently is (IE. "JMP -40" not "JMP CS:200").
One problem I do see, is that data references are absolute, but I could code around this.
Are there any other reason's why code must be relocated properly?
RE:Loadable module help
Well, I personally have to relocate so that my loadable modules can access the kernel (I have a select few kernel routines "published" to the loadable modules so they can call the kernel as if it were actually linked to the modules (which it is, essentially - I like the two are run-time)).
Data references are also a good reason to relocate. How do you intend to "work around" this? Say you load in 20 modules... in order to "work around" these data addresses you would have to create a new data segment for each of these modules which sets it's load address as 0x0. That's pretty wasteful (especially considering 20 modules is a conservative ammount...)
And what about BSS variables? Most compilers (I believe) will assume the BSS variables will be located in memory directly after the program, which is fine... if you wish to change this, however, you'll need to perform some relocations.
Cheers,
Jeff
Data references are also a good reason to relocate. How do you intend to "work around" this? Say you load in 20 modules... in order to "work around" these data addresses you would have to create a new data segment for each of these modules which sets it's load address as 0x0. That's pretty wasteful (especially considering 20 modules is a conservative ammount...)
And what about BSS variables? Most compilers (I believe) will assume the BSS variables will be located in memory directly after the program, which is fine... if you wish to change this, however, you'll need to perform some relocations.
Cheers,
Jeff
RE:Loadable module help
My workaround was not a good system... but a "workaround"
The kernel could set a base variable pointer, and all data references would be [baseptr + variable].. therefore they would all work correctly, and be within one data segment.
Obviously this wouldnt be a good system, but it could work.
BSS variables I know nothing about so I'll have to go read up exactly what they are... I've seen references too them in OBJ samples, but haven't found out what they are exactly.
What I don't understand is how relocation works. Do you know of any examples or tutorials on how to do it?
The kernel could set a base variable pointer, and all data references would be [baseptr + variable].. therefore they would all work correctly, and be within one data segment.
Obviously this wouldnt be a good system, but it could work.
BSS variables I know nothing about so I'll have to go read up exactly what they are... I've seen references too them in OBJ samples, but haven't found out what they are exactly.
What I don't understand is how relocation works. Do you know of any examples or tutorials on how to do it?
RE:Loadable module help
I have a question/solution that I'd like comments on.
For each driver that is loaded, it recieves its own LDT.
Each driver is linked at 0 (or perhaps some small offset to allow task-related information to be stored before the actual code).
One master LDT is kept at a fixed location (which is referenced in the GDT), and the LDT for the driver is copied into this fixed location. Then the LDT is reloaded (to reload the new data).
Now each driver has its own address space, and all that is required is a block memory copy of around 16 or so bytes, and a LLDT instruction.
Using a JMP to enter the module code, with the return information on the stack to return to the correct kernel code selector, the module could use RETF's to return to the kernel code.
Anyway, I'd like comments and/or suggestions on the feasibility of this. In the meantime, I'm going to give it a go.
For each driver that is loaded, it recieves its own LDT.
Each driver is linked at 0 (or perhaps some small offset to allow task-related information to be stored before the actual code).
One master LDT is kept at a fixed location (which is referenced in the GDT), and the LDT for the driver is copied into this fixed location. Then the LDT is reloaded (to reload the new data).
Now each driver has its own address space, and all that is required is a block memory copy of around 16 or so bytes, and a LLDT instruction.
Using a JMP to enter the module code, with the return information on the stack to return to the correct kernel code selector, the module could use RETF's to return to the kernel code.
Anyway, I'd like comments and/or suggestions on the feasibility of this. In the meantime, I'm going to give it a go.
RE:Loadable module help
BSS is the uninitialized portion of the data segment. Global variables and static local variables that are not assigned a value when they are declared go into the BSS. This region of memory must be zeroed before main() is called. Because every variable in the BSS has the same initial value (zero), there is no need to store it in the executable file -- only it's size and address.
I don't know about OMF/OBJ, but this code will relocate DJGPP COFF, Win32 PE COFF, and ELF .o files:
http://my.execpc.com/~geezer/osd/exec/runreloc.zip
I don't know about OMF/OBJ, but this code will relocate DJGPP COFF, Win32 PE COFF, and ELF .o files:
http://my.execpc.com/~geezer/osd/exec/runreloc.zip