291 lines
12 KiB
HTML
291 lines
12 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, Bootloader | Morgan's Blog</title>
|
|
<meta name="keywords" content="">
|
|
<meta name="description" content="Linux Kernel #2">
|
|
<meta name="author" content="Me">
|
|
<link rel="canonical" href="http://blog.morgan.kr/2023/11/kernel-bootloader/">
|
|
|
|
<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, Bootloader" />
|
|
<meta property="og:description" content="Linux Kernel #2" />
|
|
<meta property="og:type" content="article" />
|
|
<meta property="og:url" content="http://blog.morgan.kr/2023/11/kernel-bootloader/" /><meta property="article:section" content="posts" />
|
|
<meta property="article:published_time" content="2023-11-22T05:35:09+00:00" />
|
|
<meta property="article:modified_time" content="2023-11-22T05:35:09+00:00" /><meta property="og:site_name" content="Morgan's Blog" />
|
|
|
|
<meta name="twitter:card" content="summary"/>
|
|
<meta name="twitter:title" content="Kernel, Bootloader"/>
|
|
<meta name="twitter:description" content="Linux Kernel #2"/>
|
|
|
|
|
|
<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, Bootloader",
|
|
"item": "http://blog.morgan.kr/2023/11/kernel-bootloader/"
|
|
}
|
|
]
|
|
}
|
|
</script>
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@type": "BlogPosting",
|
|
"headline": "Kernel, Bootloader",
|
|
"name": "Kernel, Bootloader",
|
|
"description": "Linux Kernel #2",
|
|
"keywords": [
|
|
|
|
],
|
|
"articleBody": "부트로더가 하는 일은\nCPU 초기화 IVT 초기화 하드웨어 초기화 및 커널 찾기 (외부 메모리 인터페이스 초기화 및 파일시스템 인식 과정) 커널을 메모리에 올리고 커널 Entry로 점프 인데, 여기서 부트로더가 커널을 메모리에 올릴때 어디에 어떻게 올리냐가 헷갈렸다.\n컴파일 된 커널을 보면 relative 주소로 되어 있는데, 부트로더가 커널의 .data랑 .bss를 다른 프로세스처럼 적절한 곳에 따로 두는 걸로 착각했다. 당연히 부트로더 단계에서는 메모리 매핑이나 페이징이 아직 없고, 커널은 메모리에 매핑이 된게 아니라 고정된 주소에 있어야 한다.\n커널은 PIC(Position Independant Code)인데, `.text`, `.data`, `.bss`가 정해진 offset 차이로 고정되어 메모리에 올라가기 때문에 동적 주소 매핑 없이 base address에 relative 하게 모든 section의 위치를 알 수 있다.\n생각해보면 간단하고 당연한 거였다.\n그리고 외부적 인터럽트나 시스템 콜 없이 프로세스가 context를 계속 잡고 있으면 다시 커널로 돌아올 방법이 없다. timed inturrupt나 watchdog이 필요하다.\n* 부트로더 단계에서 MMU 초기화 하고 페이징 하는 복잡한 시스템이 아니라 임베디드 ARM 환경에서의 이야기다. UEFI나 모던 시스템에서는 다를거다.\n",
|
|
"wordCount" : "144",
|
|
"inLanguage": "en",
|
|
"datePublished": "2023-11-22T05:35:09.645Z",
|
|
"dateModified": "2023-11-22T05:35:09.645Z",
|
|
"author":{
|
|
"@type": "Person",
|
|
"name": "Me"
|
|
},
|
|
"mainEntityOfPage": {
|
|
"@type": "WebPage",
|
|
"@id": "http://blog.morgan.kr/2023/11/kernel-bootloader/"
|
|
},
|
|
"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, Bootloader
|
|
</h1>
|
|
<div class="post-description">
|
|
Linux Kernel #2
|
|
</div>
|
|
|
|
<div class="post-meta"><span title='2023-11-22 05:35:09.645 +0000 UTC'>
|
|
Nov 22, 2023
|
|
</span>
|
|
</div>
|
|
</header>
|
|
<div class="post-divider"></div>
|
|
<div class="post-content"><p>부트로더가 하는 일은</p>
|
|
<ol>
|
|
<li>CPU 초기화</li>
|
|
<li>IVT 초기화</li>
|
|
<li>하드웨어 초기화 및 커널 찾기 (외부 메모리 인터페이스 초기화 및 파일시스템 인식 과정)</li>
|
|
<li>커널을 메모리에 올리고 커널 Entry로 점프</li>
|
|
</ol>
|
|
<p>인데, 여기서 부트로더가 커널을 메모리에 올릴때 어디에 어떻게 올리냐가 헷갈렸다.</p>
|
|
<p>컴파일 된 커널을 보면 relative 주소로 되어 있는데, 부트로더가 커널의 .data랑 .bss를 다른 프로세스처럼 적절한 곳에 따로 두는 걸로 착각했다. 당연히 부트로더 단계에서는 메모리 매핑이나 페이징이 아직 없고, 커널은 메모리에 매핑이 된게 아니라 고정된 주소에 있어야 한다.</p>
|
|
<p>커널은 PIC(Position Independant Code)인데, `.text`, `.data`, `.bss`가 정해진 offset 차이로 고정되어 메모리에 올라가기 때문에 동적 주소 매핑 없이 base address에 relative 하게 모든 section의 위치를 알 수 있다.</p>
|
|
<p>생각해보면 간단하고 당연한 거였다.</p>
|
|
<p>그리고 외부적 인터럽트나 시스템 콜 없이 프로세스가 context를 계속 잡고 있으면 다시 커널로 돌아올 방법이 없다. timed inturrupt나 watchdog이 필요하다.</p>
|
|
<p>* 부트로더 단계에서 MMU 초기화 하고 페이징 하는 복잡한 시스템이 아니라 임베디드 ARM 환경에서의 이야기다. UEFI나 모던 시스템에서는 다를거다.</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>
|