资源描述
操作系统实验报告
班级:
学号:
姓名:
【实验内容】
(1)要求:熟悉和理解Linux编程环境
内容
v 编写一个C程序,使用Linux下的图形库,分窗口显示三个并发进程的运行。
(2)要求:掌握添加设备驱动程序的方法
内容:
v 采用模块方法,添加一个新的设备驱动程序。
v 要求添加字符设备的驱动。
v 编写一个应用程序,测试添加的驱动程序。
(3)要求:理解和分析/proc文件
内容
v 了解/proc文件的特点和使用方法。
v 监控系统状态,显示系统中若干部件的使用情况。
v 用图形界面显示系统监控状态。
【实验过程】
1. 安装和学习LINUX 下 GTK的使用:
$sudo apt-get install build-essential
$sudo apt-get install gnome-core-devel
$sudo apt-get install pkg-config
$sudo apt-get install libgtk2.0*
(下载安装GTK)
2. 初步架构:
每个GTK项目大同小异,使用相同的库函数(当然参数根据具体情况而定,而特殊的函数是为了实现特殊的功能)。
首先要创建窗体window,设置完参数后连接到信号并设置窗口名称;
然后创建组装盒,设置参数(横向纵向,位置等等),然后将组装盒放进window并显示;
在组装盒内部,根据不同实验的具体要求创建标签或者进度条等项目,设置好参数(比如在组装盒内的排布问题)后放入组装盒并显示;
最后说明,一个窗口可以由多个组装盒组成,一个组装盒一般有多个标签, 项目的整体实现就是由组装盒和标签“罗列”而成。
3. 撰写源程序:
【实验一】:
#include <gtk/gtk.h>
#include <sys/types.h>
#include <unistd.h>
gint progress_timeout( gpointer pbar )
{
gdouble new_val;
char s[10];
new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pbar)) + 0.01;
if (new_val > 1.0)
new_val = 0.0;
sprintf (s, "%.0f%%", new_val*100);
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar), new_val);
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pbar),s);
return TRUE;
}
void destroy_progress( GtkWidget *widget)
{
gtk_main_quit ();
}
void show(int argc,char *argv[],char *title )
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *pbar;
GtkWidget *pbar2;
GtkWidget *button;
GtkWidget *label;
int timer;
char id_char[50];
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy_progress), NULL);
gtk_window_set_title (GTK_WINDOW (window), title);
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
vbox = gtk_vbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
sprintf (id_char, "鏈繘绋婭D:%d", getpid ());
label = gtk_label_new (id_char);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
sprintf (id_char, "鐖惰繘绋婭D:%d", getppid ());
label = gtk_label_new (id_char);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
pbar = gtk_progress_bar_new ();
gtk_box_pack_start (GTK_BOX (vbox), pbar, FALSE, FALSE, 0);
gtk_widget_show (pbar);
timer = gtk_timeout_add (100, progress_timeout, pbar);
button = gtk_button_new_with_label ("close");
g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), window);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main ();
}
int main(int argc, char *argv[])
{
int pid = fork ();
if (pid < 0)
printf ("error!\n");
else if (pid == 0)
{
int pid = fork ();
if (pid < 0)
printf ("error!\n");
else if (pid == 0)
show (argc,argv,"process3");
else
show (argc,argv,"process2"); }
else
show (argc,argv,"process1");
}
【实验二】:
Mydev.c:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#define BUFFER_SIZE 2048
MODULE_LICENSE("GPL");
static int mydev_major = 0;
unsigned char mybuffer[BUFFER_SIZE]="cs0905 U200915015 xc";
int Device_Open=0;
static ssize_t my_open(struct inode *inode,struct file *file)
{
static int counter=0;
if(Device_Open)
return -EBUSY;
Device_Open++;
printk("the device has been called %d times\n",counter++);
return 0;
}
static ssize_t my_release(struct inode *inode,struct file *file)
{
if(Device_Open==0)
return -1;
else
Device_Open=0;
return 0;
}
static ssize_t my_write (struct file *filp, const char __user *buf, size_t count,loff_t *pos){
int size=count;
if(size>BUFFER_SIZE)
{
printk("out of the max size!\n");
size=BUFFER_SIZE;
}
if(copy_from_user(mybuffer,buf,sizeof(mybuffer)))
return -ENOMEM;
return size;
}
static ssize_t my_read(struct file *filp, char __user *buf,size_t count, loff_t *pos){
int size=count;
if(size>BUFFER_SIZE)
{
printk("out of the max size!\n");
size=BUFFER_SIZE;
}
if(copy_to_user(buf, mybuffer, size))
return -ENOMEM;
return size;
}
static struct file_operations mydev_fops={
.read=my_read,
.write=my_write,
.open=my_open,
.release=my_release,
};
static int __init mydev_init(void)
{
int result;
result=register_chrdev(0,"mydev",&mydev_fops);
if(result<0)
{
printk("error:can not register the device\n");
return -1;
}
if(mydev_major==0){
mydev_major=result;
printk("<1>hehe,the device has been registerstatic ssize_t my_open(struct inode *inode,struct file *file)ed!\n");
printk("<1>the virtual device was assigned major number %d.\n",mydev_major);
printk("<1>To talk to the driver,create a dev file with\n");
printk("<1>'mknod/dev/my c %d 0'\n",mydev_major);
printk("<1>Remove the dev and the file when done\n");
}
return 0;
}
static void __exit mydev_exit(void)
{
unregister_chrdev(mydev_major,"mydev");
printk("<1>unloading the device\n");
}
module_init(mydev_init);
module_exit(mydev_exit);
test.c:
#include <fcntl.h>
#include <stdio.h>
#define MAXBUFF 1024
#define DEVICE "/dev/mydev"
int main(void){
char buff[MAXBUFF],buff2[MAXBUFF];
int fd;
printf("Now driver test beginning...\n");
printf("Open device...\n");
if ((fd=open(DEVICE,O_RDWR))<0){
printf("Open device is failed\n");
return 1;
}
else{
read(fd,buff,MAXBUFF);
printf("the content of device is readed:\n%s\n",buff);
printf("input something to device whatever you want:\n");
scanf("%s",buff);
printf("write your input to device...\n");
write(fd,buff,MAXBUFF);
read(fd,buff2,MAXBUFF);
printf("the content of device is readed again:\n%s\n",buff2);
}
printf("the driver test is ended successful\n");
return 0;
}
【实验三】:
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <dirent.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#define DENSITY 100
#define PMAX 100
enum
{
NAME_COLUMN,
PID_COLUMN,
CPU_COLUMN,
};
enum
{
MOD_COLUMN,
DEPEND_COLUMN,
NM_COLUMNS
};
GtkWidget *window;
GtkWidget *main_vbox;
GtkAccelGroup *accel_group;
GtkItemFactory *item_factory;
GtkWidget *menubar;
GtkWidget *notebook;
GtkWidget *label;
GtkWidget *mem_label;
GtkWidget *swap_label;
GtkWidget *vbox;
GtkWidget *cpu_draw_area;
GtkWidget *mem_draw_area;
GtkWidget *frame;
GtkWidget *info_label;
GString *info;
GtkWidget *status_bar;
GtkWidget *scrolled_window;
GtkListStore *process_store;
GtkWidget *ptree_view;
GtkWidget *mtree_view;
GtkCellRenderer *renderer; *column; GtkWidget *hbox;
GtkWidget *prefresh_button,*pdelete_button; gdouble fuser = 0;
gdouble ftotal = 0;
gdouble total = 0;
gdouble pfuser[PMAX];
gdouble rate = 0;
gint cpu_graph[DENSITY];
mem_graph[DENSITY];
GdkPixmap *mgraph = NULL;
void destroy_window (GtkWidget *, gpointer);
void sys_shutdown(GtkWidget *, gpointer);
void sys_reboot (GtkWidget *, gpointer);
void sys_halt (GtkWidget *, gpointer);
void about_author (GtkWidget *, gpointer);
gboolean handle_timeout (gpointer data);
gboolean load_graph_refresh (GtkWidget *widget);
gboolean get_cpu_rate (gpointer data);
void create_sys_status_page (void);
void create_process_page (void);
void create_sys_info_page (void);
void get_status_info (void);
void get_process_info (GtkListStore *);
void get_cpu_info (GString *);
void get_os_info (GString *);
void draw_cpu_load_graph (void);
void draw_mem_load_graph (void);
void prefresh_button_clicked (gpointer data);
void pdelete_button_clicked (gpointer data);
void mrefresh_button_clicked (gpointer data);
void mdelete_button_clicked (gpointer data);
gboolean cpu_configure_event (GtkWidget *, GdkEventConfigure *, gpointer);
gboolean cpu_expose_event (GtkWidget *, GdkEventExpose *, gpointer);
gboolean mem_configure_event (GtkWidget *, GdkEventConfigure *, gpointer);
gboolean mem_expose_event (GtkWidget *, GdkEventExpose *, gpointer);
void show_dialog (gchar *, gchar *);
static GtkItemFactoryEntry menu_items[] = {
{"/_File", NULL, NULL, 0, "<Branch>"},
{"/File/Quit", "<CTRL>Q", destroy_window, 0, "<Item>"},
{"/_Option", NULL, NULL, 0, "<Branch>"},
{"/Option/Shutdown", "<CTRL>U", sys_shutdown, 0 ,"<Item>"},
{"/Option/Reboot", "<CTRL>R", sys_reboot, 0 ,"<Item>"},
{"/Option/Halt", "<CTRL>H", sys_halt, 0 ,"<Item>"},
};
static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
int main (int argc, char **argv)
{
gtk_set_locale ();
gtk_init (&argc, &argv);
memset (cpu_graph, 50, sizeof (cpu_graph)); sizeof(cpu_graph)鐨勭┖闂? memset (mem_graph, 50, sizeof (mem_graph));
memset (pfuser, 0 ,sizeof (pfuser));
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Linux System Moniter"); gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy_window), NULL);
main_vbox =gtk_vbox_new (FALSE, 0);
gtk_widget_show (main_vbox);
gtk_container_add (GTK_CONTAINER (window), main_vbox);
accel_group = gtk_accel_group_new ();
item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR,
"<main>", accel_group);
gtk_item_factory_create_items (item_factory, nmenu_items,
menu_items, NULL);
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
menubar = gtk_item_factory_get_widget (item_factory, "<main>");
gtk_widget_show (menubar);
gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0);
notebook = gtk_notebook_new ();
gtk_widget_show (notebook);
gtk_box_pack_start (GTK_BOX (main_vbox), notebook, FALSE, FALSE, 0);
status_bar = gtk_statusbar_new ();
gtk_widget_show (status_bar);
gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (status_bar),TRUE);
gtk_box_pack_start (GTK_BOX (main_vbox), status_bar, TRUE, FALSE, 0);
gtk_timeout_add (2000, (GtkFunction)handle_timeout, NULL);
gtk_timeout_add (1000, (GtkFunction)load_graph_refresh, NULL);
gtk_timeout_add (1000, (GtkFunction)get_cpu_rate, NULL);
create_process_page ();create_sys_status_page ();
create_sys_info_page ();
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
void destroy_window (GtkWidget *widget, gpointer data) {
gtk_main_quit ();
}
void sys_shutdown (GtkWidget *widget, gpointer data{
system ("shutdown -r now");
}
void sys_reboot (GtkWidget *widget, gpointer data)
{
system ("reboot");
}
void sys_halt (GtkWidget *widget, gpointer data)
system ("halt");
}
gboolean handle_timeout (gpointer data)
{
gint page_num;
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); switch (page_num) {
case 0:
gtk_list_store_clear (process_store);
get_process_info (process_store);
break;
default:
break;
}
return TRUE;
}
gboolean load_graph_refresh (GtkWidget *widget){
draw_cpu_load_graph ();
draw_mem_load_graph ();
return TRUE;
}
gboolean get_cpu_rate ( gpointer data){
int fd,i;
gchar buffer[256];
gchar *cpu_time[9];
gchar *tmp;
gchar *delim = " ";
gdouble cuser;
gdouble ctotal;
fd = open ("/proc/stat", O_RDONLY);
read (fd, buffer, sizeof (buffer));
close (fd);
tmp = strstr (buffer, "cpu0");
tmp--;
*tmp = '\0';
cpu_time[0] = strtok (buffer, delim);
for (i = 1; i < 9 ; i++) {
cpu_time[i] = strtok (NULL, delim);
}
cuser = atoi (cpu_time[1]);
ctotal = (cuser + atoi (cpu_time[2]) + atoi (cpu_time[3]) + atoi (cpu_time[4]));
total = ctotal - ftotal;
rate = (cuser - fuser) / total;
fuser = cuser;
ftotal = ctotal;
return TRUE;
}
void create_sys_status_page (void)
{
vbox = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (notebook), vbox);
frame = gtk_frame_new ("CPU");
gtk_widget_show (frame);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
cpu_draw_area = gtk_drawing_area_new ();
gtk_widget_show (cpu_draw_area);
gtk_drawing_area_size (GTK_DRAWING_AREA (cpu_draw_area), 400, 100);
gtk_container_add (GTK_CONTAINER (frame), cpu_draw_area);
g_signal_connect (cpu_draw_area, "expose_event",
G_CALLBACK (cpu_expose_event), NULL);
g_signal_connect (cpu_draw_area, "configure_event",
G_CALLBACK (cpu_configure_event), NULL);
frame = gtk_frame_new ("Memory");
gtk_widget_show (frame);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 10);
mem_draw_area = gtk_drawing_area_new ();
gtk_widget_show (mem_draw_area);
gtk_drawing_area_size (GTK_DRAWING_AREA (mem_draw_area), 400, 100);
gtk_container_add (GTK_CONTAINER (frame), mem_draw_area);
g_signal_connect (mem_draw_area, "expose_event",
G_CALLBACK (mem_expose_event), NULL);
g_signal_connect (mem_draw_area, "configure_event",
G_CALLBACK (mem_configure_event), NULL);
mem_label = gtk_label_new ("");
gtk_widget_show (mem_label);
gtk_box_pack_start (GTK_BOX (vbox), mem_label, FALSE, FALSE, 0);
swap_label = gtk_label_new ("");//娣诲姞涓€涓爣绛撅紝鏄剧ず椤甸潰浜ゆ崲浣跨敤鎯呭喌
gtk_widget_show (swap_label);
gtk_box_pack_start (GTK_BOX (vbox), swap_label, FALSE, FALSE, 10);
label = gtk_label_new ("Status");//娣诲姞鏍囩浣滀负鏈〉鐨勬爣棰? gtk_widget_show (label);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook),
gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), label);
//澧炲姞鍒扮瑪璁版湰涓鸿椤垫爣绛?}
void create_process_page (void)//鍦ㄧ瑪璁版湰涓坊鍔犺繘绋嬩俊鎭殑椤甸潰
{
int i;
gchar *col_name[5] = { "NAME", "PID" , "STATUS", "CPU" , "MEMORY"};
vbox = gtk_vbox_new (FALSE, 0);//娣诲姞绾靛悜鐩掑瓙
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (notebook), vbox);//鍔犲埌绗旇鏈鍣ㄩ噷
scrolled_window = gtk_scrolled_window_new (NULL, NULL);//娣诲姞婊氬姩绐楀彛鎺т欢
gtk_widget_set_size_request (s
展开阅读全文