From 38e4b28d370c5f9284b285a71518ae2b6bce125c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 28 Dec 2009 21:20:37 +0800 Subject: [PATCH] Changed the x86 architecture to have tPAddr be 64-bits always - tPAddr being a constant size allows PAE to be selected at runtime (when I complete it :)) - Related bugfixes (where tPAddr was assumed to be 32-bits) - Also fixed bugs in the config file parser - Added -g flag to the build (working on a disable switch) --- Kernel/Makefile | 7 ++- Kernel/Makefile.BuildNum | 2 +- Kernel/arch/x86/include/arch.h | 4 -- Kernel/arch/x86/include/mm_phys.h | 5 +- Kernel/arch/x86/include/mm_virt.h | 2 +- Kernel/arch/x86/include/proc.h | 2 +- Kernel/arch/x86/link.ld | 12 +++++ Kernel/arch/x86/mm_phys.c | 12 +++-- Kernel/arch/x86/mm_virt.c | 36 ++++++++++++--- Kernel/arch/x86/proc.c | 14 ++++-- Kernel/bin/elf.c | 8 ++-- Kernel/bin/elf.h | 14 +++--- Kernel/include/binary.h | 27 ++++++----- Kernel/system.c | 76 +++++++++++++++++++++---------- 14 files changed, 146 insertions(+), 75 deletions(-) diff --git a/Kernel/Makefile b/Kernel/Makefile index 10c63ff3..427f4e04 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -20,6 +20,11 @@ CFLAGS += -Wall -Werror -O3 -fno-stack-protector -fno-builtin 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 @@ -54,7 +59,7 @@ apidoc: $(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 diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index 65deeabc..41c16ab1 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1084 +BUILD_NUM = 1124 diff --git a/Kernel/arch/x86/include/arch.h b/Kernel/arch/x86/include/arch.h index 77cdd706..0afc51d0 100644 --- a/Kernel/arch/x86/include/arch.h +++ b/Kernel/arch/x86/include/arch.h @@ -70,11 +70,7 @@ typedef signed long Sint32; 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 { diff --git a/Kernel/arch/x86/include/mm_phys.h b/Kernel/arch/x86/include/mm_phys.h index 8d461098..2d35587d 100644 --- a/Kernel/arch/x86/include/mm_phys.h +++ b/Kernel/arch/x86/include/mm_phys.h @@ -7,8 +7,9 @@ // === 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 diff --git a/Kernel/arch/x86/include/mm_virt.h b/Kernel/arch/x86/include/mm_virt.h index 2dc3b30e..ec6ca828 100644 --- a/Kernel/arch/x86/include/mm_virt.h +++ b/Kernel/arch/x86/include/mm_virt.h @@ -10,7 +10,7 @@ extern void MM_SetCR3(Uint32 CR3); 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(); diff --git a/Kernel/arch/x86/include/proc.h b/Kernel/arch/x86/include/proc.h index 6619ec0d..5a99c9c5 100644 --- a/Kernel/arch/x86/include/proc.h +++ b/Kernel/arch/x86/include/proc.h @@ -25,7 +25,7 @@ typedef struct sTSS { Uint32 ES, CS, DS, SS, FS, GS; Uint32 LDTR; Uint16 Resvd, IOPB; // IO Permissions Bitmap -} tTSS; +} __attribute__((packed)) tTSS; // === FUNCTIONS === extern void Proc_Start(); diff --git a/Kernel/arch/x86/link.ld b/Kernel/arch/x86/link.ld index 7bce7196..a1427476 100644 --- a/Kernel/arch/x86/link.ld +++ b/Kernel/arch/x86/link.ld @@ -36,7 +36,19 @@ SECTIONS { *(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) diff --git a/Kernel/arch/x86/mm_phys.c b/Kernel/arch/x86/mm_phys.c index 1b79650b..cbb48b08 100644 --- a/Kernel/arch/x86/mm_phys.c +++ b/Kernel/arch/x86/mm_phys.c @@ -13,9 +13,10 @@ 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; @@ -72,6 +73,7 @@ void MM_Install(tMBoot_Info *MBoot) MM_Allocate( REFERENCE_BASE + (num<<12) ); } + LOG("Filling"); // Fill references gaPageReferences = (void*)REFERENCE_BASE; memsetd(gaPageReferences, 1, kernelPages); @@ -89,7 +91,7 @@ tPAddr MM_AllocPhys() { int num = giPageCount / 32 / 32; int a, b, c; - Uint32 ret; + tPAddr ret; LOCK( &giPhysAlloc ); @@ -129,7 +131,7 @@ tPAddr MM_AllocPhysRange(int Pages) { int num = giPageCount / 32 / 32; int a, b, c; - Uint32 ret; + tPAddr ret; LOCK( &giPhysAlloc ); diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index 02bc9ac9..b87967dd 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -41,6 +41,12 @@ #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]; @@ -55,12 +61,18 @@ void MM_DumpTables(tVAddr Start, tVAddr End); 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]; @@ -75,6 +87,7 @@ void MM_PreinitVirtual() { gaInitPageDir[ 0 ] = 0; gaInitPageDir[ PAGE_TABLE_ADDR >> 22 ] = ((Uint)&gaInitPageDir - KERNEL_BASE) | 3; + INVLPG( PAGE_TABLE_ADDR ); } /** @@ -253,13 +266,17 @@ void MM_DumpTables(tVAddr Start, tVAddr End) 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 @@ -268,19 +285,23 @@ tPAddr MM_Allocate(tVAddr VAddr) 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 @@ -290,6 +311,7 @@ tPAddr MM_Allocate(tVAddr VAddr) // Invalidate Cache for address INVLPG( VAddr & ~0xFFF ); + //LEAVE('X', paddr); return paddr; } @@ -694,7 +716,7 @@ tVAddr MM_NewWorkerStack() */ 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 ; diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 60f015b2..8b2e49bc 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -113,6 +113,10 @@ void ArchThreads_Init() 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); @@ -123,21 +127,23 @@ void ArchThreads_Init() 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> 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;posEntry = hdr.entrypoint; ret->Base = -1; // Set Base to maximum value @@ -106,9 +106,7 @@ tBinary *Elf_Load(int fp) if(phtab[i].Type != PT_LOAD) continue; // Find Base - if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr; - - k = 0; + if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr; LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}", i, phtab[i].VAddr, phtab[i].Offset, phtab[i].FileSize); @@ -123,7 +121,7 @@ tBinary *Elf_Load(int fp) // Get Pages count = ( (phtab[i].VAddr&0xFFF) + phtab[i].FileSize + 0xFFF) >> 12; - for(;kPages[j+k].Virtual = phtab[i].VAddr + (k<<12); ret->Pages[j+k].Physical = phtab[i].Offset + (k<<12); // Store the offset in the physical address diff --git a/Kernel/bin/elf.h b/Kernel/bin/elf.h index a2ba3945..07f5ec19 100644 --- a/Kernel/bin/elf.h +++ b/Kernel/bin/elf.h @@ -33,7 +33,7 @@ struct sElf32_Ehdr { Uint16 shentsize; //!< Section Header Entry Size Uint16 shentcount; //!< Section Header Entry Count Uint16 shstrindex; //!< Section Header String Table Index -}; +} __attribute__ ((packed)); /** \name Executable Types @@ -101,7 +101,7 @@ struct sElf32_Shent { Uint32 info; Uint32 addralign; Uint32 entsize; -}; //sizeof = 40 +} __attribute__ ((packed)); //sizeof = 40 struct elf_sym_s { union { @@ -113,7 +113,7 @@ struct elf_sym_s { Uint8 info; Uint8 other; Uint16 shndx; -}; +} __attribute__ ((packed)); #define STN_UNDEF 0 // Undefined Symbol enum { @@ -137,18 +137,18 @@ struct sElf32_Phdr { Uint32 MemSize; Uint32 Flags; Uint32 Align; -}; +} __attribute__ ((packed)); struct elf32_rel_s { Uint32 r_offset; Uint32 r_info; -}; +} __attribute__ ((packed)); struct elf32_rela_s { Uint32 r_offset; Uint32 r_info; Sint32 r_addend; -}; +} __attribute__ ((packed)); enum { R_386_NONE = 0, // none @@ -172,7 +172,7 @@ enum { struct elf32_dyn_s { Uint32 d_tag; Uint32 d_val; //Also d_ptr -}; +} __attribute__ ((packed)); enum { DT_NULL, //!< Marks End of list diff --git a/Kernel/include/binary.h b/Kernel/include/binary.h index ed163bd0..a1265515 100644 --- a/Kernel/include/binary.h +++ b/Kernel/include/binary.h @@ -7,6 +7,20 @@ #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 * @@ -57,18 +71,7 @@ typedef struct sBinary * \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; /** diff --git a/Kernel/system.c b/Kernel/system.c index 66630ce1..3d1ebcad 100644 --- a/Kernel/system.c +++ b/Kernel/system.c @@ -3,6 +3,7 @@ * Architecture Independent System Init * system.c */ +#define DEBUG 1 #include // === TYPES === @@ -198,7 +199,7 @@ void System_ExecuteScript() { int fp; int fLen = 0; - int i = 0; + int i; char *fData; tConfigFile *file; tConfigLine *line; @@ -287,7 +288,7 @@ void System_ExecuteScript() } // 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; @@ -297,7 +298,7 @@ void System_ExecuteScript() } // 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; @@ -315,6 +316,7 @@ void System_ExecuteScript() // 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 ); @@ -332,10 +334,12 @@ tConfigFile *System_Int_ParseFile(char *FileData) { 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++) { @@ -346,23 +350,14 @@ tConfigFile *System_Int_ParseFile(char *FileData) 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; @@ -382,12 +377,19 @@ tConfigFile *System_Int_ParseFile(char *FileData) 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 @@ -398,10 +400,17 @@ tConfigFile *System_Int_ParseFile(char *FileData) 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 ); @@ -409,13 +418,19 @@ tConfigFile *System_Int_ParseFile(char *FileData) 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; @@ -427,16 +442,27 @@ tConfigFile *System_Int_ParseFile(char *FileData) } // 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; } -- 2.20.1