Question

i am new in operating system development ,i found a semi simple operating system to help as start,that operating system is "Test Os kernel" ,i download and i run it using bochs,so i decide to go to next level and try to compile ,and actually i am using MinGW Developer Studio 2.05,and also my operating system is vista not linux.

when i tried to compile the project ,i receive the following segment error:

kern\.\memory\gdt.c:113: error: conflicting types for 'GDT_set_descriptor'

kern\.\memory\gdt.c:85: error: previous implicit declaration of 'GDT_set_descriptor' was here

kern\.\memory\gdt.c:145: error: conflicting types for 'GDT_install'

kern\.\memory\gdt.c:93: error: previous implicit declaration of 'GDT_install' was here
kern\kernel.c: In function `_start':

kern\kernel.c:29: warning: implicit declaration of function `main'
kern\kernel.c: In function `main':

kern\kernel.c:36: warning: unused variable `cmd'

tos.exe - 4 error(s), 38 warning(s)

and here is the file contains the error:

#include "../../kernel_components/libc/types.h" 

/*
1-gdtdescriptor structure : the feilds of a gdt descriptor
2-gdt itelf is an array of gdtdescriptors, it contains all the gdtdescriptors
3-gdtpointer is a structure that indicates the place of the gdt in memory, this pointer is needed by the gdt register,
*/

#define GDTSIZE 16  //only 16 segments are mapped by the GDT
 
 
/*! 
 * gdtDescriptor :  each gdt descriptor represents a segment in memory
 */
typedef struct gdtDescriptor
{
    u16 segmentLimit_0_15;  //the first 16bit of the segment limit (its length)
    u16 segmentBase_0_15;   //the first 16bit of the segment Base (its beginning)
    u8  segmentBase_16_23;  //8bits in the midle for the segment base (its length)
    u8  segmentType : 4;    //data segment or code segment or stack segment
    u8  segmentOrSystemCall :1;//to revise the name of this after you know what it does
    u8  Ring:2; //ring0 is kernel segment and ring=3 for user mode segment,this used for protection
    u8  presentOrSwaped:1;  //to indicate if the segment is present in memory or it has been swaped to the HDD
    u8  segmentLimit_16_19:4;
    u8  NotUsed:2;      //this 2 bits feild is not used , so just put it to 0
    u8  instructionSize:1;  //instructionSize=1 for 32bit instructions
    u8  limitUnit:1;    //0 if the limit is expressed in bytes or 1 if the limit is in pages
    u8  segmentBase_24_31;
} __attribute__ ((packed)); //__attribute__((packed)) so that the compiler doesn't change this structure and optimize it

struct gdtDescriptor GDT[GDTSIZE];//the global descriptor table,is an array of gdtDescriptors (segment entries)

/*!
 * the folowing are used to indicate the type of segment, we use afrendly names instead of using binary parameters
 * they are used as parameters of the function GDT_set_descriptor(.....)
 */
#define segmentType_CS  0xB //the segment is a code segment
#define segmentType_DS  0x3 //to indicate that the segment being created is a data segment
#define kernelMode  0x0 //ring0, a segment used to contain kernel code
#define userMode    0x3 //ring3, used for ordinary applications that dont belong to the lernel
#define presentInMemory 0x1 //the segment is present in memory or is swapped to a backbone (a disk for exmple)
#define _32bitInstructions 0x1  //instructions in the segment are 32 bit instructions
#define _16bitInstructions 0x0
#define limitInBytes    0x0 //the limit of the segment is expressed in bytes (limit=0x100 means 0x100 bytes)  
#define limitInPages    0x1 //(limit=0x100 means 0x100 pages with each page can be 4k or 4M (on intel!)


/*! 
 * gdtPointer :  the gdt pointer is used to indicate the place of the gdt in memory
 */
typedef struct gdtPointer
{
    u16 limit;
    u32 base;
} __attribute__ ((packed));



u32 GDT_descriptors_number=0;   //the number of descriptors in the GDT
struct gdtPointer gdtr;


