315 lines
17 KiB
HTML
315 lines
17 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en" dir="auto">
|
||
|
||
<head><meta charset="utf-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||
<meta name="robots" content="index, follow">
|
||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||
<title>Kernel, Process creation | Morgan's Blog</title>
|
||
<meta name="keywords" content="">
|
||
<meta name="description" content="Linux Kernel #3">
|
||
<meta name="author" content="Me">
|
||
<link rel="canonical" href="http://blog.morgan.kr/2023/11/kernel-process-creation/">
|
||
|
||
<script type="text/javascript">
|
||
let vh = window.innerHeight * 0.01;
|
||
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||
</script>
|
||
<link crossorigin="anonymous" href="/assets/css/stylesheet.dde9171333af37b8e856933e0deb815c09f761bbd3ee0e6826d3a1309b808533.css" integrity="sha256-3ekXEzOvN7joVpM+DeuBXAn3YbvT7g5oJtOhMJuAhTM=" rel="preload stylesheet" as="style">
|
||
<script defer crossorigin="anonymous" src="/assets/js/highlight.f413e19d0714851f6474e7ee9632408e58ac146fbdbe62747134bea2fa3415e0.js" integrity="sha256-9BPhnQcUhR9kdOfuljJAjlisFG+9vmJ0cTS+ovo0FeA="
|
||
onload="hljs.initHighlightingOnLoad();"></script>
|
||
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body);"></script>
|
||
<script>
|
||
document.addEventListener("DOMContentLoaded", function() {
|
||
renderMathInElement(document.body, {
|
||
delimiters: [
|
||
{left: "$$", right: "$$", display: true},
|
||
{left: "$", right: "$", display: false}
|
||
]
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<link rel="icon" href="https://blog.morgan.kr/favicon.ico">
|
||
|
||
<meta name="theme-color" content="#2e2e33">
|
||
<meta name="msapplication-TileColor" content="#2e2e33">
|
||
<noscript>
|
||
<style>
|
||
#theme-toggle,
|
||
.top-link {
|
||
display: none;
|
||
}
|
||
|
||
</style>
|
||
</noscript><meta property="og:title" content="Kernel, Process creation" />
|
||
<meta property="og:description" content="Linux Kernel #3" />
|
||
<meta property="og:type" content="article" />
|
||
<meta property="og:url" content="http://blog.morgan.kr/2023/11/kernel-process-creation/" /><meta property="article:section" content="posts" />
|
||
<meta property="article:published_time" content="2023-11-26T07:44:51+00:00" />
|
||
<meta property="article:modified_time" content="2023-11-26T07:44:51+00:00" /><meta property="og:site_name" content="Morgan's Blog" />
|
||
|
||
<meta name="twitter:card" content="summary"/>
|
||
<meta name="twitter:title" content="Kernel, Process creation"/>
|
||
<meta name="twitter:description" content="Linux Kernel #3"/>
|
||
|
||
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "BreadcrumbList",
|
||
"itemListElement": [,
|
||
{
|
||
"@type": "ListItem",
|
||
"position": 2 ,
|
||
"name": "Posts",
|
||
"item": "http://blog.morgan.kr/posts/"
|
||
},
|
||
{
|
||
"@type": "ListItem",
|
||
"position": 3 ,
|
||
"name": "Kernel, Process creation",
|
||
"item": "http://blog.morgan.kr/2023/11/kernel-process-creation/"
|
||
}
|
||
]
|
||
}
|
||
</script>
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "BlogPosting",
|
||
"headline": "Kernel, Process creation",
|
||
"name": "Kernel, Process creation",
|
||
"description": "Linux Kernel #3",
|
||
"keywords": [
|
||
|
||
],
|
||
"articleBody": "static int init(void * unused) { lock_kernel(); do_basic_setup(); /* * Ok, we have completed the initial bootup, and * we're essentially up and running. Get rid of the * initmem segments and start the user-mode stuff.. */ free_initmem(); unlock_kernel(); if (open(\"/dev/console\", O_RDWR, 0) \u003c 0) printk(\"Warning: unable to open an initial console.\\n\"); (void) dup(0); (void) dup(0); /* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */ if (execute_command) execve(execute_command,argv_init,envp_init); execve(\"/sbin/init\",argv_init,envp_init); execve(\"/etc/init\",argv_init,envp_init); execve(\"/bin/init\",argv_init,envp_init); execve(\"/bin/sh\",argv_init,envp_init); panic(\"No init found. Try passing init= option to kernel.\"); } In this init/main.c, after basic kernel initialization things, open(\"/dev/console\") and two dup(0) opens three file descriptor 0, 1, 2 as stdin, stdout, stderr. Later when execve() or fork() happens, it simply copies calling process’s task_struct as process context, so all file descriptors are also passed down as-is.\nAll processes’ file descriptor 0, 1, 2 originates to init’s file descriptor.\nIf calling process opens PTY or TTY, which is common when we opens new terminal to run a process, it is also passed down to exec/forked process.\n",
|
||
"wordCount" : "192",
|
||
"inLanguage": "en",
|
||
"datePublished": "2023-11-26T07:44:51.449Z",
|
||
"dateModified": "2023-11-26T07:44:51.449Z",
|
||
"author":{
|
||
"@type": "Person",
|
||
"name": "Me"
|
||
},
|
||
"mainEntityOfPage": {
|
||
"@type": "WebPage",
|
||
"@id": "http://blog.morgan.kr/2023/11/kernel-process-creation/"
|
||
},
|
||
"publisher": {
|
||
"@type": "Organization",
|
||
"name": "Morgan's Blog",
|
||
"logo": {
|
||
"@type": "ImageObject",
|
||
"url": "https://blog.morgan.kr/favicon.ico"
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
</head>
|
||
|
||
<body class=" dark" id="top"><header class="header">
|
||
</header>
|
||
<script>
|
||
if (localStorage.getItem("pref-theme") === "light") {
|
||
document.body.classList.remove('dark')
|
||
document.getElementById('main-logo').src = "\/favicon-inv.png";
|
||
}
|
||
|
||
</script>
|
||
<main class="main">
|
||
|
||
<article class="post-single">
|
||
|
||
<header class="post-header">
|
||
<h1 class="post-title">
|
||
Kernel, Process creation
|
||
</h1>
|
||
<div class="post-description">
|
||
Linux Kernel #3
|
||
</div>
|
||
|
||
<div class="post-meta"><span title='2023-11-26 07:44:51.449 +0000 UTC'>
|
||
Nov 26, 2023
|
||
</span>
|
||
</div>
|
||
</header>
|
||
<div class="post-divider"></div>
|
||
<div class="post-content"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kt">int</span> <span class="nf">init</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span> <span class="n">unused</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">{</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">lock_kernel</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">do_basic_setup</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="cm">/*
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Ok, we have completed the initial bootup, and
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> * we're essentially up and running. Get rid of the
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> * initmem segments and start the user-mode stuff..
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">free_initmem</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">unlock_kernel</span><span class="p">();</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nf">open</span><span class="p">(</span><span class="s">"/dev/console"</span><span class="p">,</span> <span class="n">O_RDWR</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">printk</span><span class="p">(</span><span class="s">"Warning: unable to open an initial console.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">dup</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">dup</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="cm">/*
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> * We try each of these until one succeeds.
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> * The Bourne shell can be used instead of init if we are
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> * trying to recover a really broken machine.
|
||
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
|
||
</span></span><span class="line"><span class="cl">
|
||
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="n">execute_command</span><span class="p">)</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">execve</span><span class="p">(</span><span class="n">execute_command</span><span class="p">,</span><span class="n">argv_init</span><span class="p">,</span><span class="n">envp_init</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">execve</span><span class="p">(</span><span class="s">"/sbin/init"</span><span class="p">,</span><span class="n">argv_init</span><span class="p">,</span><span class="n">envp_init</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">execve</span><span class="p">(</span><span class="s">"/etc/init"</span><span class="p">,</span><span class="n">argv_init</span><span class="p">,</span><span class="n">envp_init</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">execve</span><span class="p">(</span><span class="s">"/bin/init"</span><span class="p">,</span><span class="n">argv_init</span><span class="p">,</span><span class="n">envp_init</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">execve</span><span class="p">(</span><span class="s">"/bin/sh"</span><span class="p">,</span><span class="n">argv_init</span><span class="p">,</span><span class="n">envp_init</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"> <span class="nf">panic</span><span class="p">(</span><span class="s">"No init found. Try passing init= option to kernel."</span><span class="p">);</span>
|
||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||
</span></span></code></pre></div><p>In this <code>init/main.c</code>, after basic kernel initialization things, <code>open("/dev/console")</code> and two <code>dup(0)</code> opens three file descriptor 0, 1, 2 as stdin, stdout, stderr. Later when <code>execve()</code> or <code>fork()</code> happens, it simply copies calling process’s <code>task_struct</code> as process context, so all file descriptors are also passed down as-is.</p>
|
||
<p>All processes’ file descriptor 0, 1, 2 originates to <code>init</code>’s file descriptor.</p>
|
||
<p>If calling process opens PTY or TTY, which is common when we opens new terminal to run a process, it is also passed down to exec/forked process.</p>
|
||
|
||
|
||
</div>
|
||
|
||
<footer class="post-footer">
|
||
<ul class="post-tags">
|
||
</ul>
|
||
<nav class="pag-back">
|
||
<a href="#back" onclick="window.history.back()">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;fill: var(--primary);stroke: var(--primary);" stroke-width="1"><polygon points="11.65,3.50 3.80,11.35 11.65,19.20 12.36,18.50 5.71,11.85 20.15,11.85 20.15,10.85 5.71,10.85 12.36,4.20"></polygon></svg>
|
||
</a>
|
||
</nav>
|
||
<br/>
|
||
</footer>
|
||
</article>
|
||
</main>
|
||
|
||
<footer class="footer">
|
||
<a href="/admin/" style="text-decoration: none;">©</a> <span><a href="http://blog.morgan.kr">Morgan</a> · PaperMod</span>
|
||
<br/>
|
||
<span style="">Ver.11081623 </span>
|
||
<a href="#" id="theme-toggle">Toggle Dark Mode</a>
|
||
</footer>
|
||
<button id="top-link" class="top-link" onclick="window.scrollTo({top: 0, behavior: 'smooth'})">
|
||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;" fill="currentColor" stroke="white" stroke-width="1"><polygon points="19.35,11.5 11.5,3.65 3.65,11.5 4.35,12.21 11,5.56 11,20 12,20 12,5.56 18.65,12.21"></polygon></svg>
|
||
</button>
|
||
|
||
<script>
|
||
let menu = document.getElementById('menu')
|
||
if (menu) {
|
||
menu.scrollLeft = localStorage.getItem("menu-scroll-position");
|
||
menu.onscroll = function () {
|
||
localStorage.setItem("menu-scroll-position", menu.scrollLeft);
|
||
}
|
||
}
|
||
|
||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||
anchor.addEventListener("click", function (e) {
|
||
e.preventDefault();
|
||
var id = this.getAttribute("href").substr(1);
|
||
if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
|
||
behavior: "smooth"
|
||
});
|
||
} else {
|
||
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
|
||
}
|
||
if (id === "top") {
|
||
history.replaceState(null, null, " ");
|
||
} else {
|
||
history.pushState(null, null, `#${id}`);
|
||
}
|
||
});
|
||
});
|
||
|
||
</script>
|
||
<script>
|
||
var mybutton = document.getElementById("top-link");
|
||
window.onscroll = function () {
|
||
if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
|
||
mybutton.style.visibility = "visible";
|
||
mybutton.style.opacity = "1";
|
||
} else {
|
||
mybutton.style.visibility = "hidden";
|
||
mybutton.style.opacity = "0";
|
||
}
|
||
};
|
||
|
||
</script>
|
||
<script>
|
||
document.getElementById("theme-toggle").addEventListener("click", () => {
|
||
if (document.body.className.includes("dark")) {
|
||
document.body.classList.remove('dark');
|
||
localStorage.setItem("pref-theme", 'light');
|
||
document.getElementById('main-logo').src = "\/favicon-inv.png";
|
||
|
||
} else {
|
||
document.body.classList.add('dark');
|
||
localStorage.setItem("pref-theme", 'dark');
|
||
document.getElementById('main-logo').src = "\/favicon.png";
|
||
|
||
}
|
||
})
|
||
|
||
</script>
|
||
<script>
|
||
document.querySelectorAll('pre > code').forEach((codeblock) => {
|
||
const container = codeblock.parentNode.parentNode;
|
||
|
||
const copybutton = document.createElement('button');
|
||
copybutton.classList.add('copy-code');
|
||
copybutton.innerHTML = 'copy';
|
||
|
||
function copyingDone() {
|
||
copybutton.innerHTML = 'copied!';
|
||
setTimeout(() => {
|
||
copybutton.innerHTML = 'copy';
|
||
}, 2000);
|
||
}
|
||
|
||
copybutton.addEventListener('click', (cb) => {
|
||
if ('clipboard' in navigator) {
|
||
navigator.clipboard.writeText(codeblock.textContent);
|
||
copyingDone();
|
||
return;
|
||
}
|
||
|
||
const range = document.createRange();
|
||
range.selectNodeContents(codeblock);
|
||
const selection = window.getSelection();
|
||
selection.removeAllRanges();
|
||
selection.addRange(range);
|
||
try {
|
||
document.execCommand('copy');
|
||
copyingDone();
|
||
} catch (e) { };
|
||
selection.removeRange(range);
|
||
});
|
||
|
||
if (container.classList.contains("highlight")) {
|
||
container.appendChild(copybutton);
|
||
} else if (container.parentNode.firstChild == container) {
|
||
|
||
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
|
||
|
||
codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
|
||
} else {
|
||
|
||
codeblock.parentNode.appendChild(copybutton);
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|