You are not logged in.


#1 2012-01-23 17:42:25

bubach
Administrator
From: Trollhättan, Sweden
Registered: 2005-02-15
Posts: 366
PM  Website

GDT segment based driver loading

Hi there, if anybody still checks this forum?  Anyway, I've been going back to my BOS source and started doing some work again. big_smile  And I'm now sure that I'll base my drivers/programs on some relocatebale file format and not the segment approch, mainly becasue it's not supported on 64-bit systems, higher language compiler issues and so on.

While I research the executable format options I thought I might as well post my proof-of-concept segment based loading code here, in case anybody finds it useful!

It's not 100% completed, but you should be able to get a hang of how it works. It sets up new GDT selectors on the fly for each program/driver so that the ORG statement can be set to zero.

[b]drv_load.inc[/b]

ASM code:

;----------------------------------------------------------;
; BOS kernel                     Christoffer Bubach, 2005. ;
;----------------------------------------------------------;
;                                                          ;
;       Handles all loading/unloading of drivers.          ;
;                                                          ;
;----------------------------------------------------------;


      drv_selector        dw   0                      ; driver CS
      drv_offset          dd   0                      ; driver offset
      stack_pointer       dd   0                      ; temporary stack pointer

      driver_struct:                                  ; space to save driver
             times 4096   dd   0                      ; pointer. max 4096..





;--------------------------------------------------------------------------;
;  Load driver/program                                                     ;
;    sets up mem and selectors for program..                               ;
;                                                                          ;
; in:  ebx = address of app or 0 if it should be loaded                    ;
;      ecx = size of app if already in mem                                 ;
;      dl  = media # if it's to be loaded                                  ;
;      dh  = 1 for driver/module, 0 for a program                          ;
;      esi = ASCIIZ file name. eg. '/bubach/apps/test/test1.app', 0        ;
;                                  '/bubach/drivers/mouse.drv', 0          ;
;                                                                          ;
;     ^----- Just forward to VFS that handles the rest                     ;
;--------------------------------------------------------------------------;
load_module:


          cmp     ebx0
          jne     .cont

          mov     ax50-11                           ; <- this is a fake-call.. ;)
          int     0x32                                ; load via VFS

     .cont:
          cmp     ecx0
          je      drv_error

          mov     dl1                               ; code sel.
          add     ecx4096                           ; add standard 4kb stack

          cmp     dword [ebx+41], 'DRV_'              ; sign. check
          jne     drv_error

     ;-------------------------;
     ;   add it to the list    ;
     ;-------------------------;
          push    ecx                                 ; save size
          xor     ecxecx
     .loop:
          cmp     dword [driver_struct+ecx], 0
          je      .add_it
          inc     ecx
          cmp     ecx4096
          jb      .loop
          pop     ecx
          jmp     drv_error
     .add_it:
          mov     dword [driver_struct+ecx], ebx
          pop     ecx                                 ; restore size


          push    ebx                                 ; save base and
          push    ecx                                 ; size

          mov     dh1                               ; 32bit thx
          call    set_gdt
          mov     word [drv_sel], cx                  ; store selector number

          pop     ecx
          pop     ebx

          mov     dxword [drv_sel]
          mov     word [ebx+23], dx                   ; store CS selector #

          mov     dl0                               ; data sel.
          mov     dh1                               ; 32bit thx

          push    ebx                                 ; save base
          call    set_gdt
          mov     edxebx                            ; save allocate bytes
          pop     ebx
          mov     word [ebx+25], cx                   ; store DS selector #
          mov     dword [ebx+27], edx                 ; store stack pointer

          mov     dword [stack_pointer], esp          ; store stackp.
          mov     axword [ebx+25]

          mov     ebxdword [ebx]                    ; get init-pointer
          mov     dword [drv_off], ebx                ; save offset


          mov     espedx                            ; set new stack, and
          push    dword [stack_pointer]               ; then mess with a local
          mov     dsax                              ; variable for the last
          mov     esax                              ; time before we set new
          mov     fsax                              ; ds,es, fs
          mov     ax0x10                            ; and gs for
          mov     gsax                              ; the driver. ;)


          db      0x9a                                ; far call
drv_off   dd      0                                   ; driver offset
drv_sel   dw      0                                   ; driver CS

          mov     ax0x10
          mov     dsax
          mov     esax
          mov     fsax
          mov     gsax
          pop     esp                                 ; our old stack pointer

          jmp     quit_drv_load

     drv_error:
          xor     eaxeax
     quit_drv_load:
          ret





