WDHAL development notes

after discussions on freenode with EricHerman I decided I should keep a journal of my thoughts as well as documenting everything I have learned through this project. There is too little material which is easy to find to get started on linux kernel programming which is accessible to people who are not deep experts. There seems to be a gap between a step by step of how to write a "hello, world" kernel module, which anyone who can program in C would be able to figure out fairly quickly by reading the source of any device driver chosen at random. So I am making such notes as I go along. For now this is just my observations, etc as I work on this but once I get into the more in depth kernel programming I will start to document all

20.04.09

Guess who got caught out by LLP64 vs LP64? For those not familar with 64 bit type models this refers to which of the C language data types are 64 bits wide instead of 32 bits.

this table shows the lengths of the standard C data types in the different models
DatatypeLP64 ILP64LLP64ILP32LP32
char88888
short1616161616
_int3232
int3264323216
long6464323232
long long64
pointer6464643232

Windows uses LLP64 and this is what I am used to, linux uses LP64. My PE header was written in such a way that it would work fine on 32 bit machines or x64 windows but my PE headers would show up all wrong causing my work in progress runtime linker to crash. After printing out a hex dump of a sample .sys file and going through it carefully I realized that all the feilds which should have been 32 bits wide were being treated as 64 bits wide. This was easily fixed as soon as I knew it was happening

Thanks to EricHerman this project now has a web page and soon a git repository.

19.04.09

Went to the library at the local university, as a polytechnic student I am able to check out books from the university library as well as my own campus library. I've found Understanding the linux kernel 3rd edition which seems to be a reasonably good introduction. In the front there is a cheat sheet which shows which header files different types of functions live in, this is extermely useful. I will likely make a LaTeX and HTML version for others to use. Trying to keep the NT semantics and the linux semantics in the code each in the parts where they belong is no easy task. I think I finally have an idea of how to go about doing this project! I'm not sure on cirtain details of the linker. With exports from the .sys I know that they are in the same addres space as the .ko but I don't understand what need to be done to make these actually callable. I will probably end up having to look at some disassemblies and draw address space diagrams on paper.

18.04.09

Worked mostly on how to go about setting up the memory environment for the loaded windows device driver. Our .sys file is loaded into kernel memory on linux but the address space presented to the module needs to be fixed appear to appear as it does on windows. Windows .sys drivers are actually .dll files which link to NTOSKRNL.EXE once the module is loaded, we provide a thunking layer similar to wine which links to our functions instead, which will then implement the required behaviour with linux kernel functions. It took me half a day just to find how to map pages into memory. there is no real documentation and what documentation I can find is often old or out of date. It needs to be read together with the source and is often a waste of time. A great deal of time in a project like this is spent preparing headers before you can even do anything. I browsed through the sources of ReactOS, WINE and ring3k looking for stuff I can use, especially for the windows PE file format information. Yes I have specs, but writing a runtime linker for the PE format from scratch takes considerable time. I had some confusion over the sizes of common types on 64 bit machines. Windows uses the LP64 model, while linux uses LLP64 or is it the other way around?