This repository was archived by the owner on Mar 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprintk.c
159 lines (136 loc) · 4.19 KB
/
printk.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
* linux/kernel/printk.c
*
* (C) 1991 Linus Torvalds
*/
/*
* When in kernel-mode, we cannot use printf, as fs is liable to
* point to 'interesting' things. Make a printf with fs-saving, and
* all is well.
*/
#include <stdarg.h>
#include <stddef.h>
#include <linux/kernel.h>
#define LOW_MEM 0x100000
#define PAGING_MEMORY (15*1024*1024)
#define PAGING_PAGES (PAGING_MEMORY>>12)
#define MAP_NR(addr) (((addr)-LOW_MEM)>>12)
#define USED 100
static char buf[1024];
extern int vsprintf(char * buf, const char * fmt, va_list args);
int printk(const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=vsprintf(buf,fmt,args);
va_end(args);
__asm__("push %%fs\n\t"
"push %%ds\n\t"
"pop %%fs\n\t"
"pushl %0\n\t"
"pushl $buf\n\t"
"pushl $0\n\t"
"call tty_write\n\t"
"addl $8,%%esp\n\t"
"popl %0\n\t"
"pop %%fs"
::"r" (i):"ax","cx","dx");
return i;
}
#include <linux/sched.h>
#include <sys/stat.h>
static char logbuf[1024];
int fprintk(int fd, const char *fmt, ...)
{
va_list args;
int count;
struct file * file;
struct m_inode * inode;
va_start(args, fmt);
count=vsprintf(logbuf, fmt, args);
va_end(args);
if (fd < 3) //如果输出到stdout或stderr,直接调用sys_write即可
{
__asm__("push %%fs\n\t"
"push %%ds\n\t"
"pop %%fs\n\t"
"pushl %0\n\t"
"pushl $logbuf\n\t" //注意对于Windows环境来说,是_logbuf,下同
"pushl %1\n\t"
"call sys_write\n\t" //注意对于Windows环境来说,是_sys_write,下同
"addl $8,%%esp\n\t"
"popl %0\n\t"
"pop %%fs"
::"r" (count),"r" (fd):"ax","cx","dx");
}
else //假定>=3的描述符都与文件关联。事实上,还存在很多其它情况,这里并没有考虑。
{
if (!(file=task[0]->filp[fd])) //从进程0的文件描述符表中得到文件句柄
return 0;
inode=file->f_inode;
__asm__("push %%fs\n\t"
"push %%ds\n\t"
"pop %%fs\n\t"
"pushl %0\n\t"
"pushl $logbuf\n\t"
"pushl %1\n\t"
"pushl %2\n\t"
"call file_write\n\t"
"addl $12,%%esp\n\t"
"popl %0\n\t"
"pop %%fs"
::"r" (count),"r" (file),"r" (inode):"ax","cx","dx");
}
return count;
}
int f_write_swap(int page)
{
int fd = 7;//swap文件
int count = 4096;//固定一次写一页
struct file * file;
struct m_inode * inode;
char addr[4096];
addr = (page << 12) + LOW_MEM//page页号对应的物理地址(linux0.11内核直接使用物理地址) page=((addr) - LOW_MEM)>>12
if (!(file=task[0]->filp[fd])) //从进程0的文件描述符表中得到文件句柄
return 0;
inode=file->f_inode;
__asm__("push %%fs\n\t" //保存fs寄存器原值(段选择符)
"push %%ds\n\t" //保存ds寄存器原值
"pop %%fs\n\t"
"pushl %0\n\t" //输入四个参数,原型为:int file_write(struct m_inode * inode, struct file * filp, char * buf, int count)
"pushl $logbuf\n\t"
"pushl %1\n\t"
"pushl %2\n\t"
"call file_write\n\t"
"addl $12,%%esp\n\t"
"popl %0\n\t"
"pop %%fs"
::"r" (count),"r" (file),"r" (inode):"ax","cx","dx");
return count;
}
int f_read_swap(int page)
{
int fd = 7;//swap文件
int count = 4096;//固定一次读一页
struct file * file;
struct m_inode * inode;
char addr[4096];
addr = (page << 12) + LOW_MEM//page页号对应的物理地址(linux0.11内核直接使用物理地址) page=((addr) - LOW_MEM)>>12
if (!(file=task[0]->filp[fd])) //从进程0的文件描述符表中得到文件句柄
return 0;
inode=file->f_inode;
__asm__("push %%fs\n\t" //保存fs寄存器原值(段选择符)
"push %%ds\n\t" //保存ds寄存器原值
"pop %%fs\n\t"
"pushl %0\n\t" //输入四个参数,原型为int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
"pushl $addr\n\t"
"pushl %1\n\t"
"pushl %2\n\t"
"call file_read\n\t"
"addl $12,%%esp\n\t"
"popl %0\n\t"
"pop %%fs"
::"r" (count),"r" (file),"r" (inode):"ax","cx","dx");
return count;
}