;---------------------------------------------------------------;
;  unload_driver  -  Unload driver/program                      ;
;---------------------------------------------------------------;
;                              in:  ebx = driver address        ;
;                                   ecx = size                  ;
;                                                               ;
;                              out: eax = 1 if error, 0 if OK   ;
;---------------------------------------------------------------;
unload_module:

     ;--------------------------;
     ; remove driver from list  ;
     ;--------------------------;
          push    ecx                                 ; save size
          xor     ecxecx
     .loop:
          cmp     dword [driver_struct+ecx], ebx
          je      .remove_it
          inc     ecx
          cmp     ecx4096
          jb      .loop
          pop     ecx
          jmp     unload_error
     .remove_it:
          mov     dword [driver_struct+ecx], 0
          pop     ecx                                 ; restore size

          push    ebx
          push    ecx                                 ; save info

          mov     ecx, [ebx+4]
          mov     dword [unl_off], ecx                ; unload function offset
          mov     cx, [ebx+23]
          mov     word [unl_sel], cx                  ; unload func. code sel.
          mov     axword [ebx+25]                   ; and data selector
          push    ax                                  ; save DS for later..
          mov     edxdword [ebx+27]                 ; stack pointer
          mov     dword [stack_pointer], esp          ; store current stackp.

          mov     espedx                            ; set new stack, and
          push    dword [stack_pointer]               ; then mess with a local
          mov     dsax                              ; variable for the last
          mov     esax                              ; time before we set new
          mov     fsax                              ; ds,es, fs
          mov     ax0x10                            ; and gs for
          mov     gsax                              ; the driver. ;)

          db      0x9a                                ; far call
unl_off   dd      0                                   ; driver offset
unl_sel   dw      0                                   ; driver CS

;cli          ; BOCHS debug..
;hlt

          mov     ax0x10
          mov     dsax
          mov     esax
          mov     fsax
          mov     gsax

          pop     esp
          ;mov     esp, dword [stack_pointer]
          pop     bx                                  ; saved DS from before
          call    del_gdt                             ; data segment
          mov     bx, [unl_sel]
          call    del_gdt                             ; code segment

          pop     ecx                                 ; restore it
          pop     ebx

     ;------------------;
     ;   free memory    ;
     ;------------------;
;          cmp     ebx, 0x100000
;          jb      .low_mem
;          call    free_mem
;          xor     eax, eax
;          jmp     quit_drv_unl
;     .low_mem:
;          shr     ebx, 10                             ; / 1024 = 1 kb units
;          call    free_low_mem
;          xor     eax, eax
;          jmp     quit_drv_unl

     unload_error:
          mov     eax1                              ; error..
     quit_drv_unl:
          ret

And my test driver, that sets up an interrupt service and then quits:

[b]test_drv.inc[/b]

ASM code:

use32

;---------------------------------------------------;
;  driver structure                                 ;
;         must be the first thing in all drivers    ;
;---------------------------------------------------;
driver_structure:         dd   init_driver            ; sets up the syscalls etc
                          dd   deactivate             ; unload, free mem and int
                          db   'Test driver    '      ; 15 bytes driver name
                          dw   0                      ; driver CS, to be filled
                          dw   0                      ; driver DS, to be filled
                          dd   0                      ; stack pointer..
                          dw   12345                  ; Unique driver ID
                          dd   00                   ; Reserved
                          db   'DRV_V 0.01'           ; 10 byte driver signature

;------------------------;
;     other data         ;
;------------------------;
     testing              db   '   Test driver:          Init - Setting up int 0x33 for my test service..',0
     testing2             db   '   Test driver:          INT 0x33 called!',0
     testing3             db   '   Test driver:          Unloading myself..',0



;---------------------------------------------------------------;
;    init_driver  -  Start the driver, set up int(s) etc..      ;
;---------------------------------------------------------------;
;                                 in:  nothing                  ;
;                                                               ;
;                                 out: nothing                  ;
;---------------------------------------------------------------;
init_driver:
          pushad
          mov     ax0x1e                            ; make new line
          int     0x32

          mov     ax0x1c                            ; print string
          mov     esitesting
          mov     bl0x07
          int     0x32

          mov     ax0x00                            ; set up int
          mov     cl0x33                            ; # 0x33
          mov     dxcs                              ; with current CS
          mov     ediinterrupt_33                   ; function pointer
          int     0x32

          popad
          retf



