⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 4.html

📁 网上一个牛人整理的关于linux内核编译
💻 HTML
📖 第 1 页 / 共 5 页
字号:
{<br>
return current-&gt;euid;<br>
}<br>
int sys_getgid(void)<br>
{<br>
return current-&gt;gid;<br>
}<br>
int sys_getegid(void)<br>
{<br>
return current-&gt;egid;<br>
}<br>
int sys_nice(long increment)<br>
{<br>
if (current-&gt;priority-increment&gt;0)<br>
current-&gt;priority -= increment;<br>
return 0;<br>
}<br>
int sys_signal(long signal,long addr,long restorer)<br>
{<br>
long i;<br>
switch (signal) {<br>
case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:<br>
case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:<br>
case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:<br>
case SIGCHLD:<br>
i=(long) current-&gt;sig_fn[signal-1];<br>
current-&gt;sig_fn[signal-1] = (fn_ptr) addr;<br>
current-&gt;sig_restorer = (fn_ptr) restorer;<br>
return i;<br>
default: return -1;<br>
}<br>
}<br>
void sched_init(void)<br>
{<br>
int i;<br>
struct desc_struct * p;<br>
set_tss_desc(gdt+FIRST_TSS_ENTRY,&amp;(init_task.task.tss));@@init task tss<br>
set_ldt_desc(gdt+FIRST_LDT_ENTRY,&amp;(init_task.task.ldt));@@init ldt<br>
p = gdt+2+FIRST_TSS_ENTRY;<br>
for(i=1;i task[i] = NULL;<br>
p-&gt;a=p-&gt;b=0;<br>
p++;<br>
p-&gt;a=p-&gt;b=0;<br>
p++;<br>
}<br>
ltr(0); @@调入task 0的tss<br>
lldt(0); @@调入task 0的ldt<br>
outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */<br>
outb_p(LATCH &amp; 0xff , 0x40); /* LSB */<br>
outb(LATCH &gt;&gt; 8 , 0x40); /* MSB */<br>
set_intr_gate(0x20,&amp;timer_interrupt); @@irq 0 时钟中断<br>
outb(inb_p(0x21)&amp;~0x01,0x21);<br>
set_system_gate(0x80,&amp;system_call);<br>
}<p>
<p>
<br>



