From 30e30d7bc325852a8677819d11a47373b08d6271 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 15 Jul 2010 21:26:51 +0800 Subject: [PATCH] ATA Fixes, Module compilation fixups - Working on getting the InitRD working again - Also, I shouldn't blame stable code for bugs (elf loader was blamed for issued arising from the module compilation) - Also been slightly fiddling with the IPStack code --- Kernel/bin/elf.c | 27 +-- Kernel/debug.c | 9 +- Kernel/lib.c | 3 + Modules/Filesystems/InitRD/files.lst | 3 +- Modules/IPStack/tcp.c | 13 +- Modules/Makefile.tpl | 22 ++- Modules/Storage/ATA/main.c | 27 ++- Usermode/Applications/ifconfig_src/main.c | 228 +++++++++++++++++++++- 8 files changed, 290 insertions(+), 42 deletions(-) diff --git a/Kernel/bin/elf.c b/Kernel/bin/elf.c index 3209c044..731d1514 100644 --- a/Kernel/bin/elf.c +++ b/Kernel/bin/elf.c @@ -285,7 +285,7 @@ int Elf_Relocate(void *Base) // Parse Program Header to get Dynamic Table phtab = Base + hdr->phoff; iSegmentCount = hdr->phentcount; - for(i=0;i phtab[i].VAddr) @@ -294,7 +294,7 @@ int Elf_Relocate(void *Base) // Find Dynamic Section if(phtab[i].Type == PT_DYNAMIC) { if(dynamicTab) { - Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n"); + Log_Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n"); continue; } dynamicTab = (void *) (tVAddr) phtab[i].VAddr; @@ -305,7 +305,7 @@ int Elf_Relocate(void *Base) // Check if a PT_DYNAMIC segement was found if(!dynamicTab) { - Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n"); + Log_Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n"); LEAVE('x', hdr->entrypoint); return hdr->entrypoint; } @@ -347,7 +347,7 @@ int Elf_Relocate(void *Base) // Alter Symbols to true base - for(i=0;iChecksum)); Log_Log("TCP", "UrgentPointer = 0x%x", htons(hdr->UrgentPointer)); */ + Log_Log("TCP", "Flags = %s%s%s%s%s%s", + (hdr->Flags & TCP_FLAG_CWR) ? "CWR " : "", + (hdr->Flags & TCP_FLAG_ECE) ? "ECE " : "", + (hdr->Flags & TCP_FLAG_URG) ? "URG " : "", + (hdr->Flags & TCP_FLAG_ACK) ? "ACK " : "", + (hdr->Flags & TCP_FLAG_PSH) ? "PSH " : "", + (hdr->Flags & TCP_FLAG_RST) ? "RST " : "", + (hdr->Flags & TCP_FLAG_SYN) ? "SYN " : "", + (hdr->Flags & TCP_FLAG_FIN) ? "FIN " : "" + ); if( Length > (hdr->DataOffset >> 4)*4 ) { @@ -823,7 +833,7 @@ Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf */ void TCP_StartConnection(tTCPConnection *Conn) { - tTCPHeader hdr; + tTCPHeader hdr = {0}; Conn->State = TCP_ST_SYN_SENT; @@ -835,7 +845,6 @@ void TCP_StartConnection(tTCPConnection *Conn) hdr.Flags = TCP_FLAG_SYN; hdr.WindowSize = htons(TCP_WINDOW_SIZE); // Max hdr.Checksum = 0; // TODO - hdr.UrgentPointer = 0; TCP_SendPacket( Conn, sizeof(tTCPHeader), &hdr ); diff --git a/Modules/Makefile.tpl b/Modules/Makefile.tpl index 60824e84..0c66fddc 100644 --- a/Modules/Makefile.tpl +++ b/Modules/Makefile.tpl @@ -14,13 +14,15 @@ CFGFILES += $(shell test -f Makefile.cfg && echo Makefile.cfg) CPPFLAGS := -I$(ACESSDIR)/Kernel/include -I$(ACESSDIR)/Kernel/arch/$(ARCHDIR)/include -DARCH=$(ARCH) $(_CPPFLAGS) CFLAGS := -Wall -Werror -fno-stack-protector $(CPPFLAGS) -O3 -fno-builtin -ifeq ($(BUILDTYPE),dynamic) +ifneq ($(CATEGORY),) + FULLNAME := $(CATEGORY)_$(NAME) +else + FULLNAME := $(NAME) +endif + +ifneq ($(BUILDTYPE),static) _SUFFIX := dyn_$(ARCH) - ifneq ($(CATEGORY),) - BIN := ../$(CATEGORY)_$(NAME).kmd.$(ARCH) - else - BIN := ../$(NAME).kmd.$(ARCH) - endif + BIN := ../$(FULLNAME).kmd.$(ARCH) CFLAGS += $(DYNMOD_CFLAGS) -fPIC else _SUFFIX := st_$(ARCH) @@ -41,16 +43,16 @@ clean: $(RM) $(BIN) $(BIN).dsm $(KOBJ) $(OBJ) $(DEPFILES) install: $(BIN) -ifeq ($(BUILDTYPE),dynamic) +ifneq ($(BUILDTYPE),static) $(xCP) $(BIN) $(DISTROOT)/Modules/$(NAME).kmd.$(ARCH) else endif -ifeq ($(BUILDTYPE),dynamic) +ifneq ($(BUILDTYPE),static) $(BIN): %.kmd.$(ARCH): $(OBJ) @echo --- $(LD) -o $@ -# $(LD) -T $(ACESSDIR)/Modules/link.ld --allow-shlib-undefined -shared -nostdlib -o $@ $(OBJ) - @$(LD) --allow-shlib-undefined -shared -nostdlib -o $@ $(OBJ) +# @$(LD) -T $(ACESSDIR)/Modules/link.ld --allow-shlib-undefined -shared -nostdlib -o $@ $(OBJ) + @$(LD) --allow-shlib-undefined -shared -nostdlib -o $@ $(OBJ) -defsym=DriverInfo=_DriverInfo_$(FULLNAME) @$(DISASM) $(BIN) > $(BIN).dsm else $(BIN): %.xo.$(ARCH): $(OBJ) diff --git a/Modules/Storage/ATA/main.c b/Modules/Storage/ATA/main.c index 4aee411c..5e9eaac0 100644 --- a/Modules/Storage/ATA/main.c +++ b/Modules/Storage/ATA/main.c @@ -12,6 +12,8 @@ #include #include "common.h" +#define IO_DELAY() do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0) + // === STRUCTURES === typedef struct { @@ -251,21 +253,34 @@ int ATA_ScanDisk(int Disk) LOG("base = 0x%x", base); - if( 0xFF == inb(base+7) ) { - LOG("Floating bus"); - LEAVE('i', 0); - return 0; - } - // Send Disk Selector if(Disk == 1 || Disk == 3) outb(base+6, 0xB0); else outb(base+6, 0xA0); + IO_DELAY(); + + // Check for a floating bus + if( 0xFF == inb(base+7) ) { + LOG("Floating bus"); + LEAVE('i', 0); + return 0; + } + + // Check for the controller + outb(base+0x02, 0x66); + outb(base+0x03, 0xFF); + if(inb(base+0x02) != 0x66 || inb(base+0x03) != 0xFF) { + LOG("No controller"); + LEAVE('i', 0); + return 0; + } // Send IDENTIFY outb(base+7, 0xEC); + IO_DELAY(); val = inb(base+7); // Read status + LOG("val = 0x%02x", val); if(val == 0) { LEAVE('i', 0); return 0; // Disk does not exist diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c index ca9b73be..5f50dac3 100644 --- a/Usermode/Applications/ifconfig_src/main.c +++ b/Usermode/Applications/ifconfig_src/main.c @@ -3,6 +3,7 @@ */ #include #include +#include #include #include @@ -10,12 +11,17 @@ #define FILENAME_MAX 255 #define IPSTACK_ROOT "/Devices/ip" +// TODO: Move this to a header +#define ntohs(v) (((v&0xFF)<<8)|((v>>8)&0xFF)) + // === PROTOTYPES === void PrintUsage(const char *ProgName); void DumpInterfaces(void); void DumpInterface(const char *Name); int AddInterface(const char *Device); int DoAutoConfig(const char *Device); + int SetAddress(int IFNum, const char *Address); + int ParseIPAddres(const char *Address, uint8_t *Dest, int *SubnetBits); // === CODE === /** @@ -23,6 +29,7 @@ void DumpInterface(const char *Name); */ int main(int argc, char *argv[]) { + int ret; // No args, dump interfaces if(argc == 1) { DumpInterfaces(); @@ -32,12 +39,25 @@ int main(int argc, char *argv[]) // Add a new interface if( strcmp(argv[1], "add") == 0 ) { if( argc < 4 ) { - fprintf(stderr, "ERROR: %s add require two arguments, %i passed\n", argv[0], argc-2); + fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n", argv[0], argc-2); PrintUsage(argv[0]); - return 0; + return -1; } // TODO: Also set the IP address as the usage says it does - return AddInterface( argv[2] ); + ret = AddInterface( argv[2] ); + if(ret < 0) return ret; + ret = SetAddress( ret, argv[3] ); + return ret; + } + + // Delete an interface + if( strcmp(argv[1], "del") == 0 ) { + if( argc < 3 ) { + fprintf(stderr, "ERROR: '%s del' requires an argument\n", argv[0]); + PrintUsage(argv[0]); + return -1; + } + // TODO: } // Autoconfigure an interface @@ -149,8 +169,8 @@ void DumpInterface(const char *Name) ioctl(fd, 5, ip); // Get IP Address subnet = ioctl(fd, 7, NULL); // Get Subnet Bits printf("\t%x:%x:%x:%x:%x:%x:%x:%x/%i\n", - ip[0], ip[1], ip[2], ip[3], - ip[4], ip[5], ip[6], ip[7], + ntohs(ip[0]), ntohs(ip[1]), ntohs(ip[2]), ntohs(ip[3]), + ntohs(ip[4]), ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]), subnet); } break; @@ -173,7 +193,6 @@ int AddInterface(const char *Device) dp = open(IPSTACK_ROOT, OPENFLAG_READ); ret = ioctl(dp, 4, (void*)Device); - printf("AddInterface: ret = 0x%x = %i\n", ret, ret); close(dp); if( ret < 0 ) { @@ -232,3 +251,200 @@ int DoAutoConfig(const char *Device) return 0; } + +/** + * \brief Set the address on an interface from a textual IP address + */ +int SetAddress(int IFNum, const char *Address) +{ + uint8_t addr[16]; + int type; + char path[sizeof(IPSTACK_ROOT)+1+5+1]; // ip000 + int tmp, fd, subnet; + + // Parse IP Address + type = ParseIPAddres(Address, addr, &subnet); + if(type == 0) { + fprintf(stderr, "'%s' cannot be parsed as an IP address\n", Address); + return -1; + } + + // Open file + sprintf(path, IPSTACK_ROOT"/%i", IFNum); + fd = open(path, OPENFLAG_READ); + if( fd == -1 ) { + fprintf(stderr, "Unable to open '%s'\n", path); + return -1; + } + + tmp = type; + tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp); + if( tmp != type ) { + fprintf(stderr, "Error in setting address type (got %i, expected %i)\n", tmp, type); + close(fd); + return -1; + } + // Set Address + ioctl(fd, ioctl(fd, 3, "set_address"), addr); + + // Set Subnet + ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet); + + close(fd); + + // Dump! + //DumpInterface( path+sizeof(IPSTACK_ROOT)+1 ); + + return 0; +} + +/** + * \brief Parse an IP Address + * \return 0 for unknown, 4 for IPv4 and 6 for IPv6 + */ +int ParseIPAddres(const char *Address, uint8_t *Dest, int *SubnetBits) +{ + const char *p = Address; + + // Check first block + while(*p && *p >= '0' && *p <= '9') p ++; + + // IPv4? + if(*p == '.') + { + int i = 0, j; + int val; + + for( j = 0; Address[i] && j < 4; j ++ ) + { + val = 0; + for( ; '0' <= Address[i] && Address[i] <= '9'; i++ ) + { + val = val*10 + Address[i] - '0'; + } + if(val > 255) { + //printf("val > 255 (%i)\n", val); + return 0; + } + Dest[j] = val; + + if(Address[i] == '.') + i ++; + } + if( j != 4 ) { + //printf("4 parts expected, %i found\n", j); + return 0; + } + // Parse subnet size + if(Address[i] == '/') { + val = 0; + i ++; + while('0' <= Address[i] && Address[i] <= '9') { + val *= 10; + val += Address[i] - '0'; + i ++; + } + if(val > 32) { + printf("Notice: Subnet size >32 (%i)\n", val); + } + *SubnetBits = val; + } + if(Address[i] != '\0') { + //printf("EOS != '\\0', '%c'\n", Address[i]); + return 0; + } + return 4; + } + + // IPv6 + if(*p == ':' || ('a' <= *p && *p <= 'f') || ('A' <= *p && *p <= 'F')) + { + int i = 0; + int j, k; + int val, split = -1, end; + uint16_t hi[8], low[8]; + + for( j = 0; Address[i] && j < 8; j ++ ) + { + if(Address[i] == '/') + break; + + if(Address[i] == ':') { + if(split != -1) { + printf("Two '::'s\n"); + return 0; + } + split = j; + i ++; + continue; + } + + val = 0; + for( k = 0; Address[i] && Address[i] != ':' && Address[i] != '/'; i++, k++ ) + { + val *= 16; + if('0' <= Address[i] && Address[i] <= '9') + val += Address[i] - '0'; + else if('A' <= Address[i] && Address[i] <= 'F') + val += Address[i] - 'A' + 10; + else if('a' <= Address[i] && Address[i] <= 'f') + val += Address[i] - 'a' + 10; + else { + printf("%c unexpected\n", Address[i]); + return 0; + } + } + + if(val > 0xFFFF) { + printf("val (0x%x) > 0xFFFF\n", val); + return 0; + } + + if(split == -1) + hi[j] = val; + else + low[j-split] = val; + + if( Address[i] == ':' ) { + i ++; + } + } + end = j; + + // Parse subnet size + if(Address[i] == '/') { + val = 0; + while('0' <= Address[i] && Address[i] <= '9') { + val *= 10; + val += Address[i] - '0'; + i ++; + } + if(val > 128) { + printf("Notice: Subnet size >128 (%i)\n", val); + } + *SubnetBits = val; + } + + for( j = 0; j < split; j ++ ) + { + //printf("%04x:", hi[j]); + Dest[j*2] = hi[j]>>8; + Dest[j*2+1] = hi[j]&0xFF; + } + for( ; j < 8 - (end - split); j++ ) + { + //printf("0000:", hi[j]); + Dest[j*2] = 0; + Dest[j*2+1] = 0; + } + for( k = 0; j < 8; j ++, k++) + { + //printf("%04x:", low[k]); + Dest[j*2] = low[k]>>8; + Dest[j*2+1] = low[k]&0xFF; + } + return 6; + } + // Unknown type + return 0; +} -- 2.20.1