;---------------------------------------------------------------;
;    deactivate  -  Kill the driver, free mem and int(s).       ;
;---------------------------------------------------------------;
;                                 in:  nothing                  ;
;                                                               ;
;                                 out: nothing                  ;
;---------------------------------------------------------------;
deactivate:
          push    eax
          push    ebx
          push    esi

          mov     ax0x1e                            ; make new line
          int     0x32

          mov     ax0x1c                            ; print string
          mov     esitesting3
          mov     bl0x07
          int     0x32

          pop     esi
          pop     ebx
          pop     eax
          retf



;-------------------------------------;
;   driver interrupt/service(s)       ;
;-------------------------------------;
interrupt_33:
          push    gs
          push    fs
          push    ds
          push    es

          push    ax                                  ; the code segment gets
          mov     ax, [cs:0x19]                       ; adjusted by it's self
          mov     dsax                              ; but I better fix ds,
          mov     esax                              ; es..
          mov     fsax                              ; ..and fs.
          pop     ax

          mov     ax0x1e                            ; make new line
          int     0x32

          mov     ax0x1c                            ; print string
          mov     esitesting2
          mov     bl0x07
          int     0x32

          pop     es
          pop     ds
          pop     fs
          pop     gs
          iret

In my test case, i simply included the assembled binary for the "driver" at the end of my kernel, making it into one file, so code for loading via VFS and freeing memory at exit is stubs/dummy code.

As I said, not perfect or complete, but maybe it can give some ideas to those that think about using segmentation.

Offline

 

#2 2012-01-25 00:16:43

bubach
Administrator
From: Trollhättan, Sweden
Registered: 2005-02-15
Posts: 366
PM  Website

Re: GDT segment based driver loading

Noticed now that I set the new app/driver stack, push my own stack pointer on there - to later pop after we get back control. No idea why I did that, since the stack pointer is saved to a local variable anyway... Seems like an uneccecary "risk" to let our own stack-pointer be exposed to the loaded program for no apparent reason.. Hmm, well it's not quality all the way, but might still give someone an idea of how it might be done.

Offline

 

#3 2012-01-26 17:54:22

smiddy
Active member
Registered: 2005-02-15
Posts: 183
PM

Re: GDT segment based driver loading

Hi,

Nice to see you back into it. I am slowly getting back into it too. I am trying to transition to 64-bit via CD/DVD/BD boot loading. I'm currently working that rather slowly. I will review what you go here, sounds kewl from the scanning I did.


- [color=red]s[/color][color=blue]m[/color][color=red]i[/color][color=blue]d[/color][color=red]d[/color][color=blue]y[/color]

Offline

 

#4 2012-01-29 01:40:00

bubach
Administrator
From: Trollhättan, Sweden
Registered: 2005-02-15
Posts: 366
PM  Website

Re: GDT segment based driver loading

Hi, yeah it's great to have some motivation back. But unfortunatly I just got a rather bad case of the flu, so nothing done this weekend.. sad

Offline

 

#5 2012-01-30 21:52:28

smiddy
Active member
Registered: 2005-02-15
Posts: 183
PM

Re: GDT segment based driver loading

Get better man! I'll look in from time to time.


- [color=red]s[/color][color=blue]m[/color][color=red]i[/color][color=blue]d[/color][color=red]d[/color][color=blue]y[/color]

Offline

 

#6 2012-01-31 02:04:05

bubach
Administrator
From: Trollhättan, Sweden
Registered: 2005-02-15
Posts: 366
PM  Website

Re: GDT segment based driver loading

Thanks, I'm actually already feeling better. Which is odd becasue I can usally be sick for a week or more tongue

Got my setup back where it should be, found me a floppy emulator for win7, did some batch file work to get the assemble->test time down and also started to get back into using boch debugger... I had forgotten most commands, which is scary, I hope my asm skills isn't in the same shape.  But atleast I've fixed a natsy bug in my directory listing code, and I'll continue with full FAT12 support before looking more deeply into the exec format.

Sometimes I can have troubles focusing becasue I start drifting away from what I'm doing and looking ahead on stuff that I'd like to implement/support later on. sad  Anyway, it's looking better each day, and I hope that I can find a balance in my life to give BOS a few hours every other day or so.

How far along are you with smiddyOS, have you done anything worth mentioning since last time I was active here? Haven't checked your webpage hosted here, but maybe you got a new one? Either way, it would be nice to get a chance to test your latest img-file smile