<center><A HREF="#Content">[目录]</A></center>
<hr><br><A NAME="I410" ID="I410"></A><center><b><font size=+2>进程信号队列</font></b></center><br>
&nbsp;&nbsp;&nbsp; 每个进程具有一个sigpending结构所描述的信号队列,它有3个成员,head指向第一个sigqueue成员,tail指向最末的sigqueue成员的next指针,signal描述了此队列中的信号集.<p>
static int<br>
send_signal(int sig, struct siginfo *info, struct sigpending *signals);<br>
将信号sig和对应的消息结构info添加到信号队列signal中.<br>
static int<br>
collect_signal(int sig, struct sigpending *list, siginfo_t *info);<br>
返回信号sig在队列list中的信息info.<p>
<br>
struct task_struct {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigpending pending;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
};<br>
struct sigpending {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue *head, **tail;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigset_t signal;<br>
};<br>
struct sigqueue {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue *next;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; siginfo_t info;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>
// kernel/signal.c<br>
static int<br>
send_signal(int sig, struct siginfo *info, struct sigpending *signals)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue * q = NULL;<br>
&nbsp;&nbsp;&nbsp;&nbsp; /* Real-time signals must be queued if sent by sigqueue, or<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; some other real-time mechanism.&nbsp; It is implementation<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defined whether kill() does so.&nbsp; We attempt to do so, on<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the principle of least surprise, but since kill is not<br>
&nbsp;&nbsp;&nbsp;&nbsp; allowed to fail with EAGAIN when low on memory we just<br>
&nbsp;&nbsp;&nbsp;&nbsp; make sure at least one signal gets delivered and don't<br>
&nbsp;&nbsp;&nbsp;&nbsp; pass on the info struct.&nbsp; */<p>
&nbsp;&nbsp;&nbsp; if (atomic_read(&amp;nr_queued_signals) &lt; max_queued_signals) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; // nr_queued_signals和max_queued_signals用来限制全局sigqueue成员的数目<br>
&nbsp;&nbsp;&nbsp; if (q) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; atomic_inc(&amp;nr_queued_signals);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;next = NULL;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *signals-&gt;tail = q;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signals-&gt;tail = &amp;q-&gt;next; tail总是指向最末的信号成员的next指针&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch ((unsign<br>
ed long) info)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 0:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // info参数如果为0,表示信号来源于当前用户进程&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_signo =<br>
sig;<br>
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_errno = 0;<br>
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_code = SI_USER;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_pid = current-&gt;pid;<br>
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_uid = current-&gt;uid;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // info参数如果为1,表示信号来源于内核本身&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_signo = sig;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_errno = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_code = SI_KERNEL;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;info.si_pid = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; q-&gt;info.si_uid = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 否则从info指针中拷贝信号<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy_siginfo(&amp;q-&gt;info, info);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (sig &gt;= SIGRTMIN &amp;&amp; info &amp;&amp; (unsigned long)info != 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &amp;&amp; info-&gt;<br>
si_code != SI_USER)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 如果该信号是内核发出的实时信号,就返回错误码<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Queue overflow, abort.&nbsp; We may abort if the signal was rt<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * and sent by user using something other than kill().<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EAGAIN;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigaddset(&amp;signals-&gt;signal, sig); 将sig号标记在队列的信号集上<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
static int<br>
collect_signal(int sig, struct sigpending *list, siginfo_t *info)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sigismember(&amp;list-&gt;signal, sig)) {<br>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Collect the siginfo appropriate to this signal.&nbsp; */&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigqueue *q, **<br>
pp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pp = &amp;list-&gt;head; pp指向第一个信号成员的next指针<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((q = *pp) != NULL) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (q-&gt;info.si_signo == sig)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto found_it;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pp = &amp;q-&gt;next;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Ok, it wasn't in the queue.&nbsp; We must have<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; been out of queue space.&nbsp; So zero out the<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigdelset(&amp;list-&gt;signal, sig);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_signo = sig;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_errno = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_code = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_pid = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;si_uid = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp; found_it:<br>
&nbsp;&nbsp; // 将找到信号成员从信号队列中删除<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((*pp = q-&gt;next) == NULL)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list-&gt;tail = pp;<br>
&nbsp; /* Copy the sigqueue information and free the queue entry */<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy_siginfo(info, &amp;q-&gt;info);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kmem_cache_free(sigqueue_cachep,q);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; atomic_dec(&amp;nr_queued_signals);<br>
&nbsp; /* Non-RT signals can exist multiple times.. */<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sig &gt;= SIGRTMIN) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((q = *pp) != NULL) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (q-&gt;info.si_signo == sig)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; goto found_another;<br>
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; pp = &amp;q-&gt;next;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigdelset(&amp;list-&gt;signal, sig);<br>
&nbsp;&nbsp;&nbsp; found_another:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<p>
<p>
<p>



<center><A HREF="#Content">[目录]</A></center>
<hr><br><A NAME="I411" ID="I411"></A><center><b><font size=+2>SMP</font></b></center><br>
&nbsp;&nbsp;&nbsp; 多处理机系统正在变得越来越普通。尽管大多数用户空间代码仍将完美地运行,而且有些情况下不需要增加额外的代码就能利用SMP特性的优势,但是内核空间代码必须编写成具备“SMP意识”且是“SMP安全的”。以下几段文字解释如何去做。<p>
问题<p>
&nbsp;&nbsp;&nbsp; 当有多个CPU时,同样的代码可能同时在两个或多个CPU上执行。这在如下所示用于初始化某个图像设备的例程中可能会出问题。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void init_hardware(void)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outb(0x1, hardware_base + 0x30);<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -