249 lines
7.2 KiB
C
249 lines
7.2 KiB
C
/* Copyright (C) 2005 David Decotigny
|
||
|
||
This program is free software; you can redistribute it and/or
|
||
modify it under the terms of the GNU General Public License
|
||
as published by the Free Software Foundation; either version 2
|
||
of the License, or (at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program; if not, write to the Free Software
|
||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||
USA.
|
||
*/
|
||
|
||
#include <crt.h>
|
||
#include <libc.h>
|
||
#include <stdarg.h>
|
||
#include <string.h>
|
||
#include <debug.h>
|
||
|
||
#include "fstest_utils.h"
|
||
|
||
/**
|
||
* @file chartest.c
|
||
*
|
||
* Character devices tests
|
||
*/
|
||
|
||
int main(void)
|
||
{
|
||
int fd, len;
|
||
unsigned int sum, mem_size;
|
||
char buff[256];
|
||
char *uaddr;
|
||
|
||
bochs_printf("Hi from chartest\n");
|
||
bochs_printf("WARNING: This test will eventually write 0 on kernel code !\n");
|
||
bochs_printf("This WILL crash the kernel (as expected...) !\n");
|
||
printf("WARNING: This test will eventually write 0 on kernel code !\n");
|
||
printf("This WILL crash the kernel (as expected...) !\n");
|
||
|
||
/* Make things more complicated */
|
||
fork();
|
||
fork();
|
||
|
||
/*
|
||
* /dev/zero
|
||
*/
|
||
|
||
TEST_EXPECT_CONDITION(fd = open("/dev/zero", O_RDWR), RETVAL == 3);
|
||
|
||
/* Make things more complicated: spawn and stay in child */
|
||
if (fork() > 0)
|
||
return 0;
|
||
|
||
strzcpy(buff, "Garbage", sizeof(buff));
|
||
TEST_EXPECT_CONDITION(len = read(fd, buff, sizeof(buff)),
|
||
RETVAL == sizeof(buff));
|
||
|
||
/* Make sure it is full with 0 */
|
||
for (len = 0 ; len < sizeof(buff) ; len ++)
|
||
if (buff[len])
|
||
break;
|
||
TEST_EXPECT_CONDITION(len, RETVAL == sizeof(buff));
|
||
|
||
TEST_EXPECT_CONDITION(len = write(fd, 0, 123456789), RETVAL == 123456789);
|
||
TEST_EXPECT_CONDITION(len = lseek(fd, 1234, SEEK_SET), RETVAL == 1234);
|
||
|
||
/* Map it once */
|
||
TEST_EXPECT_CONDITION(uaddr = mmap(NULL, 8192,
|
||
PROT_READ | PROT_WRITE, 0,
|
||
fd, 4096), RETVAL != (int)NULL);
|
||
|
||
/* Make sure it is full with 0 */
|
||
for (len = 0 ; len < 8192 ; len ++)
|
||
if (uaddr[len])
|
||
break;
|
||
TEST_EXPECT_CONDITION(len, RETVAL == 8192);
|
||
|
||
strzcpy(uaddr, "Hello /dev/zero", 8192);
|
||
TEST_EXPECT_CONDITION(strcmp(uaddr, "Hello /dev/zero"), RETVAL == 0);
|
||
|
||
/* Map it again */
|
||
TEST_EXPECT_CONDITION(uaddr = mmap(NULL, 8192,
|
||
PROT_READ | PROT_WRITE, 0,
|
||
fd, 4096), RETVAL != (int)NULL);
|
||
/* Make sure it is full with 0 */
|
||
for (len = 0 ; len < 8192 ; len ++)
|
||
if (uaddr[len])
|
||
break;
|
||
TEST_EXPECT_CONDITION(len, RETVAL == 8192);
|
||
|
||
strzcpy(uaddr, "Hello /dev/zero", 8192);
|
||
TEST_EXPECT_CONDITION(strcmp(uaddr, "Hello /dev/zero"), RETVAL == 0);
|
||
|
||
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
|
||
|
||
|
||
/*
|
||
* /dev/null
|
||
*/
|
||
|
||
TEST_EXPECT_CONDITION(fd = open("/dev/null", O_RDWR), RETVAL == 3);
|
||
|
||
/* Make things more complicated: spawn and stay in child */
|
||
if (fork() > 0)
|
||
return 0;
|
||
|
||
strzcpy(buff, "Garbage", sizeof(buff));
|
||
TEST_EXPECT_CONDITION(len = read(fd, buff, sizeof(buff)),
|
||
RETVAL == 0);
|
||
|
||
/* Make sure buffer did not change */
|
||
TEST_EXPECT_CONDITION(strcmp("Garbage", buff), RETVAL == 0);
|
||
|
||
TEST_EXPECT_CONDITION(len = write(fd, 0, 123456789), RETVAL == 123456789);
|
||
TEST_EXPECT_CONDITION(len = lseek(fd, 1234, SEEK_SET), RETVAL == 1234);
|
||
|
||
/* Map it once */
|
||
TEST_EXPECT_CONDITION(uaddr = mmap(NULL, 8192,
|
||
PROT_READ | PROT_WRITE, 0,
|
||
fd, 4096), RETVAL != (int)NULL);
|
||
/* Make sure it is full with 0 */
|
||
for (len = 0 ; len < 8192 ; len ++)
|
||
if (uaddr[len])
|
||
break;
|
||
TEST_EXPECT_CONDITION(len, RETVAL == 8192);
|
||
|
||
strzcpy(uaddr, "Hello /dev/null", 8192);
|
||
TEST_EXPECT_CONDITION(strcmp(uaddr, "Hello /dev/null"), RETVAL == 0);
|
||
|
||
/* Map it again */
|
||
TEST_EXPECT_CONDITION(uaddr = mmap(NULL, 8192,
|
||
PROT_READ | PROT_WRITE, 0,
|
||
fd, 4096), RETVAL != (int)NULL);
|
||
/* Make sure it is full with 0 */
|
||
for (len = 0 ; len < 8192 ; len ++)
|
||
if (uaddr[len])
|
||
break;
|
||
TEST_EXPECT_CONDITION(len, RETVAL == 8192);
|
||
|
||
strzcpy(uaddr, "Hello /dev/null", 8192);
|
||
TEST_EXPECT_CONDITION(strcmp(uaddr, "Hello /dev/null"), RETVAL == 0);
|
||
|
||
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
|
||
|
||
/*
|
||
* Invalid device instance of zero.c
|
||
*/
|
||
TEST_EXPECT_CONDITION(mknod("/dev/invalid_zero", S_IRUSR | S_IWUSR,
|
||
S_IFCHR, 1, 42), RETVAL == 0);
|
||
ls("/", 1, 1);
|
||
TEST_EXPECT_CONDITION(fd = open("/dev/invalid_zero", O_RDWR), RETVAL < 0);
|
||
TEST_EXPECT_CONDITION(unlink("/dev/invalid_zero"), RETVAL == 0);
|
||
|
||
|
||
/*
|
||
* Invalid device class / device instance
|
||
*/
|
||
TEST_EXPECT_CONDITION(mknod("/dev/invalid_devclass", S_IRUSR | S_IWUSR,
|
||
S_IFCHR, 54654, 476576), RETVAL == 0);
|
||
ls("/", 1, 1);
|
||
TEST_EXPECT_CONDITION(fd = open("/dev/invalid_devclass",
|
||
O_RDWR), RETVAL < 0);
|
||
TEST_EXPECT_CONDITION(unlink("/dev/invalid_devclass"), RETVAL == 0);
|
||
|
||
|
||
/*
|
||
* Make a checksum of all physical memory (/dev/mem)
|
||
*/
|
||
TEST_EXPECT_CONDITION(fd = open("/dev/mem", O_RDONLY), RETVAL == 3);
|
||
|
||
/* Make things more complicated: spawn and stay in child */
|
||
if (fork() > 0)
|
||
return 0;
|
||
|
||
for (mem_size = 0, sum = 0 ;
|
||
len = read(fd, buff, sizeof(buff)), len > 0 ;
|
||
mem_size += len)
|
||
{
|
||
char *c;
|
||
if (((mem_size / sizeof(buff)) % 4000) == 0)
|
||
printf("Read %d MB of physical memory\n", mem_size >> 20);
|
||
|
||
for (c = buff ; c - buff < len ; c++)
|
||
sum += *c;
|
||
}
|
||
TEST_EXPECT_CONDITION(mem_size, RETVAL > 0);
|
||
printf("Checkum of RAM (%d MB) is %x\n", mem_size >> 20, sum);
|
||
TEST_EXPECT_CONDITION(len = lseek(fd, 0, SEEK_SET), len == 0);
|
||
TEST_EXPECT_CONDITION(len = lseek(fd, 0, SEEK_END), len == mem_size);
|
||
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
|
||
|
||
/*
|
||
* Make a checksum of main kernel memory (/dev/kmem)
|
||
*/
|
||
TEST_EXPECT_CONDITION(fd = open("/dev/kmem", O_RDONLY), RETVAL == 3);
|
||
|
||
/* Make things more complicated: spawn and stay in child */
|
||
if (fork() > 0)
|
||
return 0;
|
||
|
||
/* Seek to beginning of main .text section */
|
||
TEST_EXPECT_CONDITION(lseek(fd, 0x201000, SEEK_SET), RETVAL == 0x201000);
|
||
for (mem_size = 0, sum = 0 ;
|
||
len = read(fd, buff, sizeof(buff)), len > 0 ;
|
||
mem_size += len)
|
||
{
|
||
char *c;
|
||
if (((mem_size / sizeof(buff)) % 400) == 0)
|
||
printf("Read %d kB of kernel memory\n", mem_size >> 10);
|
||
|
||
for (c = buff ; c - buff < len ; c++)
|
||
sum += *c;
|
||
}
|
||
TEST_EXPECT_CONDITION(mem_size, RETVAL > 0);
|
||
printf("Checkum of main kernel area (%d kB) is %x\n",
|
||
mem_size >> 10, sum);
|
||
TEST_EXPECT_CONDITION(len = lseek(fd, 0, SEEK_SET), len == 0);
|
||
TEST_EXPECT_CONDITION(len = lseek(fd, 0, SEEK_END), len == 0x40000000);
|
||
TEST_EXPECT_CONDITION(close(fd), RETVAL == 0);
|
||
|
||
printf("Bye from chartest\n");
|
||
ls("/", 1, 1);
|
||
|
||
/* Crash the whole kernel */
|
||
bochs_printf("[31;1mNOW Crashing the whole thing !...[m\n");
|
||
|
||
{
|
||
int i;
|
||
for (i = 5 ; i >= 0 ; i --)
|
||
{
|
||
printf("Crashing the whole thing in %ds !... \r", i);
|
||
sleep(1);
|
||
}
|
||
}
|
||
printf("\nGO !\n");
|
||
TEST_EXPECT_CONDITION(fd = open("/dev/mem", O_WRONLY), RETVAL == 3);
|
||
memset(buff, 0xcc, sizeof(buff));
|
||
while (write(fd, buff, sizeof(buff)))
|
||
continue;
|
||
|
||
return 0;
|
||
}
|