Offline

 

#7 2012-02-03 18:06:35

smiddy
Active member
Registered: 2005-02-15
Posts: 183
PM

Re: GDT segment based driver loading

I have not done anything significant. I'm working on getting the CD/DVD/BD boot loading working. I'm nearly there. Then I will focus on moving to 64 bit. I haven't touched that site in ages. I know I've forgotten the password for sure. I think I tried a few weeks back to get on there, but failed. If you wish you can remove it. I appreciate you keeping it up BTW. If we ever meet in person I owe you a few beers (or your favorite beverage).

I need to find a balance too, which I'm working to simplify my life a bit more. I have been traveling nearly every week for the past two years and have essentially stopped that since I am transitioning jobs shortly.

How did school go? Did you finish? As I recall you were headed for college?


- [color=red]s[/color][color=blue]m[/color][color=red]i[/color][color=blue]d[/color][color=red]d[/color][color=blue]y[/color]

Offline

 

#8 2012-02-04 11:14:29

bubach
Administrator
From: Trollhättan, Sweden
Registered: 2005-02-15
Posts: 366
PM  Website

Re: GDT segment based driver loading

Hehe, ok well as long as I keep this site there's no problem hosting it. But I could remove it if you want, doesn't matter to me either way.

Well I first went for a free-standing year called like "technical base-year" with basically all math, physics and chemistry... That was fun. Not.  Think I managed to pass on like 50% of the courses, if that. But all I really needed was one of the earlier math courses so I could get in to the computer science program, which lasts for 3 years.

There I went for 2 years before dropping out, when my homepage wwwjoox.net took off. Too much money, too quickly kind of made me loose my footing. Eventually the site died, but pulled in a truckload of money while it was up.

I wish I had partied less, and planned ahead more, could have started a serious business, or invested in stock. All I did was waste every penny of it which left me with IRS-debt here.

Well, thats in the past now, and I'm slowly building up a more stable and serious web business while at the same time paying off my debts. tongue

Offline

 

#9 2012-06-10 16:45:28

tonyMac
Member
Registered: 2005-03-02
Posts: 28
PM

Re: GDT segment based driver loading

@Bubach:  I spent 7 years in college before getting my degree, there was some partying in there, and a transfer to another school.  So now I do have my degree, but I have a home mortgage worth of student debt.  It is going to take me some time to overcome that.  A shame I can't transfer you some credits, I have enough for 2 degrees, one of which happens to be computer science with a focus in computer engineering/firmware.

Offline

 

#10 2012-06-10 18:32:46

bubach
Administrator
From: Trollhättan, Sweden
Registered: 2005-02-15
Posts: 366
PM  Website

Re: GDT segment based driver loading

Wow, seven years?  What I've heard about your college costs, it would seem that you are fortunate to have been able to pull it off at all.  All education here is free, but you still have to support your own living with only around 400 dollars in government support each month, so rest is usually managed with student loans or extra work on the side.
Motivation was a big thing for me, what wasn't basic stuff that I knew since several years was so boring and unrelated that I lost all interest when the money started rolling in. tongue

Anyway, won't need any degree since I'm still working on my own business - trying to get it back on track.

Offline

 

#11 2012-06-10 19:39:54

tonyMac
Member
Registered: 2005-03-02
Posts: 28
PM

Re: GDT segment based driver loading

$28,000 a year in school costs.  That doesn't include living expenses.  However, I had a scholarship that covered $10,000 a year for being brilliant;-). .  I had a paid internship that covered most of my living expenses, then worked full time my last 2 years.  The current president has made it possible to claim more of the loan interest on taxes for an extra couple years, however it would seem likely our gov't will change again this year, meaning I'll probably be picking up the debt of a rich man's son as well as my own.

Offline

 

#12 2012-06-10 19:41:22

tonyMac
Member
Registered: 2005-03-02
Posts: 28
PM

Re: GDT segment based driver loading

But we're off topic. ;-)

Offline

 

#13 2012-06-11 00:20:03

bubach
Administrator
From: Trollhättan, Sweden
Registered: 2005-02-15
Posts: 366
PM  Website

Re: GDT segment based driver loading

hehe, well yeah i guess tongue

Offline

 

 

Board footer

Powered by PunBB
BOS homepage © Copyright 2005 Christoffer Bubach
Strict XHTML and valid CSS.