ASFLAGS += -D ARCH=\"$(ARCH)\"
LDFLAGS += -T arch/$(ARCHDIR)/link.ld
+if $(KERNEL_DEBUG) != "" then
+ LDFLAGS += -g
+if $(KERNEL_DEBUG) != "" then
+ CFLAGS += -g
+
OBJ = $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
OBJ += heap.o messages.o debug.o modules.o lib.o syscalls.o system.o threads.o drvutil.o
OBJ += binary.o bin/elf.o
$(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile
@echo --- LD -o $(BIN)
@$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) -Map ../Map.$(ARCH).txt
- @objdump $(BIN) -D > $(BIN).dsm
+ @objdump $(BIN) -D -S > $(BIN).dsm
@wc -l $(SRCFILES) > LineCounts.$(ARCH).txt
@echo BUILD_NUM = `calc $(BUILD_NUM)+1` > Makefile.BuildNum
-BUILD_NUM = 1084
+BUILD_NUM = 1124
typedef signed long long Sint64;
typedef Uint size_t;
-#if USE_PAE
typedef Uint64 tPAddr;
-#else
-typedef Uint32 tPAddr;
-#endif
typedef Uint32 tVAddr;
typedef struct {
// === FUNCTIONS ===
extern tPAddr MM_AllocPhys();
-extern void MM_RefPhys(Uint32 Addr);
-extern void MM_DerefPhys(Uint32 Addr);
+extern tPAddr MM_AllocPhysRange(int Pages);
+extern void MM_RefPhys(tPAddr Addr);
+extern void MM_DerefPhys(tPAddr Addr);
extern int MM_GetRefCount(tPAddr Addr);
#endif
extern tPAddr MM_Allocate(tVAddr VAddr);
extern void MM_Deallocate(tVAddr VAddr);
extern int MM_Map(tVAddr VAddr, tPAddr PAddr);
-extern tVAddr MM_Clone();
+extern tPAddr MM_Clone();
extern tVAddr MM_NewKStack();
extern tVAddr MM_NewWorkerStack();
Uint32 ES, CS, DS, SS, FS, GS;
Uint32 LDTR;
Uint16 Resvd, IOPB; // IO Permissions Bitmap
-} tTSS;
+} __attribute__((packed)) tTSS;
// === FUNCTIONS ===
extern void Proc_Start();
*(KEXPORT)
gKernelSymbolsEnd = .;
+
}
+ /*
+ .debug_abbrev : { *(.debug_abbrev) }
+ .debug_info : { *(.debug_info) }
+ .debug_line : { *(.debug_line) }
+ .debug_loc : { *(.debug_loc) }
+ .debug_pubnames : { *(.debug_pubnames) }
+ .debug_aranges : { *(.debug_aranges) }
+ .debug_ranges : { *(.debug_ranges) }
+ .debug_str : { *(.debug_str) }
+ .debug_frame : { *(.debug_frame) }
+ */
.padata ALIGN (0x1000) : AT(ADDR(.padata) - 0xC0000000) {
*(.padata)
extern void gKernelEnd;
// === PROTOTYPES ===
-Uint32 MM_AllocPhys();
-void MM_RefPhys(Uint32 Addr);
-void MM_DerefPhys(Uint32 Addr);
+tPAddr MM_AllocPhys();
+tPAddr MM_AllocPhysRange(int Pages);
+void MM_RefPhys(tPAddr Addr);
+void MM_DerefPhys(tPAddr Addr);
// === GLOBALS ===
int giPhysAlloc = 0;
MM_Allocate( REFERENCE_BASE + (num<<12) );
}
+ LOG("Filling");
// Fill references
gaPageReferences = (void*)REFERENCE_BASE;
memsetd(gaPageReferences, 1, kernelPages);
{
int num = giPageCount / 32 / 32;
int a, b, c;
- Uint32 ret;
+ tPAddr ret;
LOCK( &giPhysAlloc );
{
int num = giPageCount / 32 / 32;
int a, b, c;
- Uint32 ret;
+ tPAddr ret;
LOCK( &giPhysAlloc );
#define INVLPG(addr) __asm__ __volatile__ ("invlpg (%0)"::"r"(addr))
+#if USE_PAE
+typedef Uint64 tTabEnt;
+#else
+typedef Uint32 tTabEnt;
+#endif
+
// === IMPORTS ===
extern Uint32 gaInitPageDir[1024];
extern Uint32 gaInitPageTable[1024];
tPAddr MM_DuplicatePage(tVAddr VAddr);
// === GLOBALS ===
-tPAddr *gaPageTable = (void*)PAGE_TABLE_ADDR;
-tPAddr *gaPageDir = (void*)PAGE_DIR_ADDR;
-tPAddr *gaPageCR3 = (void*)PAGE_CR3_ADDR;
-tPAddr *gaTmpTable = (void*)TMP_TABLE_ADDR;
-tPAddr *gaTmpDir = (void*)TMP_DIR_ADDR;
-tPAddr *gTmpCR3 = (void*)TMP_CR3_ADDR;
+#define gaPageTable ((tTabEnt*)PAGE_TABLE_ADDR)
+#define gaPageDir ((tTabEnt*)PAGE_DIR_ADDR)
+#define gaPageCR3 ((tTabEnt*)PAGE_CR3_ADDR)
+#define gaTmpTable ((tTabEnt*)TMP_TABLE_ADDR)
+#define gaTmpDir ((tTabEnt*)TMP_DIR_ADDR)
+#define gTmpCR3 ((tTabEnt*)TMP_CR3_ADDR)
+//tPAddr *gaPageTable = (void*)PAGE_TABLE_ADDR;
+//tPAddr *gaPageDir = (void*)PAGE_DIR_ADDR;
+//tPAddr *gaPageCR3 = (void*)PAGE_CR3_ADDR;
+//tPAddr *gaTmpTable = (void*)TMP_TABLE_ADDR;
+//tPAddr *gaTmpDir = (void*)TMP_DIR_ADDR;
+//tPAddr *gTmpCR3 = (void*)TMP_CR3_ADDR;
int gilTempMappings = 0;
int gilTempFractal = 0;
Uint32 gWorkerStacks[(NUM_WORKER_STACKS+31)/32];
{
gaInitPageDir[ 0 ] = 0;
gaInitPageDir[ PAGE_TABLE_ADDR >> 22 ] = ((Uint)&gaInitPageDir - KERNEL_BASE) | 3;
+ INVLPG( PAGE_TABLE_ADDR );
}
/**
tPAddr MM_Allocate(tVAddr VAddr)
{
tPAddr paddr;
+ //ENTER("xVAddr", VAddr);
+ //__asm__ __volatile__ ("xchg %bx,%bx");
// Check if the directory is mapped
if( gaPageDir[ VAddr >> 22 ] == 0 )
{
// Allocate directory
paddr = MM_AllocPhys();
+ //LOG("paddr = 0x%llx (new table)", paddr);
if( paddr == 0 ) {
Warning("MM_Allocate - Out of Memory (Called by %p)", __builtin_return_address(0));
+ LEAVE('i',0);
return 0;
}
// Map
if(VAddr < MM_USER_MAX) gaPageDir[ VAddr >> 22 ] |= PF_USER;
INVLPG( &gaPageDir[ VAddr >> 22 ] );
+ //LOG("Clearing new table");
memsetd( &gaPageTable[ (VAddr >> 12) & ~0x3FF ], 0, 1024 );
}
// Check if the page is already allocated
else if( gaPageTable[ VAddr >> 12 ] != 0 ) {
Warning("MM_Allocate - Allocating to used address (%p)", VAddr);
+ //LEAVE('X', gaPageTable[ VAddr >> 12 ] & ~0xFFF);
return gaPageTable[ VAddr >> 12 ] & ~0xFFF;
}
// Allocate
paddr = MM_AllocPhys();
+ //LOG("paddr = 0x%llx", paddr);
if( paddr == 0 ) {
Warning("MM_Allocate - Out of Memory when allocating at %p (Called by %p)",
VAddr, __builtin_return_address(0));
+ //LEAVE('i',0);
return 0;
}
// Map
// Invalidate Cache for address
INVLPG( VAddr & ~0xFFF );
+ //LEAVE('X', paddr);
return paddr;
}
*/
void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
{
- tPAddr *ent;
+ tTabEnt *ent;
if( !(gaPageDir[VAddr >> 22] & 1) ) return ;
if( !(gaPageTable[VAddr >> 12] & 1) ) return ;
gTSSs = &gTSS0;
#if USE_MP
}
+ #endif
+
+ Log("sizeof(tTSS) = %i", sizeof(tTSS));
+ Log("sizeof(tGDT) = %i", sizeof(tGDT));
// Initialise Double Fault TSS
gGDT[5].LimitLow = sizeof(tTSS);
gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16;
gGDT[5].BaseHi = (Uint)&gDoubleFault_TSS >> 24;
- // Initialise TSS
+ #if USE_MP
+ // Initialise Normal TSS(s)
for(pos=0;pos<giNumCPUs;pos++)
{
#else
pos = 0;
#endif
+ Log("pos = %i", pos);
gTSSs[pos].SS0 = 0x10;
gTSSs[pos].ESP0 = 0; // Set properly by scheduler
+ gGDT[6+pos].BaseLow = ((Uint)(&gTSSs[pos])) & 0xFFFF;
+ gGDT[6+pos].BaseMid = ((Uint)(&gTSSs[pos])) >> 16;
+ gGDT[6+pos].BaseHi = ((Uint)(&gTSSs[pos])) >> 24;
gGDT[6+pos].LimitLow = sizeof(tTSS);
gGDT[6+pos].LimitHi = 0;
gGDT[6+pos].Access = 0x89; // Type
gGDT[6+pos].Flags = 0x4;
- gGDT[6+pos].BaseLow = (Uint)&gTSSs[pos] & 0xFFFF;
- gGDT[6+pos].BaseMid = (Uint)&gTSSs[pos] >> 16;
- gGDT[6+pos].BaseHi = (Uint)&gTSSs[pos] >> 24;
#if USE_MP
}
for(pos=0;pos<giNumCPUs;pos++) {
LOG("iPageCount = %i", iPageCount);\r
\r
// Allocate Information Structure\r
- ret = malloc( sizeof(tBinary) + 3*sizeof(Uint)*iPageCount );\r
+ ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );\r
// Fill Info Struct\r
ret->Entry = hdr.entrypoint;\r
ret->Base = -1; // Set Base to maximum value\r
if(phtab[i].Type != PT_LOAD) continue;\r
\r
// Find Base\r
- if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr;
-\r
- k = 0;\r
+ if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr;\r
\r
LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}",\r
i, phtab[i].VAddr, phtab[i].Offset, phtab[i].FileSize);\r
\r
// Get Pages\r
count = ( (phtab[i].VAddr&0xFFF) + phtab[i].FileSize + 0xFFF) >> 12;\r
- for(;k<count;k++)\r
+ for( k = 0; k < count; k ++ )\r
{\r
ret->Pages[j+k].Virtual = phtab[i].VAddr + (k<<12);\r
ret->Pages[j+k].Physical = phtab[i].Offset + (k<<12); // Store the offset in the physical address\r
Uint16 shentsize; //!< Section Header Entry Size\r
Uint16 shentcount; //!< Section Header Entry Count\r
Uint16 shstrindex; //!< Section Header String Table Index\r
-};\r
+} __attribute__ ((packed));\r
\r
/**\r
\name Executable Types\r
Uint32 info;\r
Uint32 addralign;\r
Uint32 entsize;\r
-}; //sizeof = 40\r
+} __attribute__ ((packed)); //sizeof = 40\r
\r
struct elf_sym_s {\r
union {\r
Uint8 info;\r
Uint8 other;\r
Uint16 shndx;\r
-};\r
+} __attribute__ ((packed));\r
#define STN_UNDEF 0 // Undefined Symbol\r
\r
enum {\r
Uint32 MemSize;\r
Uint32 Flags;\r
Uint32 Align;\r
-};\r
+} __attribute__ ((packed));\r
\r
struct elf32_rel_s {\r
Uint32 r_offset;\r
Uint32 r_info;\r
-};\r
+} __attribute__ ((packed));\r
\r
struct elf32_rela_s {\r
Uint32 r_offset;\r
Uint32 r_info;\r
Sint32 r_addend;\r
-};\r
+} __attribute__ ((packed));\r
\r
enum {\r
R_386_NONE = 0, // none\r
struct elf32_dyn_s {\r
Uint32 d_tag;\r
Uint32 d_val; //Also d_ptr\r
-};\r
+} __attribute__ ((packed));\r
\r
enum {\r
DT_NULL, //!< Marks End of list\r
#define _BINARY_H
// === TYPES ===
+typedef struct sBinaryPage
+{
+ /**
+ * \brief Physical address, or file offset
+ *
+ * Physical address of this page or, when the file is not yet
+ * loaded, this is a file offset (or -1 for uninitialised data)
+ */
+ tPAddr Physical;
+ tVAddr Virtual; //!< Virtual load address
+ Uint16 Size; //!< Number of bytes to load from the file
+ Uint16 Flags; //!< Load Flags
+} __attribute__ ((packed)) tBinaryPage;
+
/**
* \brief Defines a binary file
*
* \brief Array of pages defined by this binary
* \note Contains \a NumPages entries
*/
- struct {
- /**
- * \brief Physical address, or file offset
- *
- * Physical address of this page or, when the file is not yet
- * loaded, this is a file offset (or -1 for uninitialised data)
- */
- tPAddr Physical;
- tVAddr Virtual; //!< Virtual load address
- Uint16 Size; //!< Number of bytes to load from the file
- Uint16 Flags; //!< Load Flags
- } Pages[];
+ tBinaryPage Pages[];
} tBinary;
/**
* Architecture Independent System Init
* system.c
*/
+#define DEBUG 1
#include <common.h>
// === TYPES ===
{
int fp;
int fLen = 0;
- int i = 0;
+ int i;
char *fData;
tConfigFile *file;
tConfigLine *line;
}
// Create Directory
else if(strcmp(line->Parts[0], "mkdir") == 0) {
- if( line->nParts != 3 ) {
+ if( line->nParts != 2 ) {
Warning("Configuration command 'mkdir' requires 1 argument, %i given",
line->nParts-1);
continue;
}
// Spawn a process
else if(strcmp(line->Parts[0], "spawn") == 0) {
- if( line->nParts != 3 ) {
+ if( line->nParts != 2 ) {
Warning("Configuration command 'spawn' requires 1 argument, %i given",
line->nParts-1);
continue;
// Clean up after ourselves
for( i = 0; i < file->nLines; i++ ) {
+ if( file->Lines[i].nParts == 0 ) continue; // Skip blank
free( file->Lines[i].Parts );
}
free( file );
{
char *ptr;
char *start;
- int nLines = 0;
+ int nLines = 1;
int i, j;
tConfigFile *ret;
+ ENTER("pFileData", FileData);
+
// Prescan and count the number of lines
for(ptr = FileData; *ptr; ptr++)
{
continue;
}
- #if 0 // Don't handle windows style EOLs
- if(ptr[-1] == '\r')
- {
- if( &ptr[-1] == FileData ) {
- nLines ++;
- continue;
- }
- if(ptr[-2] == '\\') continue;
- }
- #endif
-
// Escaped EOL
if(ptr[-1] == '\\') continue;
nLines ++;
}
+ LOG("nLines = %i", nLines);
+
// Ok so we have `nLines` lines, now to allocate our return
ret = malloc( sizeof(tConfigFile) + sizeof(tConfigLine)*nLines );
ret->nLines = nLines;
for(;;)
{
// Read leading whitespace
- while( *ptr && (*ptr == '\t' || *ptr == ' ') ) ptr++;
+ while( *ptr == '\t' || *ptr == ' ' ) ptr++;
// End of line/file
- if( *ptr == '\0' || *ptr == '\n' ) break;
+ if( *ptr == '\0' || *ptr == '\n' ) {
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
// Comment
- if( *ptr == '#' || *ptr == ';' ) break;
+ if( *ptr == '#' || *ptr == ';' ) {
+ while( *ptr && *ptr != '\n' ) ptr ++;
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
ret->Lines[i].nParts ++;
// Quoted
continue;
}
// Unquoted
- while( *ptr && !(*ptr == '\t' || *ptr == ' ') )
+ while( *ptr && !(*ptr == '\t' || *ptr == ' ') && *ptr != '\n' )
ptr++;
}
+ LOG("ret->Lines[%i].nParts = %i", i, ret->Lines[i].nParts);
+
+ if( ret->Lines[i].nParts == 0 ) {
+ ret->Lines[i].Parts = NULL;
+ continue;
+ }
+
// Allocate part list
ret->Lines[i].Parts = malloc( sizeof(char*) * ret->Lines[i].nParts );
for( ptr = start, j = 0; ; j++ )
{
// Read leading whitespace
- while( *ptr && (*ptr == '\t' || *ptr == ' ') ) ptr++;
+ while( *ptr == '\t' || *ptr == ' ' ) ptr++;
// End of line/file
- if( *ptr == '\0' || *ptr == '\n' ) break;
+ if( *ptr == '\0' || *ptr == '\n' ) {
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
// Comment
- if( *ptr == '#' || *ptr == ';' ) break;
-
+ if( *ptr == '#' || *ptr == ';' ) {
+ while( *ptr && *ptr != '\n' ) ptr ++;
+ if(*ptr == '\n') ptr ++;
+ break;
+ }
ret->Lines[i].Parts[j] = ptr;
}
// Unquoted
else {
- while( *ptr && !(*ptr == '\t' || *ptr == ' ') )
+ while( *ptr != '\t' && *ptr != ' ' && *ptr != '\n' )
ptr++;
}
// Break if we have reached NULL
- if( *ptr == '\0' ) break;
+ if( *ptr == '\0' ) {
+ LOG("ret->Lines[%i].Parts[%i] = '%s'", i, j, ret->Lines[i].Parts[j]);
+ break;
+ }
+ if( *ptr == '\n' ) {
+ *ptr = '\0';
+ LOG("ret->Lines[%i].Parts[%i] = '%s'", i, j, ret->Lines[i].Parts[j]);
+ ptr ++;
+ break;
+ }
*ptr = '\0'; // Cap off string
+ LOG("ret->Lines[%i].Parts[%i] = '%s'", i, j, ret->Lines[i].Parts[j]);
ptr ++; // And increment for the next round
}
}
+ LEAVE('p', ret);
return ret;
}