//LOG("Allocated Directory (%x)", *gpTmpCR3);
memsetd( gaTmpDir, 0, 1024 );
- // Copy Tables
- for( i = 0; i < 768; i ++)
- {
- // Check if table is allocated
- if( !(gaPageDir[i] & PF_PRESENT) ) {
- gaTmpDir[i] = 0;
- page += 1024;
- continue;
- }
-
- // Allocate new table
- gaTmpDir[i] = MM_AllocPhys() | (gaPageDir[i] & 7);
- INVLPG( &gaTmpTable[page] );
- // Fill
- for( j = 0; j < 1024; j ++, page++ )
+ if( Threads_GetPID() != 0 )
+ {
+ // Copy Tables
+ for( i = 0; i < 768; i ++)
{
- if( !(gaPageTable[page] & PF_PRESENT) ) {
- gaTmpTable[page] = 0;
+ // Check if table is allocated
+ if( !(gaPageDir[i] & PF_PRESENT) ) {
+ gaTmpDir[i] = 0;
+ page += 1024;
continue;
}
- // Refrence old page
- MM_RefPhys( gaPageTable[page] & ~0xFFF );
- // Add to new table
- if(gaPageTable[page] & PF_WRITE) {
- gaTmpTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
- gaPageTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
- INVLPG( page << 12 );
+ // Allocate new table
+ gaTmpDir[i] = MM_AllocPhys() | (gaPageDir[i] & 7);
+ INVLPG( &gaTmpTable[page] );
+ // Fill
+ for( j = 0; j < 1024; j ++, page++ )
+ {
+ if( !(gaPageTable[page] & PF_PRESENT) ) {
+ gaTmpTable[page] = 0;
+ continue;
+ }
+
+ // Refrence old page
+ MM_RefPhys( gaPageTable[page] & ~0xFFF );
+ // Add to new table
+ if(gaPageTable[page] & PF_WRITE) {
+ gaTmpTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
+ gaPageTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
+ INVLPG( page << 12 );
+ }
+ else
+ gaTmpTable[page] = gaPageTable[page];
}
- else
- gaTmpTable[page] = gaPageTable[page];
}
}
__asm__ __volatile__ ("mov %%esp, %0": "=r"(esp));
__asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp));
+ // TODO: Thread safety
// Find a free worker stack address
for(base = giLastUsedWorker; base < NUM_WORKER_STACKS; base++)
{
// Mapping Time!
for( addr = 0; addr < WORKER_STACK_SIZE; addr += 0x1000 )
+ //for( addr = WORKER_STACK_SIZE; addr; addr -= 0x1000 )
{
pages[ addr >> 12 ] = MM_AllocPhys();
gaTmpTable[ (base + addr) >> 12 ] = pages[addr>>12] | 3;
[global GetCPUNum]
GetCPUNum: ; TODO: Store in debug registers
- xor eax, eax
- str ax
- sub ax, 0x30
- shr ax, 3 ; ax /= 8
+; xor eax, eax
+; str ax
+; sub ax, 0x30
+; shr ax, 3 ; ax /= 8
+ mov eax, dr1
ret
; Usermode code exported by the kernel
// === FLAGS ===
#define DEBUG_TRACE_SWITCH 0
+#define DEBUG_DISABLE_DOUBLEFAULT 1
// === CONSTANTS ===
#define SWITCH_MAGIC 0xFF5317C8 // FF SWITCH - There is no code in this area
MM_FinishVirtualInit();
#endif
- #if 0
+ #if !DEBUG_DISABLE_DOUBLEFAULT
// Initialise Double Fault TSS
gGDT[5].BaseLow = (Uint)&gDoubleFault_TSS & 0xFFFF;
gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16;
tDevFS_Driver gFIFO_DriverInfo = {
NULL, "fifo",
{
+ .Size = 1,
.NumACLs = 1,
.ACLs = &gVFS_ACL_EveryoneRW,
.Flags = VFS_FFLAG_DIRECTORY,
char *FIFO_ReadDir(tVFS_Node *Node, int Id)
{
tPipe *tmp = gFIFO_NamedPipes;
+
// Entry 0 is Anon Pipes
if(Id == 0) return strdup("anon");
while(remaining)
{
// Wait for buffer to fill
- if(pipe->Flags & PF_BLOCKING)
- while(pipe->ReadPos == pipe->WritePos)
+ if(pipe->Flags & PF_BLOCKING) {
+ while(pipe->ReadPos == pipe->WritePos) {
Threads_Yield();
+ //MAGIC_BREAK();
+ }
+ }
else
if(pipe->ReadPos == pipe->WritePos)
return 0;
memset(ret, 0, allocsize);
ret->Name = Name;
+ ret->Flags = PF_BLOCKING;
// Allocate Buffer
ret->BufSize = Size;
/*
* Acess2 IP Stack
* - Address Resolution Protocol
+ * - Part of the IPv4 protocol
*/
#define DEBUG 0
#include "ipstack.h"
#include "arp.h"
#include "link.h"
-#define ARPv6 1
+#define ARPv6 0
#define ARP_CACHE_SIZE 64
#define ARP_MAX_AGE (60*60*1000) // 1Hr
ENTER("pInterface xAddress", Interface, Address);
// Check routing tables
- // Replace address with gateway if needed
+ {
+ tRoute *route = IPStack_FindRoute(4, Interface, &Address);
+ if( route ) {
+ // If the next hop is defined, use it
+ // - 0.0.0.0 as the next hop means "no next hop / direct"
+ if( ((tIPv4*)route->NextHop)->L != 0 ) {
+ // Recursion: see /Recursion/
+ return ARP_Resolve4(Interface, *(tIPv4*)route->NextHop);
+ }
+ }
+ }
+ // Check ARP Cache
Mutex_Acquire( &glARP_Cache4 );
for( i = 0; i < giARP_Cache4Space; i++ )
{
tInterface *gIP_Interfaces_Last = NULL;
tSocketFile *gIP_FileTemplates;
+
+tAdapter gIP_LoopAdapter = {
+ DeviceLen: 8,
+ Device: "LOOPBACK"
+ };
tMutex glIP_Adapters;
tAdapter *gIP_Adapters = NULL;
int giIP_NextIfaceId = 1;
ENTER("sPath", Path);
+ // Check for loopback
+ if( strcmp(Path, "LOOPBACK") == 0 )
+ {
+ // Initialise if required
+ if( gIP_LoopAdapter.DeviceFD == 0 )
+ {
+ dev = &gIP_LoopAdapter;
+
+ dev->NRef = 1;
+ dev->DeviceLen = 8;
+
+ dev->DeviceFD = VFS_Open( "/Devices/fifo/anon", VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE );
+ if( dev->DeviceFD == -1 ) {
+ Log_Warning("IPStack", "Unable to open FIFO '/Devices/fifo/anon' for loopback");
+ return NULL;
+ }
+
+ dev->MacAddr.B[0] = 'A';
+ dev->MacAddr.B[1] = 'c';
+ dev->MacAddr.B[2] = 'e';
+ dev->MacAddr.B[3] = 's';
+ dev->MacAddr.B[4] = 's';
+ dev->MacAddr.B[5] = '2';
+
+ // Start watcher
+ Link_WatchDevice( dev );
+ }
+ LEAVE('p', &gIP_LoopAdapter);
+ return &gIP_LoopAdapter;
+ }
+
Mutex_Acquire( &glIP_Adapters );
// Check if this adapter is already open
extern int IPStack_GetAddressSize(int AddressType);
extern int IPStack_CompareAddress(int AddressType, void *Address1, void *Address2, int CheckBits);
+extern tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
+
#endif
// - <HexStreamAddress> is a condensed hexadecimal stream (in big endian)
// (E.g. 0A000201 for 10.0.2.1 IPv4)
// - <Bits> is the number of subnet bits (E.g. 24 for an IPv4 Class C)
+ // Example: /Devices/ne2k/0,4,0A00020A,24
+
+ // I could also define routes using <Interface>,<HexStreamNetwork>,<Bits>,<HexStreamGateway>
+ // Example: 1,00000000,0,0A000201
}
}
- gIP_LoopInterface.Adapter = IPStack_GetAdapter("/Devices/fifo/anon");
+ // Initialise loopback interface
+ gIP_LoopInterface.Adapter = IPStack_GetAdapter("LOOPBACK");
DevFS_AddDevice( &gIP_DriverInfo );
tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name);
int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data);
int IPStack_Route_Create(const char *InterfaceName);
-tRoute *IPStack_FindRoute(int AddressType, void *Address);
+tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
// - Individual Routes
int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data);
if( !CheckMem(Data, sizeof(int) + IPStack_GetAddressSize(data->Type)) )
return -1;
- rt = IPStack_FindRoute(data->Type, data->Addr);
+ rt = IPStack_FindRoute(data->Type, NULL, data->Addr);
if( !rt )
return 0;
/**
*/
-tRoute *IPStack_FindRoute(int AddressType, void *Address)
+tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
{
tRoute *rt;
tRoute *best = NULL;
+ if( Interface && AddressType != Interface->Type ) return NULL;
+
for( rt = gIP_Routes; rt; rt = rt->Next )
{
+ // Check interface
+ if( Interface && rt->Interface != Interface ) continue;
+ // Check address type
if( rt->AddressType != AddressType ) continue;
+ // Check if the address matches
if( !IPStack_CompareAddress(AddressType, rt->Network, Address, rt->SubnetBits) )
continue;
type = ioctl(fd, 4, NULL);
+ // Ignore -1 values
+ if( type == -1 ) {
+ return ;
+ }
+
printf("%s:\t", Name);
{
int call_num = ioctl(fd, 3, "get_device");
// Create route
fd = open(IPSTACK_ROOT"/routes", 0);
- num = ioctl(fd, ioctl(fd, 3, "add_route"), Interface);
+ num = ioctl(fd, ioctl(fd, 3, "add_route"), (char*)Interface);
close(fd);
// Open route