/*! 
 * GDT_init :  initialize the gdt table : insert the code and data segment and copy the gdt to a new place 
 */
 void GDT_init()
{
    //the first GDT is null
    **===============ERROR 2** GDT_set_descriptor(1,0x0,0xfffff,segmentType_CS,0x1,kernelMode,presentInMemory,_32bitInstructions,limitInPages);
    GDT_set_descriptor(2,0x0,0xfffff,segmentType_DS,0x1,kernelMode,presentInMemory,_32bitInstructions,limitInPages);
    
    //initialize the GDT pointer
    gdtr.base=GDT;
    gdtr.limit = sizeof(struct  gdtDescriptor)*GDTSIZE; 
    
    //make this GDT the system GDT by loading it to tne gdtr regiter
    GDT_install(); **===============ERROR 4**
}


/*! 
 * GDT_set_descriptor :  set a GDT descriptor,
 *  u32 descriptor  : witch descriptor to set (the descriptor 0 is not used),1 means the first descriptor
    u8  segmentType : 4;    //data segment or code segment or stack segment
    u8  segmentOrSystemCall :1;//to revise the name of this after you know what it does
    u8  Ring:2; //ring0 is kernel segment and ring=3 for user mode segment,this used for protection
    u8  presentOrSwaped:1;  //to indicate if the segment is present in memory or it has been swaped to the HDD
    u8  segmentLimit_16_19:4;
    u8  NotUsed:2;      //this 2 bits feild is not used , so just put it to 0
    u8  instructionSize:1;  //instructionSize=1 for 32bit instructions
    u8  limitUnit:1;    //0 if the limit is expressed in bytes or 1 if the limit is in pages
    u32  segmentBase : adresse of the beginnig of the segment
    u32 limit :size of the descriptor, if limitUnit=limitInBytes so this limit is expressed in byte not in pages
 * 
 */
void GDT_set_descriptor(u32 descriptor,u32 base,u32 limit,u8 segmentType,u8 segmentOrSystemCall,u8 ring,u8 presentOrSwaped, u8 instructionSize, u8 limitUnit)
{**===============ERROR 1**
    struct gdtDescriptor gd;
    
    //set gdt base
    gd.segmentBase_0_15=(base & 0xffff);
    gd.segmentBase_16_23=((base>>16) & 0xff);
    gd.segmentBase_24_31=((base>>24) & 0xff);
            
    //set gdt limit
    gd.segmentLimit_0_15= (limit & 0xffff);
    gd.segmentLimit_16_19=((limit>>16)  & 0xf);
    
    //other descriptor bits
    gd.segmentType=segmentType;
    gd.segmentOrSystemCall=segmentOrSystemCall;
    gd.Ring=ring;
    gd.presentOrSwaped=presentOrSwaped;
    gd.NotUsed=0;
    gd.instructionSize=instructionSize;
    gd.limitUnit=limitUnit;
    
    //add this gd descriptor to the GDT table
    GDT[descriptor]=gd;
    
}
        
        
        
/*! 
 * GDT_install :  load the new GDT to the gdtr register, that means 
 */     
void GDT_install()**===============ERROR 3**
{
    //we need assembly here ! to make the GDTR register points our new GDT 
    asm("lgdt (gdtr)");
}
        
        
/*! 
 * GDT_install :  load the new GDT to the gdtr register, that means 
 */     
void GDT_load_descriptor(u32 descriptor)
{
    //this function must be edited so that we can add a  code descriptor or a data descriptor
    //for exemple  GDT_load_descriptor_CS(2) this will load the second descriptor as a CS segment ie cs<--descriptor(2) 
}
    

4 errors i noftify the places inside the code ===============ERROR number

so what could be the problem?

Was it helpful?

Solution

The problem is that the definition of GDT_set_descriptor occurs after it's referenced.

If a function is called without a preceding definition or declaration, the compiler makes certain assumptions ("implicit declaration") -- these correspond to the default assumptions made in the original C language implementation: return value assumed to be integer, integer-type arguments smaller than "int" are promoted to int, etc. In this case, the compiler later encounters an actual definition of the function that has different return value and arguments. The error is basically telling you "I assumed that but now you're telling me this".

Easy to fix. Either:
(a) invert the order of functions in the source so that the called function appears earlier in the file than the calling code.
(b) Provide forward declarations of the functions near the top of the file (or as is typically done, via a separate header file).

(a) is usually less work, but (b) is often a more general solution -- especially if you anticipate needing to call the respective function from multiple source modules, it's often easiest to put the declaration into a header.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top