djgpp problems

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
mztan

djgpp problems

Post by mztan »

hey all,

i'm having some problems loading libraries in djgpp... i'm getting undefined reference errors all over the place.

ld -e _main -Map map.txt -Ttext 0x1000 -o kernel.o main.o video.o ports.o init.o util.o fdc.o -lc

i figure this should work, except i get wacky errors like:
c:/djgpp/bin/../lib/libc.a(dpmiexcp.o)(.text+0x162):dpmiexcp.c: undefined reference to `_stklen'
c:/djgpp/bin/../lib/libc.a(dpmiexcp.o)(.text+0x16b):dpmiexcp.c: undefined reference to `__djgpp_selector_limit'
c:/djgpp/bin/../lib/libc.a(dpmiexcp.o)(.text+0x5da):dpmiexcp.c: undefined reference to `__djgpp_selector_limit'
c:/djgpp/bin/../lib/libc.a(dpmiexcp.o)(.text+0x83d):dpmiexcp.c: undefined reference to `_stklen'
c:/djgpp/bin/../lib/libc.a(dpmiexcp.o)(.text+0x843):dpmiexcp.c: undefined reference to `__djgpp_stack_limit'

i guess i need to include more libraries or something, but i dont know which ones to include.

can a brother get a little help in hurr? thanks heh.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:djgpp problems

Post by Solar »

c:/djgpp/bin/../lib/libc.a...

You're trying to mix a flat kernel binary with the C runtime of your host system... doesn't work.

I'm not familiar with DJGCC, but you should look into the flags -nostdlib, -nostartfiles, and -nodefaultlibs.
Every good solution is obvious once you've found it.
mztan

Re:djgpp problems

Post by mztan »

Well i need the libraries because otherwise, i get other undefined reference errors... like
util.o(.text+0x2e):util.c: undefined reference to `_go32_info_block'
util.o(.text+0x41):util.c: undefined reference to `_go32_info_block'
util.o(.text+0x49):util.c: undefined reference to `__dpmi_get_and_disable_virtual_interrupt_state'
util.o(.text+0x64):util.c: undefined reference to `_go32_dpmi_get_protected_mode_interrupt_vector'
util.o(.text+0x8b):util.c: undefined reference to `_go32_dpmi_allocate_iret_wrapper'
util.o(.text+0xa4):util.c: undefined reference to `_go32_dpmi_set_protected_mode_interrupt_vector'
util.o(.text+0xbb):util.c: undefined reference to `_go32_dpmi_set_protected_mode_interrupt_vector'
util.o(.text+0xcd):util.c: undefined reference to `_go32_dpmi_free_iret_wrapper'
util.o(.text+0xdb):util.c: undefined reference to `__dpmi_get_and_set_virtual_interrupt_state'
util.o(.text+0x160):util.c: undefined reference to `_go32_dpmi_allocate_dos_memory'
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:djgpp problems

Post by Pype.Clicker »

well, if there are so much dependencies to Dos Protected Mode Interface in your code, chances that you're heading the wrong way.

probably you're expecting too much (and #include<...>d too much header files). When writing an OS, you're pretty much on your own, including whatever concerns interrupts, memory allocation and the like.
mztan

Re:djgpp problems

Post by mztan »

Well I'm simply using a FDC driver I got from another post. fdc.c, fdc.h... They include a whole bunch of stuff... a lot of system-level functions, etc, I guess.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:djgpp problems

Post by Solar »

So they probably already have implemented those parts of the standard library.

You don't have a standard library available to you when you start writing a kernel. You have to either port one or write your own. When you're starting with your kernel, "#include" is basically a mistake.
Every good solution is obvious once you've found it.
mztan

Re:djgpp problems

Post by mztan »

Uhh... I have not done any #includes... the drivers include things like dos.h, go32.h, assert.h, etc. etc.
AR

Re:djgpp problems

Post by AR »

There's your problem then, if this is ment to be an OS you'll have to remove those includes and modify the code to not use the DOS functions and write your own replacement code to take the place of the DOS functions.
mztan

Re:djgpp problems

Post by mztan »

So... if util.c is calling stuff like "_go32_dpmi_allocate_dos_memory", which is located in libc.a... how would I remove those types of functions and write my own substitutes? I don't really understand..

Here is a function located in util.c that calls a lot of library functions. Any suggestions as to how I can rewrite this?

Code: Select all

void set_irq_handler(int irq,void (*handler)(void),IrqSave *irqsave)
{
   int picbase,irqstate;
   
   if (irq == 0x1c) {
      /* kludge to allow use of int 1ch in DOS */
      picbase = 0;
   } else {
      /* get INT base of IRQ's */
      if (irq < 8) {
    picbase = _go32_info_block.master_interrupt_controller_base;
      } else {
    irq -= 8;
    picbase = _go32_info_block.slave_interrupt_controller_base;
      }
   }
   
   /* disable interrupts */
   irqstate = __dpmi_get_and_disable_virtual_interrupt_state();
   
   if (handler) {
      /* setting new handler */
      _go32_dpmi_get_protected_mode_interrupt_vector(picbase + irq,
                       &irqsave->oldhdlr);
      irqsave->newhdlr.pm_offset = (unsigned long)handler;
      irqsave->newhdlr.pm_selector = _go32_my_cs();
      _go32_dpmi_allocate_iret_wrapper(&irqsave->newhdlr);
      _go32_dpmi_set_protected_mode_interrupt_vector(picbase + irq,
                       &irqsave->newhdlr);
   } else {
      /* restoring old handler */
      _go32_dpmi_set_protected_mode_interrupt_vector(picbase + irq,
                       &irqsave->oldhdlr);
      _go32_dpmi_free_iret_wrapper(&irqsave->newhdlr);
   }

   /* re-enable interrupts if necessary */
   __dpmi_get_and_set_virtual_interrupt_state(irqstate);
}
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:djgpp problems

Post by Pype.Clicker »

mztan wrote: So... if util.c is calling stuff like "_go32_dpmi_allocate_dos_memory", which is located in libc.a... how would I remove those types of functions and write my own substitutes? I don't really understand..
Well, it may require you to write new code for the functions in util.c that will only require things you provide ... and ultimately write system code (well, code that access intel-defined data structures, processor registers, I/O space and the like :)

DPMI cannot access those resources (they may be under the control of windows, for instance)... so the DPMI programmer has to use klumsy DPMI interface to access these stuff ...

Code: Select all

void set_irq_handler(int irq,void (*handler)(void),IrqSave *irqsave)
{
   int picbase,irqstate;

Code: Select all

   if (irq == 0x1c) {
      /* kludge to allow use of int 1ch in DOS */
      picbase = 0;
   } else {
chances that you want to keep RBIL:int1C are low. Drop this ;)

Code: Select all

      /* get INT base of IRQ's */
      if (irq < 8) {
    picbase = _go32_info_block.master_interrupt_controller_base;
      } else {
    irq -= 8;
    picbase = _go32_info_block.slave_interrupt_controller_base;
      }
Check out our wikiFAQ ... it has informations about "how to remap the PIC" that will let you know why this could work (with proper remapping)

Code: Select all

     picbase = 20+irq

Code: Select all

   
   /* disable interrupts */
   irqstate = __dpmi_get_and_disable_virtual_interrupt_state();
just asm("CLI") for this one (see FAQ >> Inline Assembly >> disable())

Code: Select all

   if (handler) {
      /* setting new handler */
      _go32_dpmi_get_protected_mode_interrupt_vector(picbase + irq,
                       &irqsave->oldhdlr);
      irqsave->newhdlr.pm_offset = (unsigned long)handler;
      irqsave->newhdlr.pm_selector = _go32_my_cs();
      _go32_dpmi_allocate_iret_wrapper(&irqsave->newhdlr);
      _go32_dpmi_set_protected_mode_interrupt_vector(picbase + irq,
                       &irqsave->newhdlr);
and i hesitated for the word "klumsy" ... probably you'll have to write code for "wrappers" yourself (in ASM) the FAQ will help you at it, again ...

Code: Select all

      /* restoring old handler */
      _go32_dpmi_set_protected_mode_interrupt_vector(picbase + irq,
                       &irqsave->oldhdlr);
      _go32_dpmi_free_iret_wrapper(&irqsave->newhdlr);
   }
i'm not sure you need that one...

Code: Select all

   /* re-enable interrupts if necessary */
   __dpmi_get_and_set_virtual_interrupt_state(irqstate);
}
asm("sti");



btw, just by curiosity, where did you get that "util.c" from ?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:djgpp problems

Post by Candy »

Another note for this thread, you can't just take code from somewhere else and expect it to work. Everything has to be hand-made or customized for your OS.
mztan

Re:djgpp problems

Post by mztan »

Ahh... thanks Pype... I posted a request for some sample fdc driver code earlier... ashley04 (something along those lines) told me to try this code.

Thanks.
mztan

Re:djgpp problems

Post by mztan »

Hrmm... so how would I go about rewriting _go32_dpmi_get_protected_mode_interrupt_vector()? I guess I understand what it does now. I read the FAQ on ISRs, but that is different, isn't it? "_go32_dpmi_get_protected_mode_interrupt_vector()" and "_go32_dpmi_set_protected_mode_interrupt_vector()" change the ISRs, right?, as opposed to the stuff on the FAQ that add ISRs... I don't really know how to phrase my question.
jonathanmcdougall

Re:djgpp problems

Post by jonathanmcdougall »

> Hrmm... so how would I go about rewriting
> _go32_dpmi_get_protected_mode_interrupt_vector()? I guess
> I understand what it does now. I read the FAQ on ISRs, but
>`that is different, isn't it?
<snip>

Have a look at http://k101.f2g.net, chapter 10. This will get you started with interrupts.

I think I already saw that floppy driver somewhere. It is usable, but you must adapt it. First, you will need to setup your interrupts (chapter 10 is your friend). Next, you'll want to setup dma (that's for transfering data from/to the floppy). This might be more difficult since I haven't seen a complete tutorial on that (but my website will have one pretty soon). Finally, you'll have to modify the driver to use your functions.

You cannot expect to take some arbitrary code out there and make it work with your OS out of the box. Virtually all the code you will find will be specific to an implementation. Some may be easy to port but most won't be.


Jonathan
Post Reply