MODULES += Storage/FDDv2
MODULES += Network/NE2000 Network/RTL8139
MODULES += Network/VIARhineII
+MODULES += Network/E1000
MODULES += Display/VESA
MODULES += Display/BochsGA
#MODULES += Display/VIAVideo
CPPFLAGS += -I./include -I./arch/$(ARCHDIR)/include -D_MODULE_NAME_=\"Kernel\"
CPPFLAGS += -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D PLATFORM=\"$(PLATFORM)\" -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
CPPFLAGS += -D KERNEL_VERSION=$(KERNEL_VERSION) -ffreestanding
-CFLAGS += -Wall -fno-stack-protector -Wstrict-prototypes -g
+CFLAGS += -Wall -fno-stack-protector -Wstrict-prototypes -std=gnu99 -g
CFLAGS += -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized
CFLAGS += -O3
LDFLAGS += -T arch/$(ARCHDIR)/link.ld -g
BUILDINFO_SRC := $(OBJDIR)buildinfo.c$(OBJSUFFIX)
OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
+OBJ += pmemmap.o
OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o
OBJ += drvutil_video.o drvutil_disk.o
OBJ += messages.o modules.o syscalls.o system.o
# Output binary
# - Links kernel
# - Disassembles it
-# - Gets a line count
# - Increments the build count
# - Does whatever architecture defined rules
$(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile ../../BuildConf/$(ARCH)/Makefile.cfg ../../BuildConf/$(ARCH)/$(PLATFORM).mk
@echo --- LD -o $(BIN)
@$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) --defsym __buildnum=$$(( $(BUILD_NUM) + 1 )) -Map ../Map.$(ARCH).txt
@$(DISASM) -S $(BIN) > $(BIN).dsm
- @wc -l $(SRCFILES) include/*.h > LineCounts.$(ARCH).txt
@echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum.$(ARCH)
$(POSTBUILD)
@cp $(BIN) $(BIN)_
@mkdir -p $(dir $@)
@$(AS) $(ASFLAGS) $< -o $@
ifeq ($(AS_SUFFIX),S)
- @$(MAKEDEP) $(CPPFLAGS) -MT $@ -o $(OBJDIR)$*.ao.dep$(OBJSUFFIX) $<
+ @$(MAKEDEP) $(CPPFLAGS) -MT $@ -MP -o $(OBJDIR)$*.ao.dep$(OBJSUFFIX) $<
endif
# C Sources
@echo --- CC -o $@
@mkdir -p $(dir $@)
@$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
- @$(MAKEDEP) $(CPPFLAGS) -MT $@ -o $(OBJDIR)$*.o.dep$(OBJSUFFIX) $<
+ @$(MAKEDEP) $(CPPFLAGS) -MT $@ -MP -o $(OBJDIR)$*.o.dep$(OBJSUFFIX) $<
# Build-time linked modules
%.xo.$(ARCH):
include/syscalls.h include/syscalls.inc.asm: syscalls.lst Makefile GenSyscalls.pl
perl GenSyscalls.pl
-# Rules based on the makefile
-Makefile: ../../Makefile.cfg arch/$(ARCHDIR)/Makefile
+# Differences for the makefile
+Makefile: ../../Makefile.cfg ../../BuildConf/$(ARCH)/Makefile.cfg ../../BuildConf/$(ARCH)/$(PLATFORM).mk arch/$(ARCHDIR)/Makefile
# Build-time information (git hash and build number)
$(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) $(MODS) arch/$(ARCHDIR)/link.ld Makefile
+ $(eval _GITHASH=$(shell git log -n 1 | head -n 1 | awk '{print $$2}'))
+ $(eval _GITCHANGED=$(shell git status --porcelain | grep -c '^ M '))
@echo "#include <acess.h>" > $@
- @echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@
+ @echo "const char gsGitHash[] = \"$(_GITHASH)\";" >> $@
@echo "const int giBuildNumber = $(BUILD_NUM);" >> $@
+ @echo "const char gsBuildInfo[] = \"Acess2 v$(KERNEL_VERSION) $(ARCH)-$(PLATFORM)\\\\r\\\\n\"" >> $@
+ @echo " \"Build $(shell hostname --fqdn):$(BUILD_NUM) Git $(_GITHASH) - $(_GITCHANGED) modified\";" >> $@
# Compile rule for buildinfo (needs a special one because it's not a general source file)
$(BUILDINFO_OBJ): $(BUILDINFO_SRC)
@echo --- CC -o $@
# Dependency Files
-include $(DEPFILES)
+
LogF("Backtrace: 0x%x", eip);
// else
// LogF("Backtrace: %s+0x%x", str, delta);
- if(!MM_GetPhysAddr(ebp))
+ if(!MM_GetPhysAddr((void*)ebp))
{
LogF("\nBacktrace: Invalid EBP %p, stopping\n", ebp);
return;
}
- while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
+ while( MM_GetPhysAddr((void*)ebp) && i < MAX_BACKTRACE )
{
if( ebp >= MM_KERNEL_STACKS_END ) break;
//str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
#include <init.h>
#include <mm_virt.h>
#include <mp.h>
+#include <pmemmap.h>
#define VGA_ERRORS 0
+#define KERNEL_LOAD 0x100000 // 1MiB
#define MAX_ARGSTR_POS (0x400000-0x2000)
+#define MAX_PMEMMAP_ENTS 16
// === IMPORTS ===
+extern char gKernelEnd[];
extern void Heap_Install(void);
-extern void Desctab_Install(void);
extern void MM_PreinitVirtual(void);
-extern void MM_Install(tMBoot_Info *MBoot);
+extern void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges);
extern void MM_InstallVirtual(void);
-extern void Threads_Init(void);
extern int Time_Setup(void);
-// --- Core ---
-extern void System_Init(char *Commandline);
// === PROTOTYPES ===
int kmain(Uint MbMagic, void *MbInfoPtr);
// === CODE ===
int kmain(Uint MbMagic, void *MbInfoPtr)
{
- int i;
tMBoot_Module *mods;
tMBoot_Info *mbInfo;
+ tPMemMapEnt pmemmap[MAX_PMEMMAP_ENTS];
+ int nPMemMapEnts;
- LogF("Acess2 x86-"PLATFORM" v"EXPAND_STR(KERNEL_VERSION)"\r\n");
- LogF(" Build %i, Git Hash %s\r\n", BUILD_NUM, gsGitHash);
+ LogF("%s\r\n", gsBuildInfo);
- Log("MbMagic = %08x, MbInfoPtr = %p", MbMagic, MbInfoPtr);
-
- // Set up non-boot info dependent stuff
- Desctab_Install(); // Set up GDT and IDT
MM_PreinitVirtual(); // Initialise virtual mappings
-
+
+ mbInfo = MbInfoPtr;
+
switch(MbMagic)
{
// Multiboot 1
- case MULTIBOOT_MAGIC:
+ case MULTIBOOT_MAGIC: {
+ // TODO: Handle when this isn't in the mapped area
+ gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
+
+ tMBoot_MMapEnt *ent = (void*)mbInfo->MMapAddr;
+ tMBoot_MMapEnt *last = (void*)(mbInfo->MMapAddr + mbInfo->MMapLength);
+
+ // Build up memory map
+ nPMemMapEnts = 0;
+ while( ent < last && nPMemMapEnts < MAX_PMEMMAP_ENTS )
+ {
+ tPMemMapEnt *nent = &pmemmap[nPMemMapEnts];
+ nent->Start = ent->Base;
+ nent->Length = ent->Length;
+ switch(ent->Type)
+ {
+ case 1:
+ nent->Type = PMEMTYPE_FREE;
+ break;
+ default:
+ nent->Type = PMEMTYPE_RESERVED;
+ break;
+ }
+ nent->NUMADomain = 0;
+
+ nPMemMapEnts ++;
+ ent = (void*)( (tVAddr)ent + ent->Size + 4 );
+ }
+
+ // Ensure it's valid
+ nPMemMapEnts = PMemMap_ValidateMap(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS);
+ // TODO: Error handling
+
+ // Replace kernel with PMEMTYPE_USED
+ nPMemMapEnts = PMemMap_MarkRangeUsed(
+ pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
+ KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_LOAD - KERNEL_BASE
+ );
+
+ // Replace modules with PMEMTYPE_USED
+ nPMemMapEnts = PMemMap_MarkRangeUsed(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
+ mbInfo->Modules, mbInfo->ModuleCount*sizeof(*mods)
+ );
+ mods = (void*)mbInfo->Modules;
+ for( int i = 0; i < mbInfo->ModuleCount; i ++ )
+ {
+ nPMemMapEnts = PMemMap_MarkRangeUsed(
+ pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS,
+ mods->Start, mods->End - mods->Start
+ );
+ }
+
+ // Debug - Output map
+ PMemMap_DumpBlocks(pmemmap, nPMemMapEnts);
+
// Adjust Multiboot structure address
mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
- gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE);
- MM_Install( mbInfo ); // Set up physical memory manager
- break;
+ break; }
// Multiboot 2
case MULTIBOOT2_MAGIC:
return 0;
}
+ // Set up physical memory manager
+ MM_Install(nPMemMapEnts, pmemmap);
+
MM_InstallVirtual(); // Clean up virtual address space
Heap_Install(); // Create initial heap
mods = (void*)( mbInfo->Modules + KERNEL_BASE );
giArch_NumBootModules = mbInfo->ModuleCount;
gaArch_BootModules = malloc( giArch_NumBootModules * sizeof(*gaArch_BootModules) );
- for( i = 0; i < mbInfo->ModuleCount; i ++ )
+ for( int i = 0; i < mbInfo->ModuleCount; i ++ )
{
int ofs;
*/
#define DEBUG 0
#include <acess.h>
-#include <mboot.h>
#include <mm_virt.h>
+#include <pmemmap.h>
+#include <hal_proc.h>
//#define USE_STACK 1
#define TRACE_ALLOCS 0 // Print trace messages on AllocPhys/DerefPhys
static const int numAddrClasses = sizeof(addrClasses)/sizeof(addrClasses[0]);
// === IMPORTS ===
-extern char gKernelEnd[];
extern void Proc_PrintBacktrace(void);
// === PROTOTYPES ===
-void MM_Install(tMBoot_Info *MBoot);
+void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges);
//tPAddr MM_AllocPhys(void);
//tPAddr MM_AllocPhysRange(int Pages, int MaxBits);
//void MM_RefPhys(tPAddr PAddr);
#define REFENT_PER_PAGE (0x1000/sizeof(gaPageReferences[0]))
// === CODE ===
-void MM_Install(tMBoot_Info *MBoot)
+void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges)
{
- Uint kernelPages, num;
Uint i;
Uint64 maxAddr = 0;
- tMBoot_Module *mods;
- tMBoot_MMapEnt *ent;
// --- Find largest address
- MBoot->MMapAddr |= KERNEL_BASE;
- ent = (void *)( MBoot->MMapAddr );
- while( (Uint)ent < MBoot->MMapAddr + MBoot->MMapLength )
+ for( i = 0; i < NPMemRanges; i ++ )
{
- // Adjust for size
- ent->Size += 4;
-
+ tPMemMapEnt *ent = &PMemRanges[i];
// If entry is RAM and is above `maxAddr`, change `maxAddr`
- if(ent->Type == 1)
+ if(ent->Type == PMEMTYPE_FREE || ent->Type == PMEMTYPE_USED)
{
- if(ent->Base + ent->Length > maxAddr)
- maxAddr = ent->Base + ent->Length;
+ if(ent->Start + ent->Length > maxAddr)
+ maxAddr = ent->Start + ent->Length;
giTotalMemorySize += ent->Length >> 12;
}
- // Go to next entry
- ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size );
}
- if(maxAddr == 0) {
- giPageCount = (MBoot->HighMem >> 2) + 256; // HighMem is a kByte value
- }
- else {
- giPageCount = maxAddr >> 12;
- }
+ giPageCount = maxAddr >> 12;
giLastPossibleFree = giPageCount - 1;
memsetd(gaPageBitmap, 0xFFFFFFFF, giPageCount/32);
// Set up allocateable space
- ent = (void *)( MBoot->MMapAddr );
- while( (Uint)ent < MBoot->MMapAddr + MBoot->MMapLength )
- {
- memsetd( &gaPageBitmap[ent->Base/(4096*32)], 0, ent->Length/(4096*32) );
- ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size );
+ for( i = 0; i < NPMemRanges; i ++ )
+ {
+ tPMemMapEnt *ent = &PMemRanges[i];
+ if( ent->Type == PMEMTYPE_FREE )
+ {
+ Uint64 startpg = ent->Start / PAGE_SIZE;
+ Uint64 pgcount = ent->Length / PAGE_SIZE;
+ while( startpg % 32 && pgcount ) {
+ gaPageBitmap[startpg/32] &= ~(1U << (startpg%32));
+ startpg ++;
+ pgcount --;
+ }
+ memsetd( &gaPageBitmap[startpg/32], 0, pgcount/32 );
+ startpg += pgcount - pgcount%32;
+ pgcount -= pgcount - pgcount%32;
+ while(pgcount) {
+ gaPageBitmap[startpg/32] &= ~(1U << (startpg%32));
+ startpg ++;
+ pgcount --;
+ }
+ }
+ else if( ent->Type == PMEMTYPE_USED )
+ {
+ giPhysAlloc += ent->Length / PAGE_SIZE;
+ }
}
-
- // Get used page count (Kernel)
- kernelPages = (Uint)&gKernelEnd - KERNEL_BASE - 0x100000;
- kernelPages += 0xFFF; // Page Align
- kernelPages >>= 12;
- giPhysAlloc += kernelPages; // Add to used count
- // Fill page bitmap
- num = kernelPages/32;
- memsetd( &gaPageBitmap[0x100000/(4096*32)], -1, num );
- gaPageBitmap[ 0x100000/(4096*32) + num ] = (1 << (kernelPages & 31)) - 1;
-
// Fill Superpage bitmap
- num = kernelPages/(32*32);
- memsetd( &gaSuperBitmap[0x100000/(4096*32*32)], -1, num );
- gaSuperBitmap[ 0x100000/(4096*32*32) + num ] = (1 << ((kernelPages / 32) & 31)) - 1;
-
- // Mark Multiboot's pages as taken
- // - Structure
- MM_RefPhys( (Uint)MBoot - KERNEL_BASE );
- // - Module List
- for(i = (MBoot->ModuleCount*sizeof(tMBoot_Module)+0xFFF)>12; i--; )
- MM_RefPhys( MBoot->Modules + (i << 12) );
- // - Modules
- mods = (void*)(MBoot->Modules + KERNEL_BASE);
- for(i = 0; i < MBoot->ModuleCount; i++)
+ // - A set bit means that there are no free pages in this block of 32
+ for( i = 0; i < (giPageCount+31)/32; i ++ )
{
- num = (mods[i].End - mods[i].Start + 0xFFF) >> 12;
- while(num--)
- MM_RefPhys( (mods[i].Start & ~0xFFF) + (num<<12) );
+ if( gaPageBitmap[i] + 1 == 0 ) {
+ gaSuperBitmap[i/32] |= (1 << i%32);
+ }
}
-
+
gaPageReferences = (void*)MM_REFCOUNT_BASE;
Log_Log("PMem", "Physical memory set up (%lli pages of ~%lli MiB used)",
- giPhysAlloc, (giTotalMemorySize*4)/1024
+ giPhysAlloc, (giTotalMemorySize*PAGE_SIZE)/(1024*1024)
);
}
}
// Mark page used
- if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[indx] ) )
+ if( MM_GetPhysAddr( &gaPageReferences[indx] ) )
gaPageReferences[indx] = 1;
gaPageBitmap[ indx>>5 ] |= 1 << (indx&31);
*/
tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
{
- int a, b;
int i, idx, sidx;
tPAddr ret;
}
idx = sidx / 32;
sidx %= 32;
- b = idx % 32;
- a = idx / 32;
#if 0
LOG("a=%i, b=%i, idx=%i, sidx=%i", a, b, idx, sidx);
// Mark pages used
for( i = 0; i < Pages; i++ )
{
- if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[idx*32+sidx] ) )
+ if( MM_GetPhysAddr( &gaPageReferences[idx*32+sidx] ) )
gaPageReferences[idx*32+sidx] = 1;
gaPageBitmap[ idx ] |= 1 << sidx;
sidx ++;
// Reference the page
if( gaPageReferences )
{
- if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 )
+ if( MM_GetPhysAddr( &gaPageReferences[PAddr] ) == 0 )
{
int i, base;
tVAddr addr = ((tVAddr)&gaPageReferences[PAddr]) & ~0xFFF;
giLastPossibleFree = PAddr;
// Dereference
- if( !MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) || (-- gaPageReferences[PAddr]) == 0 )
+ if( !MM_GetPhysAddr( &gaPageReferences[PAddr] ) || (-- gaPageReferences[PAddr]) == 0 )
{
#if TRACE_ALLOCS
Log_Debug("PMem", "MM_DerefPhys: Free'd %P (%i free)", PAddr<<12, giPageCount-giPhysAlloc);
if(gaPageBitmap[ PAddr / 32 ] == 0)
gaSuperBitmap[ PAddr >> 10 ] &= ~(1 << ((PAddr >> 5)&31));
- if( MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) )
+ if( MM_GetPhysAddr( &gaPageNodes[PAddr] ) )
{
gaPageNodes[PAddr] = NULL;
// TODO: Free Node Page when fully unused
// We don't care about non-ram pages
if(PAddr >= giPageCount) return -1;
- if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 )
+ if( MM_GetPhysAddr( &gaPageReferences[PAddr] ) == 0 )
return (gaPageBitmap[PAddr / 32] & (1 << PAddr%32)) ? 1 : 0;
// Check if it is freed
block_addr = (tVAddr) &gaPageNodes[PAddr];
block_addr &= ~(PAGE_SIZE-1);
- if( !MM_GetPhysAddr( block_addr ) )
+ if( !MM_GetPhysAddr( (void*)block_addr ) )
{
if( !MM_Allocate( block_addr ) ) {
Log_Warning("PMem", "Unable to allocate Node page");
if( MM_GetRefCount(PAddr) == 0 ) return 1;
PAddr /= PAGE_SIZE;
- if( !MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) {
+ if( !MM_GetPhysAddr( &gaPageNodes[PAddr] ) ) {
*Node = NULL;
return 0;
}
* \fn tPAddr MM_GetPhysAddr(tVAddr Addr)
* \brief Checks if the passed address is accesable
*/
-tPAddr MM_GetPhysAddr(tVAddr Addr)
+tPAddr MM_GetPhysAddr(const void *Addr)
{
- if( !(gaPageDir[Addr >> 22] & 1) )
+ tVAddr addr = (tVAddr)Addr;
+ if( !(gaPageDir[addr >> 22] & 1) )
return 0;
- if( !(gaPageTable[Addr >> 12] & 1) )
+ if( !(gaPageTable[addr >> 12] & 1) )
return 0;
- return (gaPageTable[Addr >> 12] & ~0xFFF) | (Addr & 0xFFF);
+ return (gaPageTable[addr >> 12] & ~0xFFF) | (addr & 0xFFF);
}
/**
for(base = MM_KERNEL_STACKS; base < MM_KERNEL_STACKS_END; base += MM_KERNEL_STACK_SIZE)
{
// Check if space is free
- if(MM_GetPhysAddr(base) != 0) continue;
+ if(MM_GetPhysAddr( (void*) base) != 0)
+ continue;
// Allocate
//for(i = MM_KERNEL_STACK_SIZE; i -= 0x1000 ; )
for(i = 0; i < MM_KERNEL_STACK_SIZE; i += 0x1000 )
*/
tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
{
- tPAddr maxCheck = (1 << MaxBits);
tPAddr phys;
tVAddr ret;
return 0;
}
- // Bound
- if(MaxBits >= PHYS_BITS) maxCheck = -1;
-
// Fast Allocate
if(Pages == 1 && MaxBits >= PHYS_BITS)
{
*/
void Proc_Start(void)
{
- int tid;
#if USE_MP
int i;
#endif
if(i) gaCPUs[i].Current = NULL;
// Create Idle Task
- tid = Proc_NewKThread(Proc_IdleThread, &gaCPUs[i]);
+ Proc_NewKThread(Proc_IdleThread, &gaCPUs[i]);
// Start the AP
if( i != giProc_BootProcessorID ) {
while( giNumInitingCPUs ) __asm__ __volatile__ ("hlt");
#else
// Create Idle Task
- tid = Proc_NewKThread(Proc_IdleThread, &gaCPUs[0]);
-// gaCPUs[0].IdleThread = Threads_GetThread(tid);
+ Proc_NewKThread(Proc_IdleThread, &gaCPUs[0]);
// Set current task
gaCPUs[0].Current = &gThreadZero;
tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
{
Uint esp;
- tThread *newThread, *cur;
+ tThread *newThread;
- cur = Proc_GetCurThread();
newThread = Threads_CloneTCB(0);
if(!newThread) return -1;
// Check Prospective Space
for( i = USER_STACK_SZ >> 12; i--; )
- if( MM_GetPhysAddr( base + (i<<12) ) != 0 )
+ if( MM_GetPhysAddr( (void*)(base + (i<<12)) ) != 0 )
break;
if(i != -1) return 0;
__asm__ __volatile__ ("mov %%ebp, %0" : "=r" (stack));
while( maxBacktraceDistance -- )
{
+ if( !CheckMem(stack, 8) ) {
+ regs = NULL;
+ break;
+ }
// [ebp] = oldEbp
// [ebp+4] = retaddr
[section .text]
[extern kmain]
+[extern Desctab_Install]
[global start]
start:
; Just show we're here
.higher_half:
mov WORD [0xB8006], 0x0773 ; 's'
+
+ push ebx ; Multiboot Info
+ push eax ; Multiboot Magic Value
+ ; NOTE: These are actually for kmain
+
+ call Desctab_Install
mov WORD [0xB8008], 0x0773 ; 's'
; Call the kernel
- push ebx ; Multiboot Info
- push eax ; Multiboot Magic Value
mov WORD [0xB800A], 0x0732 ; '2'
call kmain
void *GetSymbol(const char *Name, size_t *Size);\r
void *GetSymbol(const char *Name, size_t *Size) { Uint val; Binary_GetSymbol(Name, &val); if(Size)*Size=0; return (void*)val; };\r
#define AddLoaded(a,b) do{}while(0)\r
-#define LoadLibrary(a,b,c) 0\r
+#define LoadLibrary(a,b,c) (Log_Debug("ELF", "Module requested lib '%s'",a),0)\r
#include "../../../Usermode/Libraries/ld-acess.so_src/elf.c"\r
\r
#define DEBUG_WARN 1\r
_start &= ~(PAGE_SIZE-1);
LOG("_start = %p, _len = 0x%x", _start, _len);
for( ; _len > PAGE_SIZE; _len -= PAGE_SIZE, _start += PAGE_SIZE ) {
- if( MM_GetPhysAddr(_start) != 0 ) {
+ if( MM_GetPhysAddr( (void*)_start ) != 0 ) {
LEAVE('i', 1);
return 1;
}
}
- if( _len == PAGE_SIZE && MM_GetPhysAddr(_start) != 0 ) {
+ if( _len == PAGE_SIZE && MM_GetPhysAddr( (void*)_start ) != 0 ) {
LEAVE('i', 1);
return 1;
}
*/
int SysFS_Install(char **Options)
{
- {
- const char *fmt = "Acess2 "EXPAND_STR(KERNEL_VERSION)" "EXPAND_STR(ARCHDIR)" build %i, hash %s";
- gSysFS_Version_Kernel.Node.Size = snprintf(NULL, 0, fmt, BUILD_NUM, gsGitHash);
- gSysFS_Version_Kernel.Node.ImplPtr = malloc( gSysFS_Version_Kernel.Node.Size + 1 );
- sprintf(gSysFS_Version_Kernel.Node.ImplPtr, fmt, BUILD_NUM, gsGitHash);
- }
+ gSysFS_Version_Kernel.Node.Size = strlen(gsBuildInfo);
+ gSysFS_Version_Kernel.Node.ImplPtr = (void*)gsBuildInfo;
DevFS_AddDevice( &gSysFS_DriverInfo );
return MODULE_ERR_OK;
// Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name);
}
- Log_Debug("VTerm", "Registering with DevFS");
// Add to DevFS
DevFS_AddDevice( &gVT_DrvInfo );
}
// Debug
+ #if 0
switch(NewMode)
{
case TERM_MODE_TEXT:
//case TERM_MODE_3DACCEL:
// return;
}
+ #endif
}
int csr_x, csr_y;
int x, y;
int bytes_per_px = (FBInfo->Depth + 7) / 8;
+ size_t ofs;
ENTER("pFBInfo xOffset xLength pBuffer",
FBInfo, Offset, Length, Buffer);
csr_x = FBInfo->CursorX;
csr_y = FBInfo->CursorY;
+ if( FBInfo->BackBuffer )
+ dest = FBInfo->BackBuffer;
+ else
+ dest = FBInfo->Framebuffer;
+
DrvUtil_Video_RemoveCursor(FBInfo);
switch( FBInfo->BufferFormat )
Length = heightInChars*widthInChars - Offset;
}
- dest = FBInfo->Framebuffer;
- LOG("dest = %p", dest);
- dest += y * giVT_CharHeight * FBInfo->Pitch;
LOG("dest = %p", dest);
+ ofs = y * giVT_CharHeight * FBInfo->Pitch;
+ dest += ofs;
for( i = 0; i < Length; i++ )
{
LOG("dest = %p", dest);
}
}
+ if( x > 0 )
+ dest += FBInfo->Pitch*giVT_CharHeight;
Length = i * sizeof(tVT_Char);
- }
- break;
+
+ break; }
case VIDEO_BUFFMT_FRAMEBUFFER:
if(FBInfo->Width*FBInfo->Height*4 < Offset+Length)
case 15:
case 16:
Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in LFB write");
+ dest = NULL;
break;
case 24:
x = Offset % FBInfo->Width;
y = Offset / FBInfo->Width;
- dest = (Uint8*)FBInfo->Framebuffer + y*FBInfo->Pitch;
+ ofs = y*FBInfo->Pitch;
+ dest += ofs;
for( ; Length >= 4; Length -= 4 )
{
dest[x*3+0] = *src & 0xFF;
x = Offset % FBInfo->Width;
y = Offset / FBInfo->Height;
- px = (Uint32*)FBInfo->Framebuffer + y*FBInfo->Pitch/4;
+ ofs = y*FBInfo->Pitch;
+ dest += ofs;
+ px = (void*)dest;
- for( ; Length >= 4; Length -= 4, x )
+ for( ; Length >= 4; Length -= 4 )
{
px[x++] = *src ++;
if( x == FBInfo->Width ) {
x = 0;
- px += FBInfo->Pitch;
+ dest += FBInfo->Pitch;
+ px = (void*)dest;
}
}
}
else
{
- dest = (Uint8 *)FBInfo->Framebuffer + Offset;
+ ofs = Offset;
+ dest += ofs;
memcpy(dest, Buffer, Length);
}
break;
default:
- Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Unknown bit depthn %i", FBInfo->Depth);
+ Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Unknown bit depth %i", FBInfo->Depth);
+ dest = NULL;
break;
}
break;
FBInfo, Buffer, Length,
&gDrvUtil_Stub_2DFunctions, sizeof(gDrvUtil_Stub_2DFunctions)
);
+ dest = NULL;
break;
default:
LEAVE('i', -1);
return -1;
}
+ if( FBInfo->BackBuffer && dest ) {
+ memcpy((char*)FBInfo->Framebuffer + ofs, (char*)FBInfo->BackBuffer + ofs,
+ ((tVAddr)dest - (tVAddr)FBInfo->BackBuffer) - ofs
+ );
+ }
DrvUtil_Video_DrawCursor(FBInfo, csr_x, csr_y);
{
tDrvUtil_Video_BufInfo *FBInfo = Ent;
- // TODO: Handle non-32bit modes
- if( FBInfo->Depth != 32 ) return;
-
- // TODO: Be less hacky
- int pitch = FBInfo->Pitch/4;
- Uint32 *buf = (Uint32*)FBInfo->Framebuffer + Y*pitch + X;
- while( H -- ) {
- Uint32 *tmp;
- int i;
- tmp = buf;
- for(i=W;i--;tmp++) *tmp = Colour;
- buf += pitch;
+ switch( FBInfo->Depth )
+ {
+ case 32: {
+ // TODO: Be less hacky
+ size_t pitch = FBInfo->Pitch/4;
+ size_t ofs = Y*pitch + X;
+ Uint32 *buf = (Uint32*)FBInfo->Framebuffer + ofs;
+ Uint32 *cbuf = NULL;
+ if( FBInfo->BackBuffer )
+ cbuf = (Uint32*)FBInfo->BackBuffer + ofs;
+ while( H -- )
+ {
+ Uint32 *line;
+ line = buf;
+ for(int i = W; i--; line++)
+ *line = Colour;
+ buf += pitch;
+ if( cbuf ) {
+ line = cbuf;
+ for(int i = W; i--; line++ )
+ *line = Colour;
+ cbuf += pitch;
+ }
+ }
+ break; }
+ default:
+ // TODO: Handle non-32bit modes
+ Log_Warning("DrvUtil", "TODO: <32bpp _Fill");
+ break;
}
}
int dst = DstY*scrnpitch + DstX;
int src = SrcY*scrnpitch + SrcX;
int tmp;
+ Uint8 *framebuffer = FBInfo->Framebuffer;
+ Uint8 *backbuffer = FBInfo->BackBuffer;
+ Uint8 *sourcebuffer = (FBInfo->BackBuffer ? FBInfo->BackBuffer : FBInfo->Framebuffer);
//Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",
// Ent, DstX, DstY, SrcX, SrcY, W, H);
//Debug("W = %i, H = %i", W, H);
- if( dst > src ) {
+ if(W == FBInfo->Width && FBInfo->Pitch == FBInfo->Width*bytes_per_px)
+ {
+ memmove(framebuffer + dst, sourcebuffer + src, H*FBInfo->Pitch);
+ if( backbuffer )
+ memmove(backbuffer + dst, sourcebuffer + src, H*FBInfo->Pitch);
+ }
+ else if( dst > src )
+ {
// Reverse copy
dst += H*scrnpitch;
src += H*scrnpitch;
- while( H -- ) {
+ while( H -- )
+ {
dst -= scrnpitch;
src -= scrnpitch;
tmp = W*bytes_per_px;
- for( tmp = W; tmp --; ) {
- *((Uint8*)FBInfo->Framebuffer + dst + tmp) = *((Uint8*)FBInfo->Framebuffer + src + tmp);
+ for( tmp = W; tmp --; )
+ {
+ size_t src_o = src + tmp;
+ size_t dst_o = src + tmp;
+ framebuffer[dst_o] = sourcebuffer[src_o];
+ if( backbuffer )
+ backbuffer[dst_o] = sourcebuffer[src_o];
}
}
}
- else if(W == FBInfo->Width && FBInfo->Pitch == FBInfo->Width*bytes_per_px) {
- memmove((Uint8*)FBInfo->Framebuffer + dst, (Uint8*)FBInfo->Framebuffer + src, H*FBInfo->Pitch);
- }
else {
// Normal copy is OK
- while( H -- ) {
- memcpy((Uint8*)FBInfo->Framebuffer + dst, (Uint8*)FBInfo->Framebuffer + src, W*bytes_per_px);
+ while( H -- )
+ {
+ memcpy(framebuffer + dst, sourcebuffer + src, W*bytes_per_px);
+ if( backbuffer )
+ memcpy(backbuffer + dst, sourcebuffer + src, W*bytes_per_px);
dst += scrnpitch;
src += scrnpitch;
}
foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) );
#if VERBOSE_DUMP
Log_Log("Heap", "%p (0x%P): 0x%08x (%i) %4C",
- head, MM_GetPhysAddr((tVAddr)head), head->Size, head->ValidSize, &head->Magic);
+ head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->Magic);
Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
if(head->File) {
Log_Log("Heap", "%sowned by %s:%i",
#if !VERBOSE_DUMP
Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
- head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
+ head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->Magic);
if(foot)
Log_Log("Heap", "Foot %p = {Head:%p,Magic:%4C}", foot, foot->Head, &foot->Magic);
if(head->File) {
while( (tVAddr)head >= (tVAddr)badHead )
{
Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
- head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
+ head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->Magic);
Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
if(head->File)
Log_Log("Heap", "%sowned by %s:%i",
#if 1
if( head->Magic == MAGIC_FREE )
Log_Debug("Heap", "%p (%P) - 0x%x free",
- head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size);
+ head->Data, MM_GetPhysAddr(&head->Data), head->Size);
else
Log_Debug("Heap", "%p (%P) - 0x%x (%i) Owned by %s:%i (%lli ms old)",
- head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size, head->ValidSize, head->File, head->Line,
+ head->Data, MM_GetPhysAddr(&head->Data), head->Size, head->ValidSize, head->File, head->Line,
now() - head->AllocateTime
);
#endif
extern char __buildnum[];
#define BUILD_NUM ((int)(Uint)&__buildnum)
-extern const char gsGitHash[];
+extern const char gsGitHash[];
+extern const char gsBuildInfo[];
#define VER2(major,minor) ((((major)&0xFF)<<8)|((minor)&0xFF))
/**
* \param Addr Address of the page to get the physical address of
* \return Physical page mapped at \a Addr
*/
-extern tPAddr MM_GetPhysAddr(tVAddr Addr);
+extern tPAddr MM_GetPhysAddr(const void *Addr);
/**
* \brief Set the access flags on a page
* \param VAddr Virtual address of the page
* \brief Bit depth of the framebuffer\r
*/\r
short Depth;\r
+ /**\r
+ * \brief Cached copy of the screens state (only used if not NULL)\r
+ */\r
+ void *BackBuffer;\r
/*\r
* \}\r
*/\r
extern void Arch_LoadBootModules(void);
extern void StartupPrint(const char *String);
+extern void System_Init(char *Commandline);
+extern void Threads_Init(void);
#endif
--- /dev/null
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * pmemmap.h
+ * - Physical Memory Map definitions
+ */
+#ifndef _PMEMMAP_H_
+#define _PMEMMAP_H_
+
+typedef struct sPMemMapEnt tPMemMapEnt;
+
+enum ePMemMapEntType
+{
+ PMEMTYPE_FREE, // Free RAM
+ PMEMTYPE_USED, // Used by Kernel / Modules
+ PMEMTYPE_RESERVED, // Unavaliable
+ PMEMTYPE_NVRAM, // Non-volatile
+ PMEMTYPE_UNMAPPED // Nothing on these lines
+};
+
+struct sPMemMapEnt
+{
+ Uint64 Start;
+ Uint64 Length;
+ enum ePMemMapEntType Type;
+ Uint16 NUMADomain;
+};
+
+extern void PMemMap_DumpBlocks(tPMemMapEnt *map, int NEnts);
+extern int PMemMap_SplitBlock(tPMemMapEnt *map, int NEnts, int MaxEnts, int Block, Uint64 Offset);
+extern int PMemMap_CompactMap(tPMemMapEnt *map, int NEnts, int MaxEnts);
+extern int PMemMap_ValidateMap(tPMemMapEnt *map, int NEnts, int MaxEnts);
+extern int PMemMap_MarkRangeUsed(tPMemMapEnt *map, int NEnts, int MaxEnts, Uint64 Base, Uint64 Size);
+
+#endif
+
#define _VFS_H
#include <acess.h>
+#include <mutex.h>
/**
* \brief Thread list datatype for VFS_Select
* is unmapped. Nice for read-only files and memory-only files (or
* pseudo-readonly filesystems)
*/
-#define VFS_FFLAG_NOWRITEBACK
+#define VFS_FFLAG_NOWRITEBACK 0x1000
+
+/**
+ * \brief "Dirty Metadata" Flag
+ *
+ * Indicates that the node's metadata has been altered since the flag was last
+ * cleared. Tells the driver that it should update the inode at the next flush.
+ */
+#define VFS_FFLAG_DIRTY 0x8000
/**
* \}
*/
void *memmove(void *__dest, const void *__src, size_t len)
{
- size_t block_size;
char *dest = __dest;
const char *src = __src;
void *ret = __dest;
if( (tVAddr)dest < (tVAddr)src )
return memcpy(dest, src, len);
+ #if 0
+ size_t block_size;
if( (tVAddr)dest < (tVAddr)src )
block_size = (tVAddr)src - (tVAddr)dest;
else
}
memcpy(dest, src, len);
return ret;
+ #else
+ for( int i = len; i--; )
+ {
+ dest[i] = src[i];
+ }
+ return ret;
+ #endif
}
addr = (tVAddr)String;
- if( !MM_GetPhysAddr( addr ) )
+ if( !MM_GetPhysAddr( (void*)addr ) )
return 0;
// Check 1st page
{
if(bUser && !MM_IsUser(addr) )
return 0;
- if(!bUser && !MM_GetPhysAddr(addr) )
+ if(!bUser && !MM_GetPhysAddr((void*)addr) )
return 0;
}
addr ++;
#define USE_EDI 0
#define USE_UDI 0
+#define MODULE_FLAG_LOADERROR 0x1
// === PROTOTYPES ===
int Module_int_Initialise(tModule *Module, const char *ArgString);
"Module %p (%s) is for another architecture (%i)",
Module, Module->Name, Module->Arch
);
+ LEAVE('i', MODULE_ERR_BADMODULE);
+ return MODULE_ERR_BADMODULE;
+ }
+
+ LOG("Module->Flags = %x", Module->Flags);
+ if(Module->Flags & MODULE_FLAG_LOADERROR ) {
+ Log_Warning("Module", "%s has already attempted to load and encountered errors", Module->Name);
+ LEAVE('i', MODULE_ERR_MISC);
+ return MODULE_ERR_MISC;
}
deps = Module->Dependencies;
Log_Warning("Module", "Unable to load reason - Unknown code %i", ret);
break;
}
+ Module->Flags |= MODULE_FLAG_LOADERROR;
LEAVE_RET('i', ret);
return ret;
}
--- /dev/null
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * pmemmap.c
+ * - Physical memory map manipulation
+ */
+#define DEBUG 0
+#include <acess.h>
+#include <pmemmap.h>
+
+// === CODE ===
+void PMemMap_DumpBlocks(tPMemMapEnt *map, int NEnts)
+{
+ for( int i = 0; i < NEnts; i ++ )
+ {
+ Log_Debug("PMemMap", "%i: %i 0x%02x %08llx+%llx",
+ i, map[i].Type, map[i].NUMADomain,
+ map[i].Start, map[i].Length
+ );
+ }
+}
+
+int PMemMap_SplitBlock(tPMemMapEnt *map, int NEnts, int MaxEnts, int Block, Uint64 Offset)
+{
+ LOG("Splitting %i (%llx+%llx) at %llx", Block, map[Block].Start, map[Block].Length, Offset);
+
+ Uint64 _len = map[Block].Length;
+ map[Block].Length = Offset;
+ if( NEnts == MaxEnts ) {
+ // out of space
+ return NEnts;
+ }
+ if( Block < NEnts ) {
+ LOG("Moving %i entries from %i to %i", (NEnts - Block-1), Block+1, Block);
+ memmove(&map[Block+2], &map[Block+1], (NEnts - Block)*sizeof(map[0]));
+ }
+ Block ++;
+ NEnts ++;
+
+ // New (free) block
+ map[Block].Start = map[Block-1].Start + Offset;
+ map[Block].Length = _len - Offset;
+ map[Block].Type = map[Block-1].Type;
+ map[Block].NUMADomain = map[Block-1].NUMADomain;
+ LOG("- New %i %02x %llx+%llx", map[Block].Type, map[Block].NUMADomain, map[Block].Start, map[Block].Length);
+
+ return NEnts;
+}
+
+int PMemMap_CompactMap(tPMemMapEnt *map, int NEnts, int MaxEnts)
+{
+ for( int i = 1; i < NEnts; i ++ )
+ {
+ // Check if the ranges are contiguous
+ if( map[i-1].Start + map[i-1].Length < map[i].Start )
+ continue ;
+ // Check if the type is the same
+ if( map[i-1].Type != map[i].Type )
+ continue ;
+ // Check if the NUMA Domains are the same
+ if( map[i-1].NUMADomain != map[i].NUMADomain )
+ continue ;
+
+ // Ok, they should be together
+ map[i-1].Length += map[i].Length;
+ memmove(&map[i], &map[i+1], (NEnts - (i+1))*sizeof(map[0]));
+ LOG("Joined %i and %i into %llx+%llx", i-1, i, map[i-1].Start, map[i-1].Length);
+
+ // Counteract the i++ in the loop iterator
+ i --;
+ NEnts --;
+ }
+ return NEnts;
+}
+
+int PMemMap_ValidateMap(tPMemMapEnt *map, int NEnts, int MaxEnts)
+{
+ // Sort the pmem map
+ int bNeedsSort = 0;
+ for( int i = 1; i < NEnts; i ++ )
+ {
+ if( map[i-1].Start > map[i].Start ) {
+ bNeedsSort = 1;
+ break;
+ }
+ }
+ if( bNeedsSort )
+ {
+ // Use a selection/swap sort
+ for( int i = 0; i < NEnts; i ++ )
+ {
+ int sel = i;
+ for( int j = i+1; j < NEnts; j ++ )
+ {
+ if( map[j].Start < map[sel].Start )
+ sel = j;
+ }
+ if( sel != i ) {
+ LOG("Swapping %i and %i", i, sel);
+ LOG(" - %llx+%llx", map[i].Start, map[i].Length);
+ LOG(" - %llx+%llx", map[sel].Start, map[sel].Length);
+ tPMemMapEnt tmp = map[i];
+ map[i] = map[sel];
+ map[sel] = tmp;
+ }
+ }
+ }
+
+ // Ensure that the map has no overlaps
+ for( int i = 1; i < NEnts; i ++ )
+ {
+ if( map[i-1].Start + map[i-1].Length <= map[i].Start )
+ continue ;
+ // Oops, overlap!
+ Log_Notice("Arch", "Map ranges %llx+%llx and %llx+%llx overlap",
+ map[i-1].Start, map[i-1].Length,
+ map[i].Start, map[i].Length
+ );
+ }
+
+ NEnts = PMemMap_CompactMap(map, NEnts, MaxEnts);
+ return NEnts;
+}
+
+
+int PMemMap_MarkRangeUsed(tPMemMapEnt *map, int NEnts, int MaxEnts, Uint64 Base, Uint64 Size)
+{
+ int first;
+
+ Size = (Size + 0xFFF) & ~0xFFF;
+ Base = Base & ~0xFFF;
+
+ first = -1;
+ for( int i = 0; i < NEnts; i ++ )
+ {
+ if( map[i].Start + map[i].Length > Base ) {
+ first = i;
+ break;
+ }
+ }
+ if( first == -1 ) {
+ // Not in map
+ LOG("%llx+%llx not in map (past end)", Base, Size);
+ return NEnts;
+ }
+
+ if( map[first].Start > Base ) {
+ // Not in map
+ LOG("%llx+%llx not in map (in hole)", Base, Size);
+ return NEnts;
+ }
+
+ // Detect single
+ if( map[first].Start <= Base && Base + Size <= map[first].Start + map[first].Length )
+ {
+ // Split before
+ if( map[first].Start < Base )
+ {
+ if( NEnts == MaxEnts ) {
+ // out of space... oops
+ return NEnts;
+ }
+ NEnts = PMemMap_SplitBlock(map, NEnts, MaxEnts, first, Base - map[first].Start);
+ first ++;
+ }
+
+ // map[first].Start == Base
+ // Split after
+ if( map[first].Length > Size )
+ {
+ if( NEnts == MaxEnts ) {
+ // out of space
+ return NEnts;
+ }
+ NEnts = PMemMap_SplitBlock(map, NEnts, MaxEnts, first, Size);
+ }
+
+ // map[first] is now exactly the block
+ map[first].Type = PMEMTYPE_USED;
+
+ return PMemMap_CompactMap(map, NEnts, MaxEnts);
+ }
+ else
+ {
+ // Wait... this should never happen, right?
+ Log_Notice("Arch", "Module %llx+%llx overlaps two or more ranges",
+ Base, Size);
+ PMemMap_DumpBlocks(map, NEnts);
+ // TODO: Error?
+ return NEnts;
+ }
+}
+
+
+
// -- Get the physical address of a page
case SYS_GETPHYS:
- ret = MM_GetPhysAddr(Regs->Arg1);
+ ret = MM_GetPhysAddr( (void*)Regs->Arg1 );
break;
// -- Map an address
// - Symbolic Link <link>=<destination>
if(value[0] == '/')
{
- Log_Log("Config", "Symbolic link '%s' pointing to '%s'", Arg, value);
+// Log_Log("Config", "Symbolic link '%s' pointing to '%s'", Arg, value);
VFS_Symlink(Arg, value);
}
// - Mount <mountpoint>=<fs>:<device>
}
// Create Mountpoint
if( (fd = VFS_Open(Arg, 0)) == -1 ) {
- Log_Log("Config", "Creating directory '%s'", Arg, value);
+// Log_Log("Config", "Creating directory '%s'", Arg, value);
VFS_MkDir( Arg );
} else {
VFS_Close(fd);
}
// Mount
- Log_Log("Config", "Mounting '%s' to '%s' ('%s')", dev, Arg, value);
+// Log_Log("Config", "Mounting '%s' to '%s' ('%s')", dev, Arg, value);
VFS_Mount(dev, Arg, value, "");
}
}
{
int max_handles = *Threads_GetMaxFD();
// Allocate Buffer
- if( MM_GetPhysAddr( (tVAddr)gaUserHandles ) == 0 )
+ if( MM_GetPhysAddr( gaUserHandles ) == 0 )
{
Uint addr, size;
size = max_handles * sizeof(tVFS_Handle);
else
{
// Allocate space if not already
- if( MM_GetPhysAddr( (tVAddr)gaKernelHandles ) == 0 )
+ if( MM_GetPhysAddr( gaKernelHandles ) == 0 )
{
Uint addr, size;
size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
int max_handles = *Threads_GetMaxFD();
// Check if this process has any handles
- if( MM_GetPhysAddr( (tVAddr)gaUserHandles ) == 0 )
+ if( MM_GetPhysAddr( gaUserHandles ) == 0 )
return ;
for( i = 0; i < max_handles; i ++ )
int max_handles = *Threads_GetMaxFD();
// Check if this process has any handles
- if( MM_GetPhysAddr( (tVAddr)gaUserHandles ) == 0 )
+ if( MM_GetPhysAddr( gaUserHandles ) == 0 )
return ;
for( i = 0; i < max_handles; i ++ )
int max_handles = *Threads_GetMaxFD();
// Check if this process has any handles
- if( MM_GetPhysAddr( (tVAddr)gaUserHandles ) == 0 )
+ if( MM_GetPhysAddr( gaUserHandles ) == 0 )
return NULL;
// Allocate
return ;
// Check if there is already a set of handles
- if( MM_GetPhysAddr( (tVAddr)gaUserHandles ) != 0 )
+ if( MM_GetPhysAddr( gaUserHandles ) != 0 )
return ;
LOG("%i pages anonymous to %p", npages, mapping_dest);
for( ; npages --; mapping_dest += PAGE_SIZE, ofs += PAGE_SIZE )
{
- if( MM_GetPhysAddr(mapping_dest) ) {
+ if( MM_GetPhysAddr((void*)mapping_dest) ) {
// TODO: Set flags to COW if needed (well, if shared)
MM_SetFlags(mapping_dest, MM_PFLAG_COW, MM_PFLAG_COW);
LOG("clear from %p, %i bytes", (void*)(mapping_base + ofs),
// - Map (and allocate) pages
while( npages -- )
{
- if( MM_GetPhysAddr(mapping_dest) == 0 )
+ if( MM_GetPhysAddr( (void*)mapping_dest ) == 0 )
{
if( pb->PhysAddrs[pagenum - pb->BaseOffset] == 0 )
{
}
// TODO: Clip read length
read_len = nt->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
-// if( read_len != PAGE_SIZE ) {
-// memset( (void*)(mapping_dest+read_len), 0, PAGE_SIZE-read_len );
-// }
+ // TODO: This was commented out, why?
+ if( read_len != PAGE_SIZE ) {
+ memset( (void*)(mapping_dest+read_len), 0, PAGE_SIZE-read_len );
+ }
}
- pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
+ pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( (void*)mapping_dest );
MM_SetPageNode( pb->PhysAddrs[pagenum - pb->BaseOffset], h->Node );
MM_RefPhys( pb->PhysAddrs[pagenum - pb->BaseOffset] );
LOG("Read and map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
\r
Mutex_Release( &glVesa_Lock );\r
\r
+ gVesa_BufInfo.BackBuffer = realloc(gVesa_BufInfo.BackBuffer,\r
+ gVesa_Modes[mode].height * gVesa_Modes[mode].pitch);\r
gVesa_BufInfo.Framebuffer = gpVesa_Framebuffer;\r
gVesa_BufInfo.Pitch = gVesa_Modes[mode].pitch;\r
gVesa_BufInfo.Width = gVesa_Modes[mode].width;\r
Ext2_int_ReadInode(disk, Node->Inode, &inode);
size = inode.i_size;
- LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);
+ LOG("inode={.i_block[0]= 0x%x, .i_size=0x%x}", inode.i_block[0], inode.i_size);
// Find Entry
// Get First Block
// - Do this ourselves as it is a simple operation
Base = inode.i_block[0] * disk->BlockSize;
// Scan directory
- while(Pos -- && size > 0)
+ while(Pos -- && size > 0 && size <= inode.i_size)
{
VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
ofs += dirent.rec_len;
}
ofs = 0;
Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
+ if( Base == 0 ) {
+ size = 0;
+ break;
+ }
}
}
// Check for the end of the list
- if(size <= 0) {
+ if(size <= 0 || size > inode.i_size) {
LEAVE('n');
return NULL;
}
// Read Entry
VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );
- //LOG("dirent.inode = %i", dirent.inode);
- //LOG("dirent.rec_len = %i", dirent.rec_len);
- //LOG("dirent.name_len = %i", dirent.name_len);
+ LOG("dirent={.rec_len=%i,.inode=0x%x,.name_len=%i}",
+ dirent.rec_len, dirent.inode, dirent.name_len);
dirent.name[ dirent.name_len ] = '\0'; // Cap off string
+ if( dirent.name_len == 0 ) {
+ LEAVE('p', VFS_SKIP);
+ return VFS_SKIP;
+ }
// Ignore . and .. (these are done in the VFS)
if( (dirent.name[0] == '.' && dirent.name[1] == '\0')
*/
int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
{
- #if 0
- tVFS_Node *child;
- Uint64 inodeNum;
- tExt2_Inode inode;
- inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode);
+ ENTER("pParent sName xFlags", Parent, Name, Flags);
- memset(&inode, 0, sizeof(tExt2_Inode));
-
- // File type
- inode.i_mode = 0664;
- if( Flags & VFS_FFLAG_READONLY )
- inode.i_mode &= ~0222;
- if( Flags & VFS_FFLAG_SYMLINK )
- inode.i_mode |= EXT2_S_IFLNK;
- else if( Flags & VFS_FFLAG_DIRECTORY )
- inode.i_mode |= EXT2_S_IFDIR | 0111;
-
- inode.i_uid = Threads_GetUID();
- inode.i_gid = Threads_GetGID();
- inode.i_ctime =
- inode.i_mtime =
- inode.i_atime = now() / 1000;
-
- child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum);
- return Ext2_Link(Parent, child, Name);
- #else
- return 1;
- #endif
+ Uint64 inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode);
+ if( inodeNum == 0 ) {
+ return -1;
+ }
+ tVFS_Node *child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum);
+ if( !child ) {
+ Ext2_int_DereferenceInode(Parent->ImplPtr, inodeNum);
+ return -1;
+ }
+
+ child->Flags = Flags & (VFS_FFLAG_DIRECTORY|VFS_FFLAG_SYMLINK|VFS_FFLAG_READONLY);
+ child->UID = Threads_GetUID();
+ child->GID = Threads_GetGID();
+ child->CTime =
+ child->MTime =
+ child->ATime =
+ now();
+ child->ImplInt = 0; // ImplInt is the link count
+ // TODO: Set up ACLs
+
+ int rv = Ext2_Link(Parent, Name, child);
+ child->Type->Close(child);
+ LEAVE('i', rv);
+ return rv;
}
/**
if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
return tmpNode;
-
+
+ memset(&retNode, 0, sizeof(retNode));
// Set identifiers
retNode.Inode = InodeID;
// Set file length
retNode.Size = inode.i_size;
- retNode.Data = NULL;
// Set Access Permissions
retNode.UID = inode.i_uid;
int Ext2_Install(char **Arguments);\r
int Ext2_Cleanup(void);\r
// - Interface Functions\r
- int Ext2_Detect(int FD);\r
+ int Ext2_Detect(int FD);\r
tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options);\r
-void Ext2_Unmount(tVFS_Node *Node);\r
-void Ext2_CloseFile(tVFS_Node *Node);\r
+void Ext2_Unmount(tVFS_Node *Node);\r
+void Ext2_CloseFile(tVFS_Node *Node);\r
// - Internal Helpers\r
- int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
-Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
-Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
-void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
+ int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
+Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
+Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
+void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode);\r
+void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
\r
// === SEMI-GLOBALS ===\r
MODULE_DEFINE(0, VERSION, FS_Ext2, Ext2_Install, Ext2_Cleanup);\r
void Ext2_CloseFile(tVFS_Node *Node)\r
{\r
tExt2_Disk *disk = Node->ImplPtr;\r
- Inode_UncacheNode(disk->CacheID, Node->Inode);\r
+\r
+ if( Mutex_Acquire(&Node->Lock) != 0 )\r
+ {\r
+ return ;\r
+ }\r
+\r
+ if( Node->Flags & VFS_FFLAG_DIRTY )\r
+ {\r
+ // Commit changes\r
+ }\r
+\r
+ int was_not_referenced = (Node->ImplInt == 0);\r
+ tVFS_ACL *acls = Node->ACLs;\r
+ if( Inode_UncacheNode(disk->CacheID, Node->Inode) )\r
+ {\r
+ if( was_not_referenced )\r
+ {\r
+ // Remove inode\r
+ }\r
+ if( acls != &gVFS_ACL_EveryoneRW ) {\r
+ free(acls);\r
+ }\r
+ }\r
return ;\r
}\r
\r
return 0;\r
}\r
\r
+/**\r
+ * \brief Reduce the reference count on an inode\r
+ */\r
+void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode)\r
+{\r
+ \r
+}\r
+\r
/**\r
* \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
* \brief Updates the superblock\r
extern void Ext2_CloseFile(tVFS_Node *Node);
extern Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);
extern void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);
+extern Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);
+extern void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode);
extern int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
extern int Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
// --- Dir ---
}
base = block * disk->BlockSize;
VFS_WriteAt(disk->FD, base, retLen, Buffer);
+
+ // TODO: When should the size update be committed?
inode.i_size += retLen;
+ Node->Size += retLen;
+ Node->Flags |= VFS_FFLAG_DIRTY;
+
retLen = 0;
ret: // Makes sure the changes to the inode are committed
Dir "SBin" {
File "init" "__BIN__/SBin/init"
File "login" "__BIN__/SBin/login"
+ File "telnetd" "__BIN__/SBin/telnetd"
}
Dir "Bin" {
File "CLIShell" "__BIN__/Bin/CLIShell"
*/
int InitRD_Install(char **Arguments)
{
- Log_Notice("InitRD", "Installed");
VFS_AddDriver( &gInitRD_FSInfo );
return MODULE_ERR_OK;
#if DUMP_ON_MOUNT
InitRD_DumpDir( &gInitRD_RootNode, 0 );
#endif
- Log_Notice("InitRD", "Mounted (%i files)", giInitRD_NumFiles);
return &gInitRD_RootNode;
}
#include "buffer.h"
+enum eIPStack_AdapterTypes
+{
+ ADAPTERTYPE_ETHERNET_10M,
+ ADAPTERTYPE_ETHERNET_100M,
+ ADAPTERTYPE_ETHERNET_1G
+};
+
+// Checksum offloading
+#define ADAPTERFLAG_OFFLOAD_MAC (1 << 0)
+#define ADAPTERFLAG_OFFLOAD_IP4 (1 << 1)
+#define ADAPTERFLAG_OFFLOAD_IP6 (1 << 2)
+#define ADAPTERFLAG_OFFLOAD_TCP (1 << 3)
+#define ADAPTERFLAG_OFFLOAD_UDP (1 << 4)
+
typedef struct sIPStack_AdapterType tIPStack_AdapterType;
struct sIPStack_AdapterType
Uint32 flag;
Uint8 layer;
+ if( !Source ) {
+ Log_Error("Keyboard", "Passed NULL handle");
+ return ;
+ }
+ if( !Source->Node ) {
+ Log_Error("Keyboard", "Passed handle with NULL node");
+ return ;
+ }
+
bPressed = !(HIDKeySym & (1 << 31));
HIDKeySym &= 0x7FFFFFFF;
void KBC8042_KeyboardHandler(int IRQ, void *Ptr)
{
- Uint8 scancode;
-
-// Log("KBC8042_KeyboardHandler: (IRQ=%i, Ptr=%p)", IRQ, Ptr);
-
- scancode = inb(0x60);
+ Uint8 scancode = inb(0x60);
KB_HandleScancode( scancode );
}
--- /dev/null
+#
+# Acess2 Intel E1000 driver
+#
+
+OBJ = e1000.o
+NAME = E1000
+
+-include ../Makefile.tpl
+
--- /dev/null
+/*
+ * Acess2 E1000 Network Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * e1000.c
+ * - Intel E1000 Network Card Driver (core)
+ */
+#define DEBUG 1
+#define VERSION VER2(0,1)
+#include <acess.h>
+#include "e1000.h"
+#include <modules.h>
+#include <drv_pci.h>
+#include <IPStack/include/adapters_api.h>
+
+// === PROTOTYPES ===
+ int E1000_Install(char **Arguments);
+ int E1000_Cleanup(void);
+tIPStackBuffer *E1000_WaitForPacket(void *Ptr);
+ int E1000_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
+void E1000_IRQHandler(int Num, void *Ptr);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, E1000, E1000_Install, E1000_Cleanup, NULL);
+tIPStack_AdapterType gE1000_AdapterType = {
+ .Name = "E1000",
+ .Type = 0, // TODO: Differentiate differnet wire protos and speeds
+ .Flags = 0, // TODO: IP checksum offloading, MAC checksum offloading etc
+ .SendPacket = E1000_SendPacket,
+ .WaitForPacket = E1000_WaitForPacket
+ };
+
+// === CODE ===
+int E1000_Install(char **Arguments)
+{
+ for( int id = -1; (id = PCI_GetDevice(0x8086, 0x100E, id)) != -1; )
+ {
+
+ }
+ return MODULE_ERR_NOTNEEDED;
+}
+
+int E1000_Cleanup(void)
+{
+ return 0;
+}
+
+tIPStackBuffer *E1000_WaitForPacket(void *Ptr)
+{
+ return NULL;
+}
+
+int E1000_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
+{
+ return -1;
+}
+
+void E1000_IRQHandler(int Num, void *Ptr)
+{
+}
--- /dev/null
+/*
+ * Acess2 E1000 Network Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * e1000.h
+ * - Driver core header
+ */
+#ifndef _E1000_H_
+#define _E1000_H_
+
+
+
+#endif
+
card->NextTX = (card->NextTX + nDescs) % N_TX_DESCS;
desc = card->TXDescs + first_desc_id;
- desc->TXBufferStart = MM_GetPhysAddr( (tVAddr)data );
+ desc->TXBufferStart = MM_GetPhysAddr( data );
desc->BufferSize = len | (1 << 15);
desc->TSR = 0;
desc->TCR = 0;
IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri, NULL );
IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec, NULL );
- gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[0] );
- gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[1] );
+ gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( &gATA_Buffers[0] );
+ gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( &gATA_Buffers[1] );
LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
- gaATA_PRDT_PAddrs[0] = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[0] );
+ gaATA_PRDT_PAddrs[0] = MM_GetPhysAddr( &gATA_PRDTs[0] );
LOG("gaATA_PRDT_PAddrs[0] = 0x%x", gaATA_PRDT_PAddrs[0]);
ATA_int_BusMasterWriteDWord(4, gaATA_PRDT_PAddrs[0]);
- gaATA_PRDT_PAddrs[1] = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[1] );
+ gaATA_PRDT_PAddrs[1] = MM_GetPhysAddr( &gATA_PRDTs[1] );
LOG("gaATA_PRDT_PAddrs[1] = 0x%x", gaATA_PRDT_PAddrs[1]);
ATA_int_BusMasterWriteDWord(12, gaATA_PRDT_PAddrs[1]);
*/
int USB_Install(char **Arguments)
{
- Log_Warning("USB", "Not Complete - Devel Only");
-
Proc_SpawnWorker(USB_PollThread, NULL);
Proc_SpawnWorker(USB_AsyncThread, NULL);
1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31
};
for( int i = 0; i < 1024; i ++ ) {
- Uint32 addr = MM_GetPhysAddr( (tVAddr)&Host->TDQHPage->ControlQH );
+ Uint32 addr = MM_GetPhysAddr( &Host->TDQHPage->ControlQH );
Host->FrameList[i] = addr | 2;
}
for( int i = 0; i < 64; i ++ ) {
dest += _count; destphys += _count * sizeof(tUHCI_QH);
}
// Skip padding, and move to control QH
- dest->Next = MM_GetPhysAddr( (tVAddr)&Host->TDQHPage->BulkQH ) | 2;
+ dest->Next = MM_GetPhysAddr( &Host->TDQHPage->BulkQH ) | 2;
dest->Child = 1;
}
// Set up control and bulk queues
- Host->TDQHPage->ControlQH.Next = MM_GetPhysAddr( (tVAddr)&Host->TDQHPage->BulkQH ) | 2;
+ Host->TDQHPage->ControlQH.Next = MM_GetPhysAddr( &Host->TDQHPage->BulkQH ) | 2;
Host->TDQHPage->ControlQH.Child = 1;
Host->TDQHPage->BulkQH.Next = 1;
Host->TDQHPage->BulkQH.Child = 1;
// Add
TD->Link = 1;
if( QH->Child & 1 ) {
- QH->Child = MM_GetPhysAddr( (tVAddr)TD );
+ QH->Child = MM_GetPhysAddr( TD );
}
else {
// Depth first
- QH->_LastItem->Link = MM_GetPhysAddr( (tVAddr)TD ) | 4;
+ QH->_LastItem->Link = MM_GetPhysAddr( TD ) | 4;
}
QH->_LastItem = TD;
if(
((tVAddr)Data & (PAGE_SIZE-1)) + Length > PAGE_SIZE
#if PHYS_BITS > 32
- || MM_GetPhysAddr( (tVAddr)Data ) >> 32
+ || MM_GetPhysAddr( Data ) >> 32
#endif
)
{
LOG("Relocated IN");
info = calloc( sizeof(tUHCI_ExtraTDInfo), 1 );
info->Offset = ((tVAddr)Data & (PAGE_SIZE-1));
- info->FirstPage = MM_GetPhysAddr( (tVAddr)Data );
- info->SecondPage = MM_GetPhysAddr( (tVAddr)Data + Length - 1 );
+ info->FirstPage = MM_GetPhysAddr( Data );
+ info->SecondPage = MM_GetPhysAddr( (const char *)Data + Length - 1 );
}
else
{
}
else
{
- td->BufferPointer = MM_GetPhysAddr( (tVAddr)Data );
+ td->BufferPointer = MM_GetPhysAddr( Data );
td->_info.bFreePointer = 0;
}
}
- tPAddr global_pool = MM_GetPhysAddr( (tVAddr)gaUHCI_TDPool );
+ tPAddr global_pool = MM_GetPhysAddr( gaUHCI_TDPool );
if( PAddr < global_pool || PAddr >= global_pool + PAGE_SIZE ) return NULL;
USRAPPS := init login CLIShell cat ls mount
USRAPPS += bomb dhcpclient
-USRAPPS += ip ping telnet irc wget
+USRAPPS += ip ping telnet irc wget telnetd
USRAPPS += axwin3
ALL_DYNMODS = $(addprefix all-,$(DYNMODS))
@echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@
@echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@
@echo "const int giBuildNumber = $(BUILD_NUM);" >> $@
+ @echo "const char gsBuildInfo[] = \"Acess2 DiskTool v$(ACESS_VERSION)\";" >> $@
$(BUILDINFO_OBJ): $(BUILDINFO_SRC)
@echo [CC] -o $@
@$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)
return VFS_Mount(tpath, mountpoint, "", "");
}
+int DiskTool_MkDir(const char *Directory)
+{
+ return -1;
+}
+
int DiskTool_Copy(const char *Source, const char *Destination)
{
int src = DiskTool_int_TranslateOpen(Source, VFS_OPENFLAG_READ);
if( Path[0] == '#' )
{
- if(Buffer)
+ len = strlen(Path+1);
+ if(Buffer) {
strcpy(Buffer, Path+1);
- return strlen(Path) - 1;
+ }
}
-
- if( colon )
+ else if( Path[0] == ':' )
+ {
+ len = strlen("/Devices/LVM/");
+ len += strlen(Path+1);
+ if(Buffer) {
+ strcpy(Buffer, "/Devices/LVM/");
+ strcat(Buffer, Path+1);
+ }
+ }
+ else if( colon )
{
const char *pos;
for(pos = Path; pos < colon; pos ++)
strncat(Buffer+strlen("/Mount/"), Path, colon - Path);
strcat(Buffer, colon + 1);
}
- return len;
}
+ else
+ {
+ native_path:
+ if( !gsWorkingDirectory[0] ) {
+ getcwd(gsWorkingDirectory, 1024);
+ }
-native_path:
-
- if( !gsWorkingDirectory[0] ) {
- getcwd(gsWorkingDirectory, 1024);
- }
-
- len = strlen("/Native");
- len += strlen( gsWorkingDirectory ) + 1;
- len += strlen(Path);
- if( Buffer ) {
- strcpy(Buffer, "/Native");
- strcat(Buffer, gsWorkingDirectory);
- strcat(Buffer, "/");
- strcat(Buffer, Path);
+ len = strlen("/Native");
+ len += strlen( gsWorkingDirectory ) + 1;
+ len += strlen(Path);
+ if( Buffer ) {
+ strcpy(Buffer, "/Native");
+ strcat(Buffer, gsWorkingDirectory);
+ strcat(Buffer, "/");
+ strcat(Buffer, Path);
+ }
}
return len;
}
extern char __buildnum[];
#define BUILD_NUM ((int)(Uint)&__buildnum)
extern const char gsGitHash[];
+extern const char gsBuildInfo[];
#define BITS 32
#define NULL ((void*)0)
typedef uint32_t tTID;
// NOTE: Since this is single-threaded (for now) mutexes can be implimented as simple locks
-typedef char tMutex;
typedef char tShortSpinlock;
typedef int64_t tTime;
extern int DivUp(int value, int divisor);
extern uint64_t DivMod64U(uint64_t Num, uint64_t Den, uint64_t *Rem);
-static inline int Mutex_Acquire(tMutex *m) {
- if(*m) Log_KernelPanic("---", "Double mutex lock");
- *m = 1;
- return 0;
-}
-static inline void Mutex_Release(tMutex *m) { *m = 0; }
-
static inline void SHORTLOCK(tShortSpinlock *Lock) {
if(*Lock) Log_KernelPanic("---", "Double short lock");
*Lock = 1;
--- /dev/null
+
+#ifndef _MUTEX_H_
+#define _MUTEX_H_
+
+typedef struct {
+ void *LockerReturnAddr;
+} tMutex;
+
+static inline int Mutex_Acquire(tMutex *m) {
+ if(m->LockerReturnAddr)
+ Log_KernelPanic("---", "Double mutex lock of %p by %p (was locked by %p)",
+ m, __builtin_return_address(0), m->LockerReturnAddr);
+ m->LockerReturnAddr = __builtin_return_address(0);;
+ return 0;
+}
+static inline void Mutex_Release(tMutex *m) { m->LockerReturnAddr = 0; }
+
+#endif
+
case 'p':
fprintf(stderr, " %p", va_arg(args, const void *));
break;
+ case 'n':
+ fprintf(stderr, " NULL");
+ break;
default:
fprintf(stderr, " ?");
break;
if( strcmp("mount", argv[i]) == 0 || strcmp("-i", argv[i]) == 0 ) {
// Mount an image
if( argc - i < 3 ) {
- fprintf(stderr, "--image/-i takes 2 arguments (ident and path)\n");
+ fprintf(stderr, "mount takes 2 arguments (image and mountpoint)\n");
exit(-1);
}
- if( DiskTool_MountImage(argv[i+1], argv[i+2]) ) {
- fprintf(stderr, "Unable to mount '%s' as '%s'\n", argv[i+2], argv[i+1]);
+ if( DiskTool_MountImage(argv[i+2], argv[i+1]) ) {
+ fprintf(stderr, "Unable to mount '%s' as '%s'\n", argv[i+1], argv[i+2]);
break;
}
if( strcmp("mountlvm", argv[i]) == 0 ) {
if( argc - i < 3 ) {
- fprintf(stderr, "mountlvm takes 2 arguments (ident and path)\n");
+ fprintf(stderr, "mountlvm takes 2 arguments (iamge and ident)\n");
exit(-1);
}
- if( DiskTool_RegisterLVM(argv[i+1], argv[i+2]) ) {
- fprintf(stderr, "Unable to register '%s' as LVM '%s'\n", argv[i+2], argv[i+1]);
+ if( DiskTool_RegisterLVM(argv[i+2], argv[i+1]) ) {
+ fprintf(stderr, "Unable to register '%s' as LVM '%s'\n", argv[i+1], argv[i+2]);
break;
}
continue ;
}
+ if( proto != PROTO_HTTP ) {
+ fprintf(stderr, "TODO: Support protocols other than HTTP\n");
+ free(uri);
+ continue ;
+ }
+
rv = getaddrinfo(uri->Host, "http", NULL, &addrinfo);
if( rv != 0 ) {
fprintf(stderr, "Unable to resolve %s: %s\n", uri->Host, gai_strerror(rv));