diff --git a/Makefile b/Makefile index 4116047..ee7a606 100755 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ kernel: src (cd src/sys;make) + +install: + (cd src/sys;make install) clean: - (cd src/sys;make clean) \ No newline at end of file + (cd src/sys;make clean) diff --git a/src/sys/Makefile b/src/sys/Makefile index e19d5f3..8c18831 100755 --- a/src/sys/Makefile +++ b/src/sys/Makefile @@ -1,7 +1,7 @@ # $Id$ # Kernel Makefile (C) 2002 The UbixOS Project -all: boot-code init-code kernel-code driver-code kernel +all: boot-code init-code kernel-code driver-code kernel-img boot-code: boot (cd boot;make) @@ -15,12 +15,15 @@ driver-code: drivers (cd drivers;make) -kernel: compile +kernel-img: compile (cd compile;make) +install: + (cd boot;make install) + clean: (cd boot;make clean) (cd init;make clean) (cd drivers;make clean) (cd kernel;make clean) - (cd compile;make clean) \ No newline at end of file + (cd compile;make clean) diff --git a/src/sys/boot/Makefile b/src/sys/boot/Makefile index f1a1b02..699e1ff 100755 --- a/src/sys/boot/Makefile +++ b/src/sys/boot/Makefile @@ -1,10 +1,27 @@ # $Id$ -# Boot Strap Makefile (C) 2002 The UbixOS Project -all: boot +#FDDEVICE = "/dev/fd0" +FDDEVICE = /dev/fd1 +NASM = nasm +#NASM = /usr/local/bin/nasm -boot: boot.s - as -o boot.o boot.s - +all: writeimg format + +writeimg: writeimg.c + gcc writeimg.c -o writeimg + +format: format.c + gcc format.c -o format + +install: writeimg + (./format $(FDDEVICE) 101 2 help.txt readme.txt) + ($(NASM) bootsec.asm -o bootsec) + (cat ../compile/ubix.elf >>bootsec) + (./writeimg $(FDDEVICE)) + (rm bootsec) + +formatdsk: format + (./format 60 2 bin help.txt readme.txt) + clean: - (rm -fr boot) + (rm -f writeimg format bootsec) diff --git a/src/sys/boot/boot.s b/src/sys/boot/boot.s deleted file mode 100755 index e69de29..0000000 --- a/src/sys/boot/boot.s +++ /dev/null diff --git a/src/sys/boot/bootsec.asm b/src/sys/boot/bootsec.asm new file mode 100755 index 0000000..e0e20c2 --- /dev/null +++ b/src/sys/boot/bootsec.asm @@ -0,0 +1,300 @@ +; $Id$ + +%include "gdtnasm.inc" + +[ORG 0x7c00] +jmp start +nop + +id db 'UbixFS' ;file system id +version dd 1h ; Filing System Version +fs_start dd 101 ; LBA address for start of root dir +krnl_size dd 59 ; Kernel size in sectors, starts at sector 1 +BytesPerSector dw 512 +SectorsPerTrack dw 18 +TotalHeads dw 2 +TotalSectors dd 2880 ; 1474560/512 for a 1.44meg disk +file_entry_nextdata equ 273 ; Offset in file_entry structure to the nextdata LBA pointer +data_entry_data equ 9 ; Offset in data_entry structure to the data +bootdrv db 0 + +start: +xor ax, ax +mov ds, ax +mov [bootdrv], dl +;mov al,0x13 +;int 0x10 +; First get into protected mode +cli +n5: + in al, 0x64 ;Enable A20 {4A} {5} + test al, 2 + jnz n5 + mov al, 0xD1 + out 0x64, al +n6: + in al, 0x64 + test al, 2 + jnz n6 + mov al, 0xDF + out 0x60, al + lgdt [gdtinfo] ;Load GDT + mov ecx, CR0 ;Switch to protected mode + inc cx + mov CR0, ecx + mov ax, flat_data-gdt_table ; Selector for 4Gb data seg + mov ds, ax ; {2} Extend limit for ds + mov es, ax ; Extend limit for es + mov fs, ax ; fs and... + mov gs, ax ; gs + dec cx ; switch back to real mode + mov CR0, ecx + sti + xor ax, ax + mov ds, ax + mov dl, [bootdrv] + mov bx, 0x60 + mov es, bx + mov eax, 1 + mov ecx, [krnl_size] + mov di, 1 +load_loop: + call read_sectors + inc eax + mov bx, es + add bx, 32 + mov es, bx + loop load_loop + ; Turn off the floppy motor, its annoying leaving it on ! + mov edx,0x3f2 + mov al,0x0c + out dx,al + ;lets convert the ELF file to a linear binary so we can execute it + cmp dword [0x600],464c457fh ; The ELF signature is \07fELF + jne ldr_ELF_err ; Ugh... not an ELF file !!! + cmp word [0x600+4],101h ; It should be statically linked etc. + jne ldr_ELF_err + cmp byte [0x600+6],1 + jne ldr_ELF_err + jmp short skip_err_handler + ldr_ELF_err: + mov ax, 'E'+0x0E00 + mov bx, 7 + int 10h + mov al, 'L' + int 10h + mov al, 'F' + int 10h + cli + hlt +skip_err_handler: + + mov eax, [0x600+18h] + mov [krnl_entry], eax + + xor ecx,ecx ; Get the number of sections in cx + mov cx,[0x600+2ch] + +sectionloop: + dec cx ; Next section + push cx ; Save cx on the stack while we load + ; the section into memory + + mov eax,[0x600+2ah] ; Get the program header entry size + mul cx ; Calculate the offset from the start + ; of the program header table + mov ebx,[0x600+1ch] ; Get the PHT offset in ebx + add ebx,eax ; Add it to our PHT entry offset + add ebx,0x600 ; Calculate the address of the entry + + cmp dword [bx],1 ; Does this section have to be + ; loaded into memory ? + jne nextsect ; No, next section + + mov dword ecx,[bx+4h] ; Get the offset of the segment in + ; the ELF file + + mov dword ebp,[bx+10h] ; Get the size of the segment in the + ; ELF file + + mov dword edi,[bx+8h] ; Get the memory address of the sect. + mov dword eax,[bx+14h] ; Get the size of the section in + mov ebx,eax ; the memory into ebx + +; ds:dx = Address of ASCIIZ filename +; es:edi = Where in memory to put it +; ecx = Offset in file to start reading (bytes) +; ebp = Length of segment to read (bytes) +; +; Returns: +; eax = Length of file that was loaded +; eax = 0 if an error occured + + + push ebp + pusha + mov esi, 0x600 + add esi, ecx + mov ecx, ebp + call memcopy + popa + pop eax + + sub ebx,eax ; This amount needs to be zeroed + jz nextsect ; It's ok, next section + + add edi,eax ; Zero the memory from this address + xor ax,ax ; edi is an absolute address + mov ecx,ebx + call zero_memblock ; Zero the rest of the section + +nextsect: + pop cx ; Restore our section count + or cx,cx ; Was this the last one ? + + jnz sectionloop + + +; Re-enter protected mode ! A20 is already enabled + cli ; No interrupts please at all + lgdt [gdtinfo] + mov ecx, cr0 + inc cx + mov cr0, ecx + mov ax, flat_data-gdt_table + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + jmp dword (flat_code-gdt_table):pmode1 + + pmode1: +[BITS 32] + + push dword 2 + popfd + + mov eax, [krnl_entry] + + call eax + + cli + hlt + +;Hang the system.. +hang: jmp hang + +[BITS 16] + read_sectors: +; Input: +; EAX = LBN +; DI = sector count +; ES = segment +; Output: +; BL = low byte of ES +; EBX high half cleared +; DL = 0x80 +; EDX high half cleared +; ESI = 0 + + pusha + + cdq ;edx = 0 + movzx ebx, byte [SectorsPerTrack] + div ebx ;EAX=track ;EDX=sector-1 + mov cx, dx ;CL=sector-1 ;CH=0 + inc cx ;CL=Sector number + xor dx, dx + mov bl, [TotalHeads] + div ebx + + mov dh, dl ;Head + mov dl, [bootdrv] ;Drive 0 + xchg ch, al ;CH=Low 8 bits of cylinder number; AL=0 + shr ax, 2 ;AL[6:7]=High two bits of cylinder; AH=0 + or cl, al ;CX = Cylinder and sector + mov ax, di ;AX = Maximum sectors to xfer +retry: mov ah, 2 ;Read + xor bx, bx + int 13h + jc retry + + popa + + ret + +; zero_memblock: Fills the specified memory block with zeros (0x0) +; +; Takes parameters: +; ax = segment/selector of memory to be cleared +; edi = offset of memory to be cleared +; ecx = number of bytes to clear +; +; Returns: +; nothing + +zero_memblock: + push eax ; Save the registers + push edi + push ecx + push es + mov es,ax + xor eax,eax ; Fill the memory with zeros (0x0) + cld ; Clear the direction flag; rep increments di + a32 rep stosb ; Fill the memory (one byte at a time) + pop es ; Restore the registers + pop ecx + pop edi + pop eax + ret ; Return to the main program + +; Parameters +; DS:ESI = Source +; DS:EDI = Destination +; CX = length +memcopy: + pusha +memcopy_loop: + mov al, [esi] + mov [edi], al + inc edi + inc esi + loop memcopy_loop + popa + ret + +print: + lodsb ; load next character + or al, al ; test for NUL character + jz .DONE + mov ah, 0x0E ; BIOS teletype + mov bh, 0x00 ; display page 0 + mov bl, 0x07 ; text attribute + int 0x10 ; invoke BIOS + jmp print + .DONE: + ret + +gdtinfo: + +dw gdtlength +dd gdt_table + +;********* GDT TABLE +gdt_table: + +null_desc desc 0,0,0 + +flat_code desc 0, 0xFFFFF, D_CODE + D_READ + D_BIG + D_BIG_LIM + +flat_data desc 0, 0xFFFFF, D_DATA + D_WRITE + D_BIG + D_BIG_LIM + +gdtlength equ $ - gdt_table - 1 +;********* END GDT TABLE +krnl_entry dd 0 + +bootMsg db 'Loading UbixOS' , 0x0D, 0x0A, 0x00 + +times 510-($-$$) db 0 +dw 0xAA55 diff --git a/src/sys/boot/format.c b/src/sys/boot/format.c new file mode 100755 index 0000000..833856a --- /dev/null +++ b/src/sys/boot/format.c @@ -0,0 +1,204 @@ +/************************************************************************************** +$Id$ + + +**************************************************************************************/ + +#include +#include + +unsigned long getfilesize(char *filename); +unsigned long ceil(double __x); + +typedef struct { + unsigned char jmp[4]; /* jump to code (4bytes) */ + unsigned char id[6]; /* Should be 'UbixFS' */ + unsigned long version; /* Should be 1 */ + unsigned long fs_start; /* LBA pointer to the start of the FS */ + unsigned long krnl_size; /* LBA pointer to Kernel file entry */ + unsigned int BytesPerSector; + unsigned int SectorsPerTrack; + unsigned int TotalHeads; + unsigned long TotalSectors; + unsigned char code[479]; + } __attribute__ ((packed)) t_bootsect; + +typedef struct { + unsigned char type; /* 0 = unused. 1 = file entry. 2 = data_entry */ + unsigned long prev_entry; /* LBA pointer to previous file entry */ + unsigned long next_entry; /* LBA pointer to next file entry */ + unsigned char filename[255]; /* File name, padded with NULLs */ + /* Attributes + * Bit 0: Read + * Bit 1: Write + * Bit 2: Execute + * Bit 3: Hidden + * Bit 4: Directory + * Rest are unused, and available for future expansion + */ + unsigned char attributes; + unsigned long size; /* size in bytes */ + unsigned long parent_dir; /* LBA pointer to parent dir entry */ + unsigned long first_dataentry; /* LBA pointer to next data struct */ + unsigned char padding[3819]; + } __attribute__ ((packed)) t_file_entry; + +typedef struct { + unsigned char type; /* 0 = unused. 1 = file entry. 2 = data_entry */ + unsigned long prev_entry; /* LBA pointer to previous data/file entry */ + unsigned long next_entry; /* LBA pointer to next data/file entry */ + unsigned char data[4087]; + } __attribute__ ((packed)) t_data_entry; + +// argv[1] = start of FS +// argv[2] = file to put onto FS + +int main(int argc, char **argv) { + t_bootsect bootsect; + t_file_entry file_entry; + t_data_entry data_entry; + unsigned char *data; + unsigned long _fs_start; + unsigned long filesize=0; + unsigned long cur_lbasector = 0; + char filename[255]; + unsigned long no_of_files, file_loop=0; + unsigned int loop=0; + FILE *dev, *file; + if (argc < 4) { + printf("Usage: format \n"); + exit(1); + } + sscanf(argv[2], "%d", &_fs_start); + sscanf(argv[3], "%d", &no_of_files); + + printf("Size of t_bootsect = %d\n", sizeof(bootsect)); + printf("Size of t_file_entry = %d\n", sizeof(t_file_entry)); + printf("Size of t_data_entry = %d\n", sizeof(t_data_entry)); + printf("Size of data_entry.data = %d\n", sizeof(data_entry.data)); + + for (loop=0; loop<4; loop++) { + bootsect.jmp[loop] = 0; + } + + bootsect.id[0] = 'U'; + bootsect.id[1] = 'b'; + bootsect.id[2] = 'i'; + bootsect.id[3] = 'x'; + bootsect.id[4] = 'F'; + bootsect.id[5] = 'S'; + bootsect.version = 1; + bootsect.fs_start = _fs_start; + bootsect.BytesPerSector = 512; + bootsect.SectorsPerTrack = 18; + bootsect.TotalHeads = 2; + bootsect.TotalSectors = 2880*512; + bootsect.krnl_size = _fs_start; + + for (loop=0; loop>2) & 0x400 ;Gate + dw %1 + dw %2 + dw (%3)+D_PRESENT + dw (%1) >> 16 +%else ;Not a gate + dw %2 + dw %1 + db (%1) >> 16 + db ((%3)+D_PRESENT) >> 8 + db (%3) + ((%2) >> 16) + db (%1) >> 24 +%endif +%endmacro + +;----------------------------------------------------------------------------- +; +; A gate is identified as any descriptor whose flags has bit 10 set and +; bit 12 clear. +; +; For a gate, the following rearrangement occurs: +; +; subField Final location +; ------------------ -------------- +; Selector[0..15] 16..31 +; Minor control bits 32..39 +; Major control bits 40..47 +; Offset[0..15] 0..15 +; Offset[16..31] 48..63 +; +; For non-gates the following rearrangement occurs: +; +; subField Final location +; ------------------ -------------- +; Limit[0..15] 0..15 +; Limit[16..19] 48..51 +; Minor control bits 52..57 +; Major control bits 40..47 +; Base[0..23] 16..39 +; Base[24..31] 56..63 +; +; The last parameter to the desc macro contains all the control bits +; combined. It is generated by adding together the appropriate +; D_ constants. For all descriptors, it has the major control bits in D_ +; bits 8 to 15. The minor control bits are in either D_ bits 0 to 7 or bits +; 4 to 7 depending on the type of descriptor. +;_____________________________________________________________________________ + diff --git a/src/sys/boot/help.txt b/src/sys/boot/help.txt new file mode 100755 index 0000000..e9c8127 --- /dev/null +++ b/src/sys/boot/help.txt @@ -0,0 +1,14 @@ +$Id$ + +Ubix^3 Help File +---------------- + + +There Are Only Six Commands Currently Supported By This Shell + +ls - Gives you a directory listing +cat - Displays the contents of +version - Displays the version of this os +credits - A list of current developers of this os +reboot - Reboots the machines +exec - Execute File diff --git a/src/sys/boot/readme.txt b/src/sys/boot/readme.txt new file mode 100755 index 0000000..176fb80 --- /dev/null +++ b/src/sys/boot/readme.txt @@ -0,0 +1,7 @@ +$Id$ + +Ubix^3 Readme +------------- + + +Ok find bugs email them to chris@ubixos.com diff --git a/src/sys/boot/writeimg.c b/src/sys/boot/writeimg.c new file mode 100755 index 0000000..336547b --- /dev/null +++ b/src/sys/boot/writeimg.c @@ -0,0 +1,22 @@ +/************************************************************************************** +$Id$ + + +**************************************************************************************/ + +#include + +int main(int argc, char **argv) { + FILE *in,*out; + int tmp; + + in = fopen("bootsec","rb"); + out = fopen(argv[1],"r+b"); + while(!feof(in)) { + tmp = fgetc(in); + fputc(tmp,out); + } + close(in); + close(out); + return(0); + } diff --git a/src/sys/drivers/video.c b/src/sys/drivers/video.c index d183a28..0467170 100755 --- a/src/sys/drivers/video.c +++ b/src/sys/drivers/video.c @@ -7,5 +7,36 @@ #include -unsigned char *VIDEO_MEMORY = (char *)0xB8000; -int printColor = 0x07; \ No newline at end of file +unsigned char *videoBuffer = (char *)0xB8000; +int printColor = 0x07; + +void kprint(char *string) { + unsigned int bufferOffset = 0,character = 0,i = 0; + /* We Need To Get The Y Position */ + outportByte(0x3d4, 0x0e); + bufferOffset = inportByte(0x3d5); + bufferOffset <<= 8; /* Shift Address Left 8 Bits */ + /* Then We Need To Add The X Position */ + outportByte(0x3d4, 0x0f); + bufferOffset += inportByte(0x3d5); + bufferOffset <<= 1; /* Shift Address Left 1 Bits */ + while ((character=*string++)) { + switch(character) { + default: + videoBuffer[bufferOffset++] = character; + videoBuffer[bufferOffset++] = printColor; + break; + } + /* Check To See If We Are Out Of Bounds */ + if (bufferOffset >= 160*25) { + for (i = 0; i < 160*24; i++) { + videoBuffer[i] = videoBuffer[i+160]; + } + for (i = 0; i < 80; i++) { + videoBuffer[(160*24)+(i*2)] = 0x20; + videoBuffer[(160*24)+(i*2)+1] = 0x07; + } + bufferOffset -= 160; + } + } + } \ No newline at end of file diff --git a/src/sys/include/drivers/video.h b/src/sys/include/drivers/video.h new file mode 100755 index 0000000..77a071a --- /dev/null +++ b/src/sys/include/drivers/video.h @@ -0,0 +1,10 @@ +/************************************************************************************** + Copyright (c) 2002 + The UbixOS Project + + $Id$ +**************************************************************************************/ + +extern int printColor; + +void kprint(char *string); \ No newline at end of file diff --git a/src/sys/kernel/version.c b/src/sys/kernel/version.c index 9031d74..8686881 100755 --- a/src/sys/kernel/version.c +++ b/src/sys/kernel/version.c @@ -6,6 +6,8 @@ **************************************************************************************/ #include +#include -void outputeVersion() { - } \ No newline at end of file +void outputVersion() { + kprint("Woot"); + } diff --git a/ubixos.kdevprj b/ubixos.kdevprj index 9438921..fc3e5a1 100755 --- a/ubixos.kdevprj +++ b/ubixos.kdevprj @@ -32,7 +32,7 @@ kdevprj_version=1.3 lfv_open_groups=Others make_options=\s-j1 clean all -makefiles=./Makefile.am,src/Makefile.am,src/sys/Makefile.am,src/sys/include/Makefile.am,src/lib/Makefile.am,src/lib/libc/Makefile.am,src/lib/libc/include/Makefile.am,src/bin/Makefile.am,src/bin/shell/Makefile.am,Makefile.am,src/sys/boot/Makefile.am,src/sys/init/Makefile.am,src/sys/include/ubixos/Makefile.am,src/sys/drivers/Makefile.am,src/sys/kernel/Makefile.am,src/sys/compile/Makefile.am,src/sys/include/version/Makefile.am +makefiles=./Makefile.am,src/Makefile.am,src/sys/Makefile.am,src/sys/include/Makefile.am,src/lib/Makefile.am,src/lib/libc/Makefile.am,src/lib/libc/include/Makefile.am,src/bin/Makefile.am,src/bin/shell/Makefile.am,Makefile.am,src/sys/boot/Makefile.am,src/sys/init/Makefile.am,src/sys/include/ubixos/Makefile.am,src/sys/drivers/Makefile.am,src/sys/kernel/Makefile.am,src/sys/compile/Makefile.am,src/sys/include/version/Makefile.am,src/sys/include/drivers/Makefile.am modifyMakefiles=true project_name=UbixOS project_type=normal_empty @@ -111,15 +111,15 @@ type=DATA [src/sys/boot/Makefile.am] -files=src/sys/boot/Makefile,src/sys/boot/boot.s +files=src/sys/boot/Makefile,src/sys/boot/bootsec.asm sub_dirs= type=normal -[src/sys/boot/boot.s] +[src/sys/boot/bootsec.asm] dist=true install=false install_location= -type=SOURCE +type=DATA [src/sys/compile/Makefile] dist=true @@ -150,9 +150,20 @@ type=SOURCE [src/sys/include/Makefile.am] -sub_dirs=ubixos,version +sub_dirs=ubixos,version,drivers type=normal +[src/sys/include/drivers/Makefile.am] +files=src/sys/include/drivers/video.h +sub_dirs= +type=normal + +[src/sys/include/drivers/video.h] +dist=true +install=false +install_location= +type=HEADER + [src/sys/include/ubixos/Makefile.am] files=src/sys/include/ubixos/gdt.h,src/sys/include/ubixos/scheduler.h,src/sys/include/ubixos/io.h sub_dirs=