00001
00002
00003
00004
00005
00006
00007
00008 #include <const.h>
00009 #include <errno.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014 #include <arch/i386.h>
00015 #include <arch/mem.h>
00016 #include <arch/paging.h>
00017 #include <arch/v86.h>
00018
00019 #include <kernel/clock.h>
00020 #include <kernel/console.h>
00021 #include <kernel/elf32.h>
00022 #include <kernel/ext2.h>
00023 #include <kernel/fat.h>
00024 #include <kernel/floppy.h>
00025 #include <kernel/Ide.h>
00026 #include <kernel/IdeDebug.h>
00027 #include <kernel/IdeTimer.h>
00028 #include <kernel/IdeLow.h>
00029 #include <kernel/kernel.h>
00030 #include <kernel/keyboard.h>
00031 #include <kernel/kmalloc.h>
00032 #include <kernel/pci.h>
00033 #include <kernel/speaker.h>
00034 #include <kernel/task.h>
00035 #include <kernel/serial.h>
00036 #include <kernel/time.h>
00037
00038 #include <net/arp.h>
00039 #include <net/eth.h>
00040 #include <net/icmp.h>
00041
00042 #include <kernel/shell.h>
00043
00044
00045
00046
00047
00048
00049
00050 #define SH_HELP 0
00051 #define SH_UNAME 1
00052 #define SH_CLEAR 2
00053 #define SH_REBOOT 3
00054 #define SH_DUMP 4
00055 #define SH_READ 5
00056 #define SH_WRITE 6
00057 #define SH_PAGES 7
00058 #define SH_MEM 8
00059 #define SH_CHECKMEM 9
00060 #define SH_FRAMES 10
00061 #define SH_BG 11
00062 #define SH_V86EXEC 12
00063 #define SH_V86BG 13
00064 #define SH_TEST 14
00065 #define SH_CPUID 15
00066 #define SH_MOUNT 16
00067 #define SH_LS 17
00068 #define SH_CAT 18
00069 #define SH_CD 19
00070 #define SH_PS 20
00071 #define SH_KILL 21
00072 #define SH_RS232 22
00073 #define SH_EXEC 23
00074 #define SH_PCISCAN 24
00075 #define SH_ETH_ARP 25
00076 #define SH_RTL8139_INIT 26
00077 #define SH_ETH_PING 27
00078 #define SH_HALT 28
00079 #define SH_RM 29
00080 #define SH_ELF 30
00081
00082 #define SH_IDETEST 31
00083 #define SH_IDEREAD 32
00084 #define SH_IDEWRITE 33
00085 #define SH_IDEDEVICEINFO 34
00086
00087
00088 #define SH_LS_EXT2 35
00089 #define SH_CAT_EXT2 36
00090 #define SH_CD_EXT2 37
00091
00092 #define SH_TIME 38
00093
00094
00095 static CMD_t commands[] = {
00096 { SH_ETH_ARP, "arp", "arp destination", "Send an ARP echo request to ip destination"},
00097 { SH_BG, "bg", "bg filename", "Execute a program in background"},
00098 { SH_V86BG, "bg-v86", "bg-v86 filename", "Execute a virtual 8086 mode program in background"},
00099 { SH_CAT, "cat", "cat filename", "Concatenate FILE to standard output"},
00100
00101 { SH_CAT_EXT2, "cat2", "cat2 filename", "Concatenate ext2 FILE to standard output"},
00102
00103 { SH_CD, "cd", "cd [dir]", "Change the current directory"},
00104
00105 { SH_CD_EXT2, "cd2", "cd2 [dir]", "Change the current ext2 directory"},
00106
00107 { SH_RS232, "chat", "chat <2400|4800|9600|19200|38400|56700|115200>", "Connect to /dev/modem on COM1"},
00108 { SH_CHECKMEM, "checkmem", "checkmem", "Create a background task to check frames stack integrity"},
00109 { SH_CLEAR, "clear", "clear", "Clear the screen"},
00110 { SH_CPUID, "cpuid", "cpuid", "Show informations about the CPU - Only for IA-32 INTEL(R)"},
00111 { SH_DUMP, "dump", "dump", "Register dump"},
00112 { SH_ELF, "elf", "elf filename", "Check if filename is a valid ELF32 file"},
00113 { SH_FRAMES, "frames", "frames", "Dump free frames"},
00114 { SH_EXEC, "fg", "fg filename", "Execute a program in foreground (you can use ./ instead of fg)"},
00115 { SH_V86EXEC, "fg-v86", "fg-v86 filename", "Execute a virtual 8086 mode program in foreground"},
00116 { SH_HALT, "halt", "halt", "Power down the system (if possible, otherwise halt)"},
00117 { SH_HELP, "help", "help [cmd]", "Show the command help"},
00118
00119 { SH_IDEDEVICEINFO, "idedeviceinfo","idedeviceinfo","Display complete info of a specified device"},
00120 { SH_IDEREAD, "ideread", "ideread", "Read a block from a device on a specified ide channel"},
00121 { SH_IDETEST, "idetest", "idetest", "test ide routine for debuging purpose"},
00122 { SH_IDEWRITE, "idewrite", "idewrite", "Write a block to a device on specified ide channel"},
00123
00124 { SH_RTL8139_INIT, "ifconfig", "ifconfig <up|down> [promisc]", "Initialize RTL8139 ethernet card"},
00125 { SH_KILL, "kill", "kill [pid]", "Kill a task"},
00126 { SH_LS, "ls", "ls", "List informations about FILEs"},
00127
00128 { SH_LS_EXT2, "ls2", "ls2", "List information about ext2 FILEs"},
00129
00130 { SH_MEM, "mem", "mem", "Dump kernel memory map"},
00131 { SH_MOUNT, "mount", "mount", "Mount the FAT12 filesystem on the floppy"},
00132 { SH_ETH_PING, "ping", "ping destination", "PING to the ip destination"},
00133 { SH_PAGES, "pages", "pages", "Dump dirty pages"},
00134 { SH_PCISCAN, "pciscan", "pciscan", "Scan for PCI devices"},
00135 { SH_PS, "ps", "ps", "Print the state of every processes"},
00136 { SH_READ, "read", "read [block]", "Read a block from the floppy to the buffer"},
00137 { SH_REBOOT, "reboot", "reboot", "Reboot the system"},
00138 { SH_RM, "rm", "rm filename", "Remove a file"},
00139 { SH_TEST, "test", "test [num]", "Create <num> auto-killing tasks"},
00140 { SH_TIME, "time", "time", "Print the UNIX timestamp (seconds since 1970-01-01 00:00:00)"},
00141 { SH_UNAME, "uname", "uname", "Print kernel informations"},
00142 { SH_WRITE, "write", "write [block]", "Write a block from the buffer to the floppy"},
00143
00144 };
00145
00146
00147
00148
00149 void Sh_IdeTest()
00150 {
00151 kprintf("\n\rThis command is only for debug purpose.\n\r");
00152 }
00153
00154 void Sh_IdeRead()
00155 {
00156 int Dev;
00157 int Lba;
00158 int Err=FALSE;
00159 byte DataBuffer[512];
00160
00161 kprintf("\n\rInsert the channel number (0 or 1): 0\b");
00162 scanf("%i", &Dev);
00163 kprintf("\n\rChannel %i Selected",Dev);
00164 if ( Dev==0 )
00165 SelectAtaChannel(CC_PRIMARY);
00166 else if ( Dev==1 )
00167 SelectAtaChannel(CC_SECONDARY);
00168 else
00169 {
00170 kprintf("\n\rBad Channel Number: Channel 0 will be selected");
00171 SelectAtaChannel(CC_PRIMARY);
00172 }
00173
00174 kprintf("\n\rInsert the device number to Read (0 or 1): 0\b");
00175 scanf("%i", &Dev);
00176 kprintf("\n\rDevice %i Selected",Dev);
00177 if ( Dev==0 || Dev==1 )
00178 {
00179
00180 kprintf("\n\rInsert Lba : ");
00181 scanf("%i", &Lba);
00182 kprintf("\n\rLba Selected %i",Lba);
00183
00184 Err=ReadSectorsLba(Dev,(int64) Lba,1,(word *) &DataBuffer,TRUE);
00185 if (Err)
00186 ShowIdeErrorMessage(Err,TRUE);
00187 else
00188 {
00189 kprintf("\n\r HEX DATA");
00190 ShowMatrixData(DataBuffer,1,16,20,512,DBG_SHOWMAT_HEX);
00191 WaitKeyPress(MSG_PRESSKEY);
00192 kprintf("\n\r CHAR DATA");
00193 ShowMatrixData(DataBuffer,1,40,20,512,DBG_SHOWMAT_ASCII);
00194 WaitKeyPress(MSG_PRESSKEY);
00195 }
00196 }
00197 else
00198 kprintf("\n\rBad Device Number");
00199 kprintf("\n\r ");
00200 }
00201
00202 void Sh_IdeWrite()
00203 {
00204 int Dev;
00205 int i=0;
00206 int Lba;
00207 char DataBuffer[512];
00208 int Pattern;
00209 int Err=FALSE;
00210 byte Data;
00211
00212 kprintf("\n\rInsert the channel number (0 or 1): 0\b");
00213 scanf("%i", &Dev);
00214 kprintf("\n\rChannel %i Selected",Dev);
00215 if ( Dev==0 )
00216 {
00217 SelectAtaChannel(CC_PRIMARY);
00218 }
00219 else if ( Dev==1 )
00220 {
00221 SelectAtaChannel(CC_SECONDARY);
00222 }
00223 else
00224 {
00225 kprintf("\n\rBad Channel Number Channel 0 will be selected");
00226 SelectAtaChannel(CC_PRIMARY);
00227 }
00228
00229
00230 kprintf("\n\rInsert the device number to Write (0 or 1): 0\b");
00231 scanf("%i", &Dev);
00232 kprintf("\n\rDevice %i Selected",Dev);
00233 if ( Dev==0 || Dev==1 )
00234 {
00235
00236 kprintf("\n\rInsert Lba : ");
00237 scanf("%i", &Lba);
00238 kprintf("\n\rLba Selected %i",Lba);
00239
00240 kprintf("\n\rSpecify Type of Pattern To Write (1 byte in decimal format): ");
00241 scanf("%i",&Pattern);
00242 kprintf("\n\rPattern: %i",Pattern);
00243 Data=(byte) Pattern;
00244 for (i=0;i<512;i++)
00245 DataBuffer[i]=Data;
00246
00247 Err=WriteSectorsLba(Dev,(int64) Lba,1,(word *) &DataBuffer,TRUE);
00248 if (Err)
00249 ShowIdeErrorMessage(Err,TRUE);
00250 }
00251 else
00252 kprintf("\n\rBad Device Number");
00253 kprintf("\n\r ");
00254
00255 }
00256
00257 void Sh_IdeDeviceInfo()
00258 {
00259 int Dev;
00260
00261 kprintf("\n\rInsert the channel number (0 or 1): 0\b");
00262 scanf("%i", &Dev);
00263 kprintf("\n\rChannel %i Selected",Dev);
00264 if ( Dev==0 )
00265 SelectAtaChannel(CC_PRIMARY);
00266 else if ( Dev==1 )
00267 SelectAtaChannel(CC_SECONDARY);
00268 else
00269 {
00270 kprintf("\n\rBad Channel Number Channel 0 will be selected");
00271 SelectAtaChannel(CC_PRIMARY);
00272 }
00273
00274
00275 kprintf("\n\rInsert the device number (0 or 1): 0\b");
00276 scanf("%i", &Dev);
00277 kprintf("\n\rDevice %i Selected",Dev);
00278 if ( Dev==0 || Dev==1 )
00279 {
00280 ShowDeviceData(Dev,30);
00281 }
00282 }
00283
00284
00285
00286
00287 void sh_cd2(char *argv)
00288 {
00289
00290 if (argv[0]=='\0') return;
00291
00292 cd_ext2(argv);
00293 }
00294
00295 void sh_cat2(char *argv)
00296 {
00297
00298 if (argv[0]=='\0')
00299 {
00300 kprintf("\n\rcat2 requires argument\n\r");
00301 return;
00302 }
00303 cat_ext2(argv);
00304 }
00305
00306
00307
00308 byte fd_buffer[FDC_SECTOR_SIZE];
00309
00310 void sh_read(char *argv)
00311 {
00312
00313 int block, i;
00314
00315 block = atoi(argv);
00316 kprintf("\n\rReading block %u...\n\r", block);
00317 kprintf("\n\r");
00318
00319 memset(fd_buffer, 0, FDC_SECTOR_SIZE);
00320
00321 for(i=0; i<3; i++)
00322 if (fdc_read(block, fd_buffer, 1)) break;
00323
00324 if (i != 3)
00325 for(i=0; i<512; i++)
00326 kputchar(fd_buffer[i]);
00327 else
00328 kprintf("\n\rFloppy I/O error. Unable to read the block!!!\n\r");
00329
00330 kprintf("\n\r");
00331 }
00332
00333 void sh_write(char *argv)
00334 {
00335
00336 int block, i;
00337
00338 block = atoi(argv);
00339 kprintf("\n\rWriting block %u...\n\r", block);
00340 for(i=0; i<3; i++)
00341 if (fdc_write(block, fd_buffer, 1)) break;
00342
00343 if (i == 3)
00344 kprintf("\n\rFloppy I/O error. Unable to write the block!!!\n\r");
00345 }
00346
00347 void sh_kill(char *argv)
00348 {
00349 kprintf("\n\rKilling task %i...", atoi(argv));
00350 if ( kill(atoi(argv)) )
00351 kprintf(" OK!\n\r");
00352 else
00353 kprintf("\n\rCannot kill this task!\n\r");
00354 }
00355
00356
00357 #define V86_START_ADDRESS 0x10000
00358
00359 void sh_v86_exec(char *argv)
00360 {
00361 byte *file_buffer;
00362 int file_size;
00363 task_t *child;
00364 int status;
00365
00366 if( !argv )
00367 {
00368 kprintf("file name?\n");
00369 return;
00370 }
00371 strtoupper(argv);
00372
00373
00374 file_size = get_file_size(argv);
00375
00376 if (file_size != -1)
00377 {
00378
00379 file_buffer = kmalloc(file_size);
00380 load_file(argv, file_buffer);
00381 child = create_v86_process((void *)V86_START_ADDRESS, file_buffer, file_size, argv);
00382 kfree(file_buffer);
00383
00384 waitpid(child->pid, &status, 0);
00385 }
00386 }
00387
00388 void sh_v86_bg(char *argv)
00389 {
00390
00391 byte *file_buffer;
00392 int file_size;
00393
00394 if( !argv )
00395 {
00396 kprintf("file name?\n");
00397 return;
00398 }
00399 strtoupper(argv);
00400
00401
00402 file_size = get_file_size(argv);
00403
00404 if (file_size != -1)
00405 {
00406
00407 file_buffer = kmalloc(file_size);
00408 load_file(argv, file_buffer);
00409 create_v86_process((void *)V86_START_ADDRESS, file_buffer, file_size, argv);
00410 kfree(file_buffer);
00411 }
00412 }
00413
00414
00415
00416 int sh_parse_params(const char *cmd_str, char ***argv, int *argc)
00417 {
00418 char *strtmp=NULL, *cmd_line=NULL;
00419 int i, len;
00420
00421
00422 *argv = (char **)NULL;
00423 *argc = 0;
00424
00425
00426 if ( cmd_str==NULL )
00427 return( 0 );
00428 if ( *cmd_str == '\0' )
00429 return( 0 );
00430
00431
00432 if ( (len=strlen(cmd_str))!=0 )
00433 cmd_line = kmalloc(len+1);
00434
00435 if ( cmd_line == NULL )
00436 return( -ENOMEM );
00437
00438 strcpy( cmd_line, cmd_str );
00439
00440
00441 while( *cmd_line == ' ' )
00442 cmd_line++;
00443
00444
00445 strtmp = cmd_line;
00446 while( TRUE )
00447 {
00448 switch( *strtmp )
00449 {
00450 case ' ':
00451 *strtmp++ = '\0';
00452 (*argc)++;
00453 while( *strtmp == ' ' )
00454 {
00455 *strtmp++ = '\0';
00456 }
00457 if ( *strtmp == '\0' )
00458 {
00459 goto argc_done;
00460 }
00461 break;
00462
00463 case '\0':
00464 case '\n':
00465 *strtmp = '\0';
00466 (*argc)++;
00467 goto argc_done;
00468 break;
00469
00470 default:
00471 strtmp++;
00472 break;
00473 }
00474 }
00475 argc_done:
00476
00477 *argv = kmalloc( (*argc) * sizeof(char *) );
00478
00479
00480 for( i=0; i<(*argc); i++ )
00481 {
00482 (*argv)[i] = cmd_line;
00483 len = strlen(cmd_line);
00484 cmd_line += (len);
00485 while( *(++cmd_line) == '\0' );
00486 }
00487
00488
00489 kfree( cmd_line );
00490 return( 0 );
00491 }
00492
00493
00494 void sh_exec(char *cmd_line)
00495 {
00496 task_t *child;
00497 int file_size;
00498 int status;
00499 int u_argc;
00500 char **u_argv;
00501
00502
00503
00504 if ( sh_parse_params(cmd_line, &u_argv, &u_argc) < 0 )
00505 {
00506 kprintf("\n\rOut of virtual memory!!!");
00507 return;
00508 }
00509
00510 if( !u_argv )
00511 {
00512 kprintf("file name?\n");
00513 return;
00514 }
00515 strtoupper( u_argv[0] );
00516
00517
00518 file_size = get_file_size( u_argv[0] );
00519
00520 if ( file_size != -1 )
00521 {
00522
00523 child = new_task(u_argv[0], u_argc, u_argv, USER_PRIVILEGE);
00524 if ( child == NULL )
00525 {
00526
00527
00528 sh_v86_exec( u_argv[0] );
00529 kfree( u_argv );
00530 return;
00531 }
00532
00533 waitpid(child->pid, &status, 0);
00534 }
00535 else
00536 kprintf("\n\rFile not found!\n\r");
00537
00538
00539 kfree( u_argv );
00540 }
00541
00542
00543 void sh_bg(char *cmd_line)
00544 {
00545 int file_size;
00546 task_t *child;
00547 int u_argc;
00548 char **u_argv;
00549
00550
00551
00552 if ( sh_parse_params(cmd_line, &u_argv, &u_argc) < 0 )
00553 {
00554 kprintf("\n\rOut of virtual memory!!!");
00555 return;
00556 }
00557
00558 if( !u_argv )
00559 {
00560 kprintf("file name?\n");
00561 return;
00562 }
00563 strtoupper( u_argv[0] );
00564
00565
00566 file_size = get_file_size( u_argv[0] );
00567
00568 if ( file_size != -1 )
00569 {
00570
00571 child = new_task(u_argv[0], u_argc, u_argv, USER_PRIVILEGE);
00572 if ( child == NULL )
00573 {
00574
00575
00576 sh_v86_bg( u_argv[0] );
00577 kfree( u_argv );
00578 return;
00579 }
00580 }
00581 else
00582 kprintf("\n\rFile not found!\n\r");
00583
00584
00585 kfree( u_argv );
00586 }
00587
00588 void sh_cat(char *argv)
00589 {
00590
00591 strtoupper(argv);
00592 if ( cat(argv) )
00593 kprintf("\n\r");
00594 else
00595 kprintf("\n\rFile not found!\n\r");
00596 }
00597
00598 void sh_cd(char *argv)
00599 {
00600
00601 strtoupper(argv);
00602 if (argv[0]=='\0') return;
00603 if ( !(cd(argv)) )
00604 kprintf("\n\rMiniShell: cd: %s: No such directory\n\r", argv);
00605 }
00606
00607 void sh_rm(char *argv)
00608 {
00609
00610 strtoupper(argv);
00611 if ( rm(argv) )
00612 kprintf("Deleted!\n\r");
00613 else
00614 kprintf("\n\rFile not found!\n\r");
00615 }
00616
00617 void task_test()
00618 {
00619 register int cr3;
00620 __asm__ __volatile__(
00621 "movl %%cr3, %%eax"
00622 : "=a"(cr3) : );
00623 __asm__ __volatile__ ("" : : : "eax");
00624 kprintf("\n\rHello from task %u!!! My PDBR is @ %#010x\n\r", get_pid(), cr3);
00625 _exit( 0 );
00626 }
00627
00628 void sh_test(char *argv)
00629 {
00630 int i;
00631 short int n;
00632
00633 n = atoi(argv);
00634 if ( !n ) n=1;
00635 kprintf("\n\rCreating %u background tasks. Please wait.\n\r", n);
00636 for(i=0; i<n; i++)
00637 {
00638 create_process(&task_test, &task_test, 0, "sh_task_test", KERNEL_PRIVILEGE);
00639 kputchar('.');
00640 }
00641 }
00642
00643 void show_cpuid()
00644 {
00645 typedef struct cache_info {
00646 byte index;
00647 char *string;
00648 } cache_info_t;
00649
00650
00651 static cache_info_t cache_strings[37] = {
00652
00653 { 0x01, "Instruction TLB: 4KB Pages 4-way set associative, 32 entries" },
00654 { 0x02, "Instruction TLB: 4MB Pages, 4-way set associative, 2 entries" },
00655 { 0x03, "Data TLB: 4KB Pages, 4-way set associative, 64 entries" },
00656 { 0x04, "Data TLB: 4MB Pages, 4-way set associative, 8 entries" },
00657 { 0x06, "1st-level instruction cache: 8KB, 4-way set associative, 32 byte line size" },
00658 { 0x08, "1st-level instruction cache: 16KB, 4-way set associative, 32 byte line size" },
00659 { 0x0A, "1st-level data cache: 8KB, 2-way set associative, 32 byte line size" },
00660 { 0x0C, "1st-level data cache: 16KB, 4-way set associative, 32 byte line size" },
00661 { 0x22, "3rd-level cache: 512KB, 4-way set associative, dual-sectored line, 64 byte sector size" },
00662 { 0x23, "3rd-level cache: 1MB, 8-way set associative, dual-sectored line, 64 byte sector size" },
00663 { 0x40, "No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache" },
00664 { 0x41, "2nd-level cache: 128KB, 4-way set associative, 32 byte line size" },
00665 { 0x42, "2nd-level cache: 256KB, 4-way set associative, 32 byte line size" },
00666 { 0x43, "2nd-level cache: 512KB, 4-way set associative, 32 byte line size" },
00667 { 0x44, "2nd-level cache: 1MB, 4-way set associative, 32 byte line size" },
00668 { 0x45, "2nd-level cache: 2MB, 4-way set associative, 32 byte line size" },
00669 { 0x50, "Instruction TLB: 4KB and 2MB or 4MB pages, 64 entries" },
00670 { 0x51, "Instruction TLB: 4KB and 2MB or 4MB pages, 128 entries" },
00671 { 0x52, "Instruction TLB: 4KB and 2MB or 4MB pages, 256 entries" },
00672 { 0x5B, "Data TLB: 4KB and 4MB pages, 64 entries" },
00673 { 0x5C, "Data TLB: 4KB and 4MB pages, 128 entries" },
00674 { 0x5D, "Data TLB: 4KB and 4MB pages, 256 entries" },
00675 { 0x66, "1st-level data cache: 8KB, 4-way set associative, 64 byte line size" },
00676 { 0x67, "1st-level data cache: 16KB, 4-way set associative, 64 byte line size" },
00677 { 0x68, "1st-level data cache: 32KB, 4-way set associative, 64 byte line size" },
00678 { 0x70, "Trace cache: 12K-op, 8-way set associative" },
00679 { 0x71, "Trace cache: 16K-op, 8-way set associative" },
00680 { 0x72, "Trace cache: 32K-op, 8-way set associative" },
00681 { 0x79, "2nd-level cache: 128KB, 8-way set associative, dual-sectored line, 64 byte sector size" },
00682 { 0x7A, "2nd-level cache: 256KB, 8-way set associative, dual-sectored line, 64 byte sector size" },
00683 { 0x7B, "2nd-level cache: 512KB, 8-way set associative, dual-sectored line, 64 byte sector size" },
00684 { 0x7C, "2nd-level cache: 1MB, 8-way set associative, dual-sectored line, 64 byte sector size" },
00685 { 0x82, "2nd-level cache: 256KB, 8-way set associative, 32 byte line size" },
00686 { 0x83, "2nd-level cache: 512KB, 8-way set associative, 32 byte line size" },
00687 { 0x84, "2nd-level cache: 1MB, 8-way set associative, 32 byte line size" },
00688 { 0x85, "2nd-level cache: 2MB, 8-way set associative, 32 byte line size" },
00689 };
00690
00691 int eax, ebx, ecx, edx;
00692 dword vendor[4];
00693 dword i, j;
00694 int virtual;
00695 uint64_t timestamp1, timestamp2;
00696 uint32_t mhz_freq;
00697 dword IF = GET_IF();
00698
00699 kprintf("\n\rReading CPU informations...");
00700
00701
00702 disable();
00703
00704
00705 (void)time_read();
00706
00707 __asm__ __volatile__("rdtsc" : "=A"(timestamp1));
00708
00709 (void)time_read();
00710
00711 __asm__ __volatile__("rdtsc" : "=A"(timestamp2));
00712
00713 mhz_freq = ((uint32_t)(timestamp2 - timestamp1))/1000000;
00714 kprintf("\n\rFrequency: %u MHz", mhz_freq);
00715
00716 SET_IF(IF);
00717
00718
00719 cpuid(0, &eax, &ebx, &ecx, &edx);
00720
00721 vendor[0] = ebx;
00722 vendor[1] = edx;
00723 vendor[2] = ecx;
00724 vendor[3] = 0;
00725
00726 kprintf("\n\rDetected \"%s\" CPU", (char *)vendor);
00727
00728
00729 cpuid(1, &eax, &ebx, &ecx, &edx);
00730
00731
00732 switch((eax >> 12) & 0x03)
00733 {
00734 case 0:
00735 kprintf("\n\rOriginal OEM Processor");
00736 break;
00737
00738 case 1:
00739 kprintf("\n\rIntel Overdrive(R) Processor");
00740 break;
00741
00742 case 2:
00743 kprintf("\n\rDual Processor");
00744 break;
00745
00746 case 3:
00747 kprintf("\n\r??? (reserved)");
00748 break;
00749 }
00750
00751 kprintf( "\n\rFamily=%u Model=%u SteppingID=%u\n\r",
00752 ((eax >> 8) & 0x0F), ((eax >> 4) & 0x0F), ((eax >> 0) & 0x0F) );
00753
00754
00755 switch(ebx & 0xFF)
00756 {
00757 case 0:
00758 kprintf( "Brand identification not supported\n\r"
00759 "Processor produced before the introduction of Pentium III Xeon processor\n\r");
00760 break;
00761
00762 case 1:
00763 kprintf("Celeron\n\r");
00764 break;
00765
00766 case 2:
00767 kprintf("Pentium III\n\r");
00768 break;
00769
00770 case 3:
00771 kprintf("Pentium III Xeon\n\r");
00772 break;
00773
00774 case 6:
00775 kprintf("Pentium III Mobile\n\r");
00776 break;
00777
00778 case 8:
00779 kprintf("Pentium 4 (Willamette)\n\r");
00780 break;
00781
00782 case 9:
00783 kprintf("Pentium 4 (Northwood)\n\r");
00784 break;
00785
00786 default:
00787 kprintf("??? (processor) %u\n\r", (ebx & 0xFF));
00788 break;
00789 }
00790
00791
00792 if ( edx & (1<<23) ) kprintf("MMX Technology found\n\r");
00793 if ( edx & (1<<25) ) kprintf("SSE extension supported\n\r");
00794 if ( edx & (1<<26) ) kprintf("SSE2 extension supported\n\r");
00795 if ( (edx & (1<<28)) )
00796 {
00797 virtual = ( (ebx >> 16) & 0xFF );
00798 kprintf("Hyper-Threading Technology found (%u virtual %s)\n\r",
00799 virtual, (virtual > 1) ? ("processors") : ("processor") );
00800 }
00801
00802
00803 do
00804 {
00805
00806 cpuid(2, &eax, &ebx, &ecx, &edx);
00807 } while ((eax & 0x0F) != 1);
00808
00809 kprintf("\n\r- Internal cache informations -\n\r");
00810 if (!(eax & 0x80000000)) vendor[0] = (eax >> 8);
00811 if (!(ebx & 0x80000000)) vendor[1] = ebx;
00812 if (!(ecx & 0x80000000)) vendor[2] = ecx;
00813 if (!(edx & 0x80000000)) vendor[3] = edx;
00814
00815 for (j=0; j<(sizeof(cache_strings)/sizeof(cache_info_t)); j++)
00816 for (i=0; i<4*sizeof(dword); i++)
00817 {
00818 if ( ((char *)vendor)[i] != 0)
00819 if ( ((char *)vendor)[i]==cache_strings[j].index )
00820 {
00821 kprintf("%s\n\r", cache_strings[j].string);
00822 break;
00823 }
00824 }
00825 kprintf("\n\r");
00826 }
00827
00828 void sh_help(char *argv)
00829 {
00830
00831 int i, row;
00832
00833 kprintf("\n\r%s\n\r", SH_VERSION);
00834
00835 if ( *argv != NULL )
00836 {
00837
00838 for (i=0; i<SH_COMMANDS; i++)
00839 if (strcmp(argv, commands[i].name)==0)
00840 {
00841
00842 kprintf("\n\r-> ");
00843 set_color(WHITE);
00844 kprintf("%s", commands[i].usage);
00845 set_color(DEFAULT_COLOR);
00846 kprintf("\n\r %s;\n\n\r", commands[i].help);
00847 return;
00848 }
00849
00850 kprintf("\n\r Command not found!\n\n\r");
00851 return;
00852 }
00853
00854
00855 for (i=0, row=2; i<SH_COMMANDS; i++)
00856 {
00857
00858 kprintf("\n\r-> ");
00859 set_color(WHITE);
00860 kprintf("%s", commands[i].usage);
00861 set_color(DEFAULT_COLOR);
00862 kprintf("\n\r %s;", commands[i].help);
00863
00864
00865 row += 2;
00866 if (row >= 24)
00867 {
00868 if (kgetchar() == CTRL_C) break;
00869 row = 0;
00870 }
00871 }
00872 kprintf("\n\n\r");
00873 }
00874
00875 void ps_task()
00876 {
00877
00878 ps();
00879 _exit(0);
00880 }
00881
00882 void sh_ps()
00883 {
00884 pid_t pid;
00885 int status;
00886 pid = create_process(&ps_task, &ps_task, 0, "ps", KERNEL_PRIVILEGE)->pid;
00887 waitpid(pid, &status, 0);
00888 }
00889
00890 void sh_halt()
00891 {
00892
00893 kprintf("\n\rHalting system using APM features...");
00894 beep();
00895
00896 sh_cd("/");
00897 sh_cd("bin");
00898 sh_v86_exec("halt.bin");
00899
00900
00901
00902
00903
00904 out(0x03F2, 0x0C);
00905
00906
00907 kprintf("\n\rNow you can turn off power.");
00908 halt();
00909 }
00910
00911 void sh_elf(char *argv)
00912 {
00913
00914 byte *file_buffer;
00915 int file_size;
00916
00917 if( !argv )
00918 {
00919 kprintf("background file?\n");
00920 return;
00921 }
00922 strtoupper(argv);
00923
00924
00925 file_size = get_file_size(argv);
00926
00927
00928 file_buffer = kmalloc(file_size);
00929 switch ( elf32_load_file(argv, file_buffer) )
00930 {
00931 case -ENOENT:
00932 kprintf("file not found!\n\r");
00933 break;
00934
00935 case -ENOEXEC:
00936 kprintf("not a valid ELF32 file!\n\r");
00937 break;
00938
00939 default:
00940 kprintf("ELF32 file-format OK!\n\r");
00941 break;
00942 }
00943 kfree(file_buffer);
00944 }
00945
00946 void shell()
00947 {
00948
00949
00950 #define SH_PROMPT "\r[root:/fd0/%s]# "
00951 #define CMD_ARG (cmd+strlen(commands[i].name)+1)
00952
00953
00954 char cmd[STR_MAX_LENGTH];
00955 int i;
00956
00957
00958 memset(cmd, 0, sizeof(cmd));
00959
00960
00961 set_color(DEFAULT_COLOR);
00962 kprintf("\n\rWelcome to the MiniShell (tty%u)", get_curr_task()->console);
00963 kprintf("\n\rHave a lot of fun...\n\r");
00964
00965
00966 while(TRUE)
00967 {
00968 kprintf(SH_PROMPT, pwd());
00969 gets(cmd);
00970
00971 for(i=0; i<SH_COMMANDS; i++)
00972 {
00973
00974 if ( strncmp(cmd, commands[i].name, strlen(commands[i].name))==0 )
00975 {
00976 if (*(cmd+strlen(commands[i].name)) == '\0')
00977 {
00978 *CMD_ARG = '\0';
00979 break;
00980 }
00981 if (*(cmd+strlen(commands[i].name)) == ' ')
00982 break;
00983 }
00984 }
00985
00986 if (i == SH_COMMANDS)
00987 {
00988
00989 if (!cmd[0]) continue;
00990
00991
00992 if( !strncmp(cmd, "./", 2) )
00993 {
00994 if( cmd[2]=='\0' )
00995 {
00996 kprintf("\n%s: is a directory\n");
00997 continue;
00998 }
00999 else
01000 {
01001 sh_exec(cmd+2);
01002 continue;
01003 }
01004 }
01005
01006
01007 kprintf("\n%s: command not found\n", cmd);
01008 continue;
01009 }
01010
01011 switch(commands[i].index)
01012 {
01013 case SH_HELP:
01014 sh_help(CMD_ARG);
01015 break;
01016
01017 case SH_UNAME:
01018 kprintf("\n\r%s - Kernel [v%s]\n\r", KERNEL_NAME, KERNEL_VERSION);
01019 break;
01020
01021 case SH_CLEAR:
01022 set_color(DEFAULT_COLOR);
01023 clrscr();
01024 break;
01025
01026 case SH_REBOOT:
01027 reboot();
01028 break;
01029
01030 case SH_DUMP:
01031 breakpoint();
01032 break;
01033
01034 case SH_READ:
01035 sh_read(CMD_ARG);
01036 break;
01037
01038 case SH_WRITE:
01039 sh_write(CMD_ARG);
01040 break;
01041
01042 case SH_PAGES:
01043 dump_dirty_pages();
01044 break;
01045
01046 case SH_MEM:
01047 dump_memory_map();
01048 break;
01049
01050 case SH_CHECKMEM:
01051 create_process(
01052 &check_free_frames_integrity,
01053 &check_free_frames_integrity,
01054 0,
01055 "frames_check",
01056 KERNEL_PRIVILEGE
01057 );
01058 break;
01059
01060 case SH_FRAMES:
01061 dump_free_frames();
01062 break;
01063
01064 case SH_EXEC:
01065 sh_exec(CMD_ARG);
01066 break;
01067
01068 case SH_BG:
01069 sh_bg(CMD_ARG);
01070 break;
01071
01072 case SH_V86EXEC:
01073 sh_v86_exec(CMD_ARG);
01074 break;
01075
01076 case SH_V86BG:
01077 sh_v86_bg(CMD_ARG);
01078 break;
01079
01080 case SH_TEST:
01081 sh_test(CMD_ARG);
01082 break;
01083
01084 case SH_CPUID:
01085 show_cpuid();
01086 break;
01087
01088 case SH_MOUNT:
01089 Read_FAT();
01090 break;
01091
01092 case SH_LS:
01093 ls();
01094 break;
01095
01096 case SH_CAT:
01097 sh_cat(CMD_ARG);
01098 break;
01099
01100 case SH_CD:
01101 sh_cd(CMD_ARG);
01102 break;
01103
01104 case SH_RM:
01105 sh_rm(CMD_ARG);
01106 break;
01107
01108 case SH_PS:
01109 sh_ps();
01110 break;
01111
01112 case SH_KILL:
01113 sh_kill(CMD_ARG);
01114 break;
01115
01116 case SH_RS232:
01117 rs232_chat(CMD_ARG);
01118 break;
01119
01120 case SH_PCISCAN:
01121 pci_scan();
01122 break;
01123
01124 case SH_RTL8139_INIT:
01125 ifconfig(CMD_ARG);
01126 break;
01127
01128 case SH_ETH_PING:
01129 ping(CMD_ARG);
01130 break;
01131
01132 case SH_ETH_ARP:
01133 arp_request(CMD_ARG);
01134 break;
01135
01136 case SH_HALT:
01137 sh_halt();
01138 break;
01139
01140 case SH_ELF:
01141 sh_elf(CMD_ARG);
01142 break;
01143
01144
01145 case SH_IDETEST:
01146 Sh_IdeTest();
01147 break;
01148 case SH_IDEREAD:
01149 Sh_IdeRead();
01150 break;
01151 case SH_IDEWRITE:
01152 Sh_IdeWrite();
01153 break;
01154 case SH_IDEDEVICEINFO:
01155 Sh_IdeDeviceInfo();
01156 break;
01157
01158
01159
01160 case SH_LS_EXT2:
01161 ls_ext2();
01162 break;
01163
01164 case SH_CD_EXT2:
01165 sh_cd2(CMD_ARG);
01166 break;
01167
01168 case SH_CAT_EXT2:
01169 sh_cat2(CMD_ARG);
01170 break;
01171
01172
01173 case SH_TIME:
01174 kprintf("\r%u\n\r", time_read());
01175 break;
01176 }
01177 }
01178 }