Files
CoderSherlock.github.io/_site/posts/intro-xv6.html
T
2024-04-13 21:06:39 +00:00

1201 lines
55 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>Xv6 introduction - STSD</title>
<meta name="description" content="In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching...">
<link rel="canonical" href="https://blog.pengzhan.dev/posts/intro-xv6"><link rel="alternate" type="application/rss+xml" title="STSD" href="/feed.xml"><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
<link rel="manifest" href="/assets/site.webmanifest">
<link rel="mask-icon" href="/assets/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="/assets/favicon.ico">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-config" content="/assets/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="/static/2022-09/all.css" >
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto+Slab:wght@100..900&family=ZCOOL+XiaoWei&display=swap')
</style><!-- start custom head snippets -->
<!-- Begin Jekyll SEO tag v2.8.0 -->
<title>Xv6 introduction | STSD</title>
<meta name="generator" content="Jekyll v4.2.2" />
<meta property="og:title" content="Xv6 introduction" />
<meta name="author" content="Pengzhan Hao" />
<meta property="og:locale" content="en" />
<meta name="description" content="In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching OS classes. Understand system call and know how to implement a simple one will be coved as the first half. In the second half of this post, I will discuss a little bit more on how to debug xv6 using gdb." />
<meta property="og:description" content="In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching OS classes. Understand system call and know how to implement a simple one will be coved as the first half. In the second half of this post, I will discuss a little bit more on how to debug xv6 using gdb." />
<link rel="canonical" href="https://blog.pengzhan.dev/posts/intro-xv6" />
<meta property="og:url" content="https://blog.pengzhan.dev/posts/intro-xv6" />
<meta property="og:site_name" content="STSD" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2017-07-28T14:56:55-04:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Xv6 introduction" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Pengzhan Hao"},"dateModified":"2021-12-11T13:35:39-05:00","datePublished":"2017-07-28T14:56:55-04:00","description":"In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching OS classes. Understand system call and know how to implement a simple one will be coved as the first half. In the second half of this post, I will discuss a little bit more on how to debug xv6 using gdb.","headline":"Xv6 introduction","mainEntityOfPage":{"@type":"WebPage","@id":"https://blog.pengzhan.dev/posts/intro-xv6"},"url":"https://blog.pengzhan.dev/posts/intro-xv6"}</script>
<!-- End Jekyll SEO tag -->
<!-- end custom head snippets -->
<script>(function() {
window.isArray = function(val) {
return Object.prototype.toString.call(val) === '[object Array]';
};
window.isString = function(val) {
return typeof val === 'string';
};
window.hasEvent = function(event) {
return 'on'.concat(event) in window.document;
};
window.isOverallScroller = function(node) {
return node === document.documentElement || node === document.body || node === window;
};
window.isFormElement = function(node) {
var tagName = node.tagName;
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
};
window.pageLoad = (function () {
var loaded = false, cbs = [];
window.addEventListener('load', function () {
var i;
loaded = true;
if (cbs.length > 0) {
for (i = 0; i < cbs.length; i++) {
cbs[i]();
}
}
});
return {
then: function(cb) {
cb && (loaded ? cb() : (cbs.push(cb)));
}
};
})();
})();
(function() {
window.throttle = function(func, wait) {
var args, result, thisArg, timeoutId, lastCalled = 0;
function trailingCall() {
lastCalled = new Date;
timeoutId = null;
result = func.apply(thisArg, args);
}
return function() {
var now = new Date,
remaining = wait - (now - lastCalled);
args = arguments;
thisArg = this;
if (remaining <= 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastCalled = now;
result = func.apply(thisArg, args);
} else if (!timeoutId) {
timeoutId = setTimeout(trailingCall, remaining);
}
return result;
};
};
})();
(function() {
var Set = (function() {
var add = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (data[i] === item) {
return;
}
}
this.size ++;
data.push(item);
return data;
};
var Set = function(data) {
this.size = 0;
this._data = [];
var i;
if (data.length > 0) {
for (i = 0; i < data.length; i++) {
add.call(this, data[i]);
}
}
};
Set.prototype.add = add;
Set.prototype.get = function(index) { return this._data[index]; };
Set.prototype.has = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (this.get(i) === item) {
return true;
}
}
return false;
};
Set.prototype.is = function(map) {
if (map._data.length !== this._data.length) { return false; }
var i, j, flag, tData = this._data, mData = map._data;
for (i = 0; i < tData.length; i++) {
for (flag = false, j = 0; j < mData.length; j++) {
if (tData[i] === mData[j]) {
flag = true;
break;
}
}
if (!flag) { return false; }
}
return true;
};
Set.prototype.values = function() {
return this._data;
};
return Set;
})();
window.Lazyload = (function(doc) {
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
var createNode = function(name, attrs) {
var node = doc.createElement(name), attr;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
}
return node;
};
var end = function(type, url) {
var s, q, qi, cbs, i, j, cur, val, flag;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
s[url] = true;
for (i = 0; i < q.length; i++) {
cur = q[i];
if (cur.urls.has(url)) {
qi = cur, val = qi.urls.values();
qi && (cbs = qi.callbacks);
for (flag = true, j = 0; j < val.length; j++) {
cur = val[j];
if (!s[cur]) {
flag = false;
}
}
if (flag && cbs && cbs.length > 0) {
for (j = 0; j < cbs.length; j++) {
cbs[j].call(context);
}
qi.load = true;
}
}
}
}
};
var load = function(type, urls, callback) {
var s, q, qi, node, i, cur,
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
for (i = 0; i < q.length; i++) {
cur = q[i];
if (_urls.is(cur.urls)) {
qi = cur;
break;
}
}
val = _urls.values();
if (qi) {
callback && (qi.load || qi.callbacks.push(callback));
callback && (qi.load && callback());
} else {
q.push({
urls: _urls,
callbacks: callback ? [callback] : [],
load: false
});
for (i = 0; i < val.length; i++) {
node = null, url = val[i];
if (s[url] === undefined) {
(type === 'js' ) && (node = createNode('script', { src: url }));
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
if (node) {
node.onload = (function(type, url) {
return function() {
end(type, url);
};
})(type, url);
(doc.head || doc.body).appendChild(node);
s[url] = false;
}
}
}
}
}
};
return {
js: function(url, callback) {
load('js', url, callback);
},
css: function(url, callback) {
load('css', url, callback);
}
};
})(this.document);
})();
</script><script>
(function() {
var TEXT_VARIABLES = {
version: '2.2.6',
sources: {
font_awesome: '/static/2022-09/all.css',
jquery: '/static/2022-09/jquery.min.js',
leancloud_js_sdk: '/static/2022-09/av-min.js',
chart: '/static/2022-09/Chart.bundle.min.js',
gitalk: {
js: '/static/2022-09/gitalk.min.js',
css: '/static/2022-09/gitalk.min.css'
},
valine: '/static/2022-09/Valine.min.js',
mathjax: '/static/2022-09/MathJax.js?config=TeX-MML-AM_CHTML',
mermaid: '/static/2022-09/mermaid.min.js'
},
site: {
toc: {
selectors: 'h1,h2,h3'
}
},
paths: {
search_js: '/assets/search.js'
}
};
window.TEXT_VARIABLES = TEXT_VARIABLES;
})();
</script>
</head>
<body>
<div class="root" data-is-touch="false">
<div class="layout--page js-page-root"><div class="page__main js-page-main page__viewport has-aside cell cell--auto">
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
<div class="header__title">
<div class="header__brand">
<!--<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="231.000000pt" height="218.000000pt" viewBox="0 0 231.000000 218.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.16, written by Peter Selinger 2001-2019
</metadata>
<g transform="translate(0.000000,218.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1754 2168 c-3 -4 -2 -8 3 -8 4 0 3 -4 -4 -8 -6 -4 -13 -23 -16 -42
-4 -19 -14 -41 -24 -49 -17 -12 -16 -13 6 -8 l25 6 -27 -25 c-31 -29 -33 -34
-11 -34 8 0 12 5 9 10 -3 6 -2 10 4 10 5 0 13 -5 16 -10 4 -6 12 -7 18 -4 8 5
8 3 0 -7 -7 -7 -13 -21 -13 -32 0 -10 -4 -16 -9 -13 -14 9 -7 -18 11 -45 l16
-24 16 39 c9 21 16 44 16 51 0 6 3 15 8 19 4 4 7 11 8 14 0 4 4 23 9 42 9 36
11 46 13 68 1 7 6 11 11 8 4 -3 6 5 4 18 -4 17 0 26 14 29 10 3 -8 5 -40 4
-32 0 -60 -4 -63 -9z"/>
<path d="M1936 2163 c-4 -9 -2 -20 5 -23 14 -9 14 -21 -1 -30 -8 -5 -2 -10 14
-14 15 -4 24 -11 21 -17 -4 -5 -15 -7 -26 -4 -13 5 -19 2 -19 -10 0 -9 7 -15
17 -13 14 3 17 -6 18 -52 1 -30 3 -60 7 -65 3 -6 4 -23 2 -40 -1 -16 -5 -62
-8 -102 -2 -39 -7 -80 -10 -90 -4 -12 3 -28 19 -45 14 -15 21 -30 15 -33 -6
-4 -4 -17 5 -36 9 -16 13 -34 10 -39 -3 -6 1 -10 9 -10 22 0 20 -30 -1 -31
-14 0 -15 -2 -3 -6 22 -9 42 -32 36 -42 -3 -5 -17 -11 -31 -13 -14 -3 -22 -1
-18 5 7 12 -16 27 -42 27 -19 -1 -19 -1 -2 -14 16 -12 16 -15 3 -29 -14 -13
-14 -16 0 -21 13 -5 14 -9 4 -21 -8 -10 -9 -15 -2 -15 6 0 9 -6 6 -13 -2 -7 2
-26 10 -42 8 -16 13 -32 10 -37 -3 -4 0 -8 5 -8 6 0 11 -7 11 -15 0 -8 5 -15
12 -15 6 0 3 -10 -8 -21 -19 -22 -19 -22 5 -14 16 5 21 4 17 -4 -5 -7 -1 -8
10 -4 12 5 15 3 9 -6 -6 -10 -2 -11 16 -7 19 6 21 5 8 -3 -20 -13 -66 -9 -98
8 -15 9 -21 9 -16 2 3 -6 -4 -20 -17 -31 -16 -14 -18 -18 -5 -14 12 4 17 1 17
-11 0 -14 -6 -16 -30 -11 -38 7 -39 -1 -2 -15 24 -9 25 -11 9 -20 -9 -6 -15
-14 -12 -20 4 -5 -2 -9 -12 -9 -10 0 -25 -5 -33 -11 -13 -10 -13 -10 1 -6 9 3
16 -1 16 -9 0 -12 -3 -12 -21 0 -17 10 -21 25 -22 65 -1 29 -7 58 -14 64 -10
9 -11 9 -5 -3 6 -10 1 -8 -13 4 -12 10 -19 22 -17 26 3 4 -2 11 -11 14 -8 3
-12 10 -9 16 3 6 -1 13 -10 16 -10 4 -15 14 -12 25 3 10 -2 19 -12 22 -26 6
-39 -3 -34 -24 6 -23 -13 -49 -37 -49 -10 0 -27 11 -38 25 -24 30 -32 31 -32
4 0 -16 -4 -19 -21 -14 -15 5 -19 4 -14 -5 5 -8 0 -7 -14 2 -14 9 -20 22 -19
40 1 16 6 28 11 28 5 0 3 7 -4 16 -8 9 -12 27 -11 40 7 52 -18 131 -54 168
-40 42 -76 50 -182 44 -86 -5 -133 -24 -174 -72 -23 -26 -27 -40 -28 -94 0
-66 17 -113 47 -132 17 -10 17 -10 -1 -8 -10 2 -21 -3 -24 -11 -3 -10 0 -12
13 -7 15 5 16 4 5 -9 -10 -12 -10 -15 3 -15 8 0 17 9 20 21 3 12 10 18 16 14
8 -4 6 -11 -4 -21 -8 -9 -13 -19 -10 -24 3 -4 -5 -6 -17 -4 -21 4 -21 4 -3 -5
15 -7 24 -4 37 13 21 25 22 20 7 -22 -6 -18 -14 -30 -19 -27 -4 2 -15 -4 -24
-14 -17 -18 -16 -19 18 -18 20 1 36 4 36 8 0 4 7 9 15 13 13 5 13 2 -1 -19
-13 -20 -20 -23 -34 -15 -15 8 -22 5 -33 -10 -12 -17 -16 -18 -20 -6 -4 9 -14
12 -26 9 -13 -3 -21 -1 -21 8 0 7 -3 10 -6 7 -3 -4 -1 -15 4 -25 6 -11 7 -25
3 -32 -6 -8 -10 -2 -14 18 -8 36 -22 40 -38 9 -10 -18 -9 -20 5 -15 9 4 16 1
16 -4 0 -7 -11 -9 -25 -7 -13 3 -26 0 -29 -6 -3 -7 -5 -6 -5 2 -1 7 -7 10 -13
7 -7 -4 -4 2 8 12 19 16 39 53 29 53 -2 0 -17 -14 -33 -31 l-30 -32 5 27 c4
20 1 26 -11 26 -11 0 -15 -5 -10 -12 4 -7 -2 -5 -13 4 -11 10 -27 18 -36 18
-9 0 -21 8 -27 18 -9 14 -10 11 -5 -15 5 -24 2 -34 -12 -43 -16 -10 -15 -10 5
-4 23 6 24 6 5 -14 -18 -19 -18 -19 -52 0 -33 19 -34 19 -28 -1 5 -19 3 -19
-18 -5 -26 17 -39 51 -21 57 6 2 4 3 -4 2 -8 0 -14 -6 -13 -12 1 -6 -5 -17
-14 -25 -10 -8 -14 -8 -10 -1 4 6 2 15 -4 19 -7 4 -9 3 -5 -4 3 -6 -2 -15 -11
-21 -14 -8 -14 -10 -3 -11 9 0 5 -6 -10 -17 -14 -10 -28 -17 -32 -15 -5 1 -8
-6 -8 -16 0 -10 -5 -23 -11 -29 -7 -7 -7 -13 0 -17 7 -4 6 -16 -1 -36 -7 -23
-7 -34 2 -45 11 -14 7 -19 -12 -16 -5 0 -8 -3 -8 -9 0 -13 6 -13 31 1 19 10
20 9 9 -12 -11 -19 -10 -21 4 -16 10 4 14 3 11 -2 -3 -5 -1 -12 5 -16 13 -8
13 -25 -1 -25 -5 0 -7 6 -3 13 4 7 3 9 -2 4 -5 -5 -9 -14 -9 -20 -1 -7 -7 -11
-14 -9 -7 1 -19 -5 -27 -15 -13 -17 -13 -17 -14 4 0 12 5 25 10 28 6 4 7 11 4
17 -4 7 -2 8 4 4 7 -4 12 -1 12 9 0 11 -5 15 -16 11 -8 -3 -12 -2 -9 4 3 6 1
10 -6 10 -7 0 -5 8 6 20 10 11 13 20 7 20 -6 0 -14 -5 -17 -10 -5 -8 -11 -7
-21 1 -7 6 -11 15 -8 20 3 5 -3 6 -12 2 -10 -4 -13 -8 -7 -10 6 -2 9 -16 7
-29 -3 -15 -1 -23 5 -20 5 4 12 3 14 -1 3 -5 -14 -9 -36 -10 -31 -2 -38 0 -27
7 13 9 12 13 -8 30 -13 10 -29 17 -37 14 -17 -7 -28 -34 -14 -34 6 0 9 -9 6
-20 -3 -11 -1 -20 5 -20 5 0 7 -4 3 -9 -3 -5 -1 -12 5 -16 6 -4 7 -11 4 -17
-4 -6 1 -17 11 -25 11 -7 13 -13 6 -13 -7 0 -9 -4 -6 -10 8 -13 -1 -13 -26 0
-13 7 -19 7 -19 0 0 -5 7 -10 16 -10 8 0 13 -4 9 -9 -3 -5 7 -11 22 -13 20 -2
27 -8 25 -20 -2 -10 3 -18 9 -18 7 0 3 -9 -9 -20 -22 -21 -67 -27 -77 -10 -6
10 13 14 45 11 13 -2 13 -1 0 8 -12 9 -13 11 -1 11 8 0 11 3 8 7 -4 3 -22 -2
-41 -12 l-34 -18 26 -24 c14 -12 19 -23 12 -23 -7 0 -10 -7 -6 -16 3 -9 2 -12
-4 -9 -6 4 -9 14 -8 23 2 9 -5 18 -15 20 -16 3 -17 1 -8 -16 8 -15 8 -22 -2
-25 -7 -3 -5 -6 6 -6 9 -1 16 -6 15 -13 -2 -7 8 -12 24 -12 23 1 25 -1 18 -21
-10 -26 -2 -104 13 -122 6 -9 6 -13 -2 -13 -7 0 -9 -4 -6 -10 3 -5 0 -10 -7
-10 -11 0 -11 -2 0 -9 10 -6 11 -13 1 -34 -9 -21 -9 -33 -1 -53 8 -16 9 -31 3
-43 -7 -13 -4 -24 15 -46 13 -15 24 -39 24 -53 0 -17 4 -22 14 -19 10 4 17 -4
21 -24 4 -17 13 -33 20 -35 7 -3 16 -16 19 -30 l6 -24 600 0 c368 0 600 4 600
9 0 6 -4 13 -10 16 -5 3 -10 12 -9 18 0 9 2 9 5 1 7 -16 44 -5 44 12 0 17 21
18 44 1 22 -16 12 -44 -17 -50 -12 -2 28 -5 90 -6 98 -1 112 1 117 17 3 9 20
23 37 31 20 9 28 18 24 29 -4 12 -3 13 9 3 17 -14 36 -7 36 14 0 8 -6 12 -14
9 -10 -4 -13 0 -9 14 5 20 -23 84 -59 134 -12 18 -29 29 -46 29 -24 2 -24 2
-4 6 12 2 22 7 22 10 0 2 -17 29 -37 58 -35 50 -114 115 -141 115 -6 0 -12 4
-12 8 0 5 -16 27 -36 50 -19 23 -31 42 -25 42 6 0 16 -9 23 -20 16 -24 30 -26
21 -3 -5 13 0 12 28 -7 43 -30 80 -70 115 -125 15 -24 31 -42 36 -39 5 3 7 2
6 -3 -5 -15 39 -63 57 -63 13 0 15 -3 7 -13 -9 -10 -1 -34 29 -95 23 -45 46
-82 51 -82 5 0 6 -5 3 -10 -3 -6 0 -13 8 -16 9 -3 13 -13 10 -25 -3 -10 -1
-19 5 -19 6 0 12 -10 14 -22 3 -21 8 -23 63 -23 l60 0 3 62 c3 59 2 63 -19 63
-22 0 -22 -1 -4 -13 11 -9 14 -16 7 -21 -6 -3 -18 2 -28 11 -12 13 -19 14 -22
5 -9 -28 -32 -12 -32 23 0 24 5 35 15 35 8 0 15 -5 15 -11 0 -5 5 -7 11 -3 8
5 8 9 -1 14 -8 5 -9 9 -1 11 12 5 3 49 -10 49 -5 0 -8 -3 -7 -7 2 -5 -1 -8 -7
-8 -5 0 -9 11 -7 25 l2 25 -17 -27 c-21 -33 -34 -35 -58 -8 -10 11 -26 22 -36
25 -23 8 -25 25 -4 25 8 0 15 -5 15 -11 0 -8 4 -8 13 -1 7 6 25 9 40 6 22 -3
27 -1 27 16 0 11 4 20 10 20 5 0 7 -6 4 -14 -7 -17 25 -36 52 -32 10 2 13 1 7
-1 -9 -3 -10 -10 -3 -23 6 -11 9 -23 8 -27 -4 -14 13 -53 23 -53 5 0 7 50 5
123 -6 156 -6 68 0 1050 l5 848 -28 -3 c-20 -2 -29 -9 -31 -24 -2 -16 -8 -20
-21 -17 -13 3 -17 11 -14 24 4 14 0 19 -16 19 -11 0 -21 -3 -20 -7 1 -5 -2
-18 -6 -31 -6 -19 -12 -22 -35 -17 -16 3 -31 2 -34 -3 -7 -11 -106 -3 -123 10
-8 6 -13 3 -16 -9 -3 -10 -5 -1 -6 20 -1 38 -14 49 -25 20z m-1276 -1513 c-12
-7 -12 -10 -1 -10 8 0 11 -6 7 -17 -3 -10 3 -6 15 10 23 30 41 34 59 12 11
-13 10 -14 -5 -9 -13 5 -16 4 -11 -4 4 -7 19 -12 34 -13 l27 -1 -29 -8 c-16
-5 -32 -7 -36 -5 -3 2 -6 -8 -6 -21 0 -21 4 -24 23 -19 21 5 22 4 11 -15 -7
-11 -19 -20 -26 -20 -8 0 -10 5 -6 12 5 8 2 9 -12 3 -39 -16 -67 -19 -59 -5 5
9 4 11 -4 6 -6 -4 -9 -12 -6 -17 3 -5 -1 -6 -10 -3 -9 4 -14 13 -11 20 4 10
-4 9 -29 -4 -18 -9 -32 -21 -32 -26 1 -5 -4 -11 -12 -14 -10 -3 -12 0 -8 11 3
9 1 17 -6 20 -7 2 -4 16 11 40 l22 38 -23 -13 c-12 -6 -32 -12 -45 -13 -20 -1
-21 1 -7 11 12 9 13 13 3 17 -10 3 -10 7 -1 17 10 11 15 11 28 0 11 -9 15 -9
15 -1 0 7 4 10 10 6 5 -3 18 0 29 7 15 9 25 9 46 0 14 -7 24 -8 21 -3 -6 9 8
19 29 20 6 0 3 -4 -5 -9z m914 -29 c34 -29 46 -76 46 -179 0 -87 -3 -105 -26
-148 -50 -95 -82 -115 -187 -115 -60 0 -82 4 -122 26 -44 23 -104 79 -105 97
0 10 -46 110 -82 181 -31 61 -31 78 3 121 27 34 75 34 164 2 61 -22 70 -23
101 -10 18 8 42 14 53 14 10 0 38 9 61 19 45 20 62 19 94 -8z"/>
<path d="M164 1993 c36 -55 77 -136 71 -141 -3 -3 -57 -6 -120 -6 l-115 -1 4
-755 c2 -415 4 -769 5 -786 2 -46 27 -52 35 -9 7 38 29 55 57 48 11 -3 19 0
19 6 0 6 -7 11 -15 11 -20 0 -19 27 2 38 10 6 14 16 10 26 -4 9 -3 16 2 16 7
0 17 38 25 92 1 3 4 10 8 14 4 4 3 13 -3 21 -9 10 -8 13 5 13 9 0 17 9 17 20
2 28 3 33 12 48 5 7 6 21 2 31 -4 13 2 26 15 39 12 11 24 38 27 61 3 23 10 41
16 41 7 0 7 4 -1 12 -14 14 -16 32 -3 23 6 -3 15 4 21 15 8 15 8 20 -2 20 -7
1 -4 6 7 13 11 7 21 23 22 37 1 14 4 37 7 52 6 25 3 28 -29 34 l-36 6 23 16
c13 9 26 20 30 26 7 11 -9 26 -27 26 -5 0 -3 -5 5 -10 9 -6 10 -10 3 -10 -24
0 -24 20 1 29 23 9 29 31 13 47 -4 4 1 12 10 19 11 8 13 14 5 19 -7 4 -12 2
-12 -3 0 -6 -10 -11 -22 -11 -21 0 -21 0 -2 16 13 11 14 14 3 11 -9 -3 -16 1
-16 9 0 9 6 13 14 10 8 -3 11 -1 8 4 -3 5 -2 26 4 45 6 21 6 37 0 41 -5 3 -9
14 -9 25 0 10 -6 19 -12 19 -9 0 -9 3 1 9 8 5 14 22 15 37 1 16 5 35 9 42 5 6
5 12 2 12 -4 0 1 7 10 16 9 10 15 24 12 33 -2 9 2 22 10 29 7 7 13 23 13 35 0
28 15 51 28 43 5 -3 13 2 16 11 6 15 -8 32 -26 33 -5 0 -8 7 -8 15 0 8 -6 15
-12 15 -8 0 -5 7 6 15 12 9 15 15 7 15 -9 0 -12 9 -9 24 3 17 1 23 -8 19 -25
-9 -36 8 -18 28 16 17 16 19 1 19 -10 0 -17 5 -17 10 0 6 5 10 11 10 6 0 9 6
6 13 -2 6 3 17 11 23 13 10 13 14 -1 35 -10 13 -17 18 -17 11 0 -18 -24 -15
-43 6 -59 64 -60 64 -46 74 11 8 10 9 -3 4 -11 -3 -18 0 -18 8 0 12 -20 26
-36 26 -2 0 7 -17 20 -37z"/>
<path d="M1443 1727 c-3 -6 -1 -7 5 -3 23 14 12 -12 -13 -30 -25 -19 -34 -58
-15 -69 6 -4 26 5 45 19 35 27 73 33 104 16 10 -5 42 -12 72 -15 29 -4 59 -11
66 -17 17 -14 17 3 0 27 -9 12 -16 14 -21 7 -7 -12 -64 15 -101 48 -22 20
-132 33 -142 17z"/>
<path d="M726 1647 c-31 -20 -50 -40 -76 -82 l-24 -40 27 26 c18 17 43 28 73
33 77 10 102 7 155 -19 27 -14 54 -23 59 -20 16 10 12 55 -5 55 -8 0 -15 5
-15 10 0 6 -11 10 -24 10 -16 0 -27 7 -31 20 -3 11 -11 20 -16 20 -6 0 -7 -5
-3 -12 5 -8 2 -9 -12 -3 -33 13 -88 15 -108 2z"/>
</g>
</svg>
-->
<img src="/assets/favicon-32x32.png"><a title="My personal blog, some contents are useful, the others are not. Just like my mediocre life.
" href="/">STSD</a></div><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></div><nav class="navigation">
<ul><li class="navigation__item"><a href="/archive.html">Archive</a></li><li class="navigation__item"><a href="https://pengzhan.dev">About</a></li><li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li></ul>
</nav></div>
</header>
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
<div class="col-aside d-print-none js-col-aside"><aside class="page__aside js-page-aside"><div class="toc-aside js-toc-root"></div>
</aside></div>
<div class="col-main cell cell--auto"><!-- start custom main top snippet -->
<!-- end custom main top snippet -->
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1>Xv6 introduction</h1></header></div><meta itemprop="headline" content="Xv6 introduction"><div class="article__info clearfix"><ul class="left-col menu"><li>
<a class="button button--secondary button--pill button--sm"
href="/archive.html?tag=Xv6">Xv6</a>
</li><li>
<a class="button button--secondary button--pill button--sm"
href="/archive.html?tag=Teaching">Teaching</a>
</li><li>
<a class="button button--secondary button--pill button--sm"
href="/archive.html?tag=Operating+system">Operating system</a>
</li></ul><ul class="right-col menu"><li><i class="fas fa-user"></i> <span>Pengzhan Hao</span></li><li><i class="far fa-calendar-alt"></i> <span>Jul 28, 2017</span>
</li></ul></div><meta itemprop="author" content="Pengzhan Hao"/><meta itemprop="datePublished" content="2017-07-28T14:56:55-04:00">
<meta itemprop="keywords" content="Xv6,Teaching,Operating system"><div class="js-article-content"><div class="layout--article"><!-- start custom article top snippet -->
<!-- end custom article top snippet -->
<div class="article__content" itemprop="articleBody"><p>In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching OS classes.
Understand system call and know how to implement a simple one will be coved as the first half.
In the second half of this post, I will discuss a little bit more on how to debug xv6 using gdb.<br />
<!--more--></p>
<h2 id="xv6-systemcall">Xv6 Systemcall</h2>
<p>To invoke a system call, we have to first define a user mode function to be the interface of the kernel instruction in file <em>user.h</em>.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">function</span> <span class="p">(</span><span class="kt">void</span><span class="p">);</span>
</code></pre></div></div>
<p>This interface-like function will then pass the function name, in this case function, to <em>usys.S</em>. When using user mode function in programs, <em>usys.S</em> will generate a reference to SYS_function and push system call number of this function into %eax. After that, system can know from <em>syscall.c</em> and determining whether this system call is available. We must define same name system function and add it into <em>syscall.h</em> and <em>syscall.c</em>.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define SYS_function ## // ## is the system call number
</span><span class="p">[</span><span class="n">SYS_function</span><span class="p">]</span> <span class="n">sys_function</span> <span class="c1">// real system function name</span>
<span class="k">extern</span> <span class="kt">int</span> <span class="nf">sys_function</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span> <span class="c1">// real system function declaration</span>
</code></pre></div></div>
<p>After adding these sentences to syscall files, we can implement real function in specific place where you want to make the function works well.</p>
<p>Sometimes, we need to pass variables among system calls. In this case, variables values are not necessary and even cant be pass directly into system_function. When invoke a system call function, all variables of this system call will be pushed into current process stack. In file <em>syscall.c</em>, multiple functions are provided to get these variables from the process. I wont waste time on explaining how to use these functions especially when elegant and detailed comments were written in source codes. However, I will explain concepts and how process organized and works in xv6 in future articles.</p>
<h2 id="debug-xv6-with-gdb">Debug xv6 with gdb</h2>
<p>Please make sure that you have used gdb before.
If you never used gdb, you may write a simple 50-100 lines c code and practice how to use gdb first.</p>
<ul>
<li><a href="https://sourceware.org/gdb/current/onlinedocs/gdb/">GDB Manual</a></li>
<li><a href="https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf">GDB cheatsheet (pdf)</a></li>
</ul>
<p>To make sure xv6 gdb enabled, please check if <em>.gdbinit.tmpl</em> file exist.
This file is used for generate <em>.gdbinit</em> file which you can late consider it as a configuration for gdb.</p>
<p>Before running the xv6 instance in QEMU, one more thing you need to know is that using gdb to debug xv6 must be attached remotely.
This is because xv6 was running within QEMU, and emulator is virtually gapped from the host device.
Later when you start debugging, QEMU will open a gdb server to let gdb client connect to.</p>
<p>Once you want to start, using following command to compile and run xv6</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>make qemu-nox-gdb
<span class="k">***</span> Now run <span class="s1">'gdb'</span><span class="nb">.</span>
qemu-system-i386 <span class="nt">-nographic</span> <span class="nt">-drive</span> <span class="nv">file</span><span class="o">=</span>fs.img,index<span class="o">=</span>1,media<span class="o">=</span>disk,format<span class="o">=</span>raw <span class="nt">-drive</span> <span class="nv">file</span><span class="o">=</span>xv6.img,index<span class="o">=</span>0,media<span class="o">=</span>disk,format<span class="o">=</span>raw <span class="nt">-smp</span> 2 7
</code></pre></div></div>
<p>At this moment, it feels xv6 was stuck, this is because QEMU is ready to be connected by the gdb client.
You may use the <em>.gdbinit</em> to automatically finish this remote connection by simple typein following command in another terminal.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gdb <span class="nt">-x</span> .gdbinit
GNU gdb <span class="o">(</span>Debian 8.2.1-2+b3<span class="o">)</span> 8.2.1
...
The target architecture is assumed to be i8086
<span class="o">[</span>f000:fff0] 0xffff0: ljmp <span class="nv">$0x3630</span>,<span class="nv">$0xf000e05b</span>
0x0000fff0 <span class="k">in</span> ?? <span class="o">()</span>
+ symbol-file kernel
warning: A handler <span class="k">for </span>the OS ABI <span class="s2">"GNU/Linux"</span> is not built into this configuration
of GDB. Attempting to <span class="k">continue </span>with the default i8086 settings.
<span class="o">(</span>gdb<span class="o">)</span>
</code></pre></div></div>
<p>Now within this gdb client shell, type c to continue the xv6, and you will see xv6 start execution in the first terminal.</p>
<p>At this moment, you may add breakpoints to your code to see if your code is correctly implemented or not.</p>
<p><strong>One more thing</strong>, if you open <em>.gdbinit</em> file, youll find that it by default connect to a localhost target.
If you are working on some other environment that target and client were not placed in the same device, change the localhost to ip address correspondingly.
Using ssh may connect to different physical devices under same domain name, this is because load balancer were used. To check ip address, search command <em>ip</em>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>target remote localhost:28467
<span class="c"># target remote [ip-addr]:28467</span>
</code></pre></div></div>
</div><section class="article__sharing d-print-none"></section><div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2017-07-28T14:56:55-04:00"><!-- start custom article footer snippet -->
<!-- end custom article footer snippet -->
<div class="article__subscribe"><div class="subscribe"><i class="fas fa-rss"></i> <a type="application/rss+xml" href="/feed.xml">Subscribe</a></div>
</div><div class="article__license"></div></footer>
<div class="article__section-navigator clearfix"><div class="previous"><span>PREVIOUS</span><a href="/posts/some-of-my-previews-exper-work">Some of my previews experiment works: 2016</a></div><div class="next"><span>NEXT</span><a href="/posts/generate-word-cloud-with-chinese-fenci">Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries</a></div></div></div>
</div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
$(function() {
var $this ,$scroll;
var $articleContent = $('.js-article-content');
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
$scroll = $(scroll);
$articleContent.find('.highlight').each(function() {
$this = $(this);
$this.attr('data-lang', $this.find('code').attr('data-lang'));
});
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
$this = $(this);
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
});
$articleContent.on('click', '.anchor', function() {
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
});
});
});
})();
</script>
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
<!-- end custom main bottom snippet -->
</div>
</div></div></div><div class="page__footer d-print-none">
<footer class="footer py-4 js-page-footer">
<div class="main"><div itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Pengzhan Hao"><meta itemprop="url" content="/"><div class="footer__author-links"><div class="author-links">
<ul class="menu menu--nowrap menu--inline"><li title="Send me an Email.">
<a class="button button--circle mail-button" itemprop="email" href="mailto:haopengzhan@gmail.com" target="_blank">
<div class="icon"><svg fill="#000000" width="24px" height="24px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M512.091 166.946c116.242 0 232.484-0.014 348.727 0.007 41.522 0.008 76.321 12.188 94.842 53.167 8.25 18.251 6.5 30.831-13.43 43.256-137.452 85.695-274.125 172.655-410.534 260.014-14.762 9.456-24.638 9.569-39.498 0.041C354.353 435.041 216.033 347.399 77.465 260.14c-12.701-8.002-16.368-15.572-12.01-29.962 9.882-32.627 30.845-52.873 63.868-59.66 13.656-2.806 27.953-3.4 41.966-3.431C284.888 166.83 398.492 166.943 512.091 166.946z" />
<path d="M510.888 856.021c-117.998 0-235.996 0.134-353.993-0.067-47.671-0.083-79.295-22.331-91.17-61.206-4.28-14.027-2.127-22.232 10.858-30.356 108.193-67.725 215.807-136.366 324.233-203.713 7.275-4.519 21.51-4.25 29.378-0.171 22.589 11.713 44.026 25.859 64.999 40.383 11.823 8.191 21.091 8.623 33.117 0.325 20.993-14.484 43.689-26.52 64.549-41.176 12.159-8.539 20.73-7.176 32.785 0.537 106.04 67.844 212.318 135.315 319.158 201.894 16.481 10.272 18.065 21.564 12.577 37.407-12.35 35.666-45.183 55.999-92.491 56.081C746.889 856.149 628.886 856.021 510.888 856.021z" />
<path d="M64.376 326.925c97.051 61.769 192.332 122.409 290.508 184.898-97.877 62.309-192.719 122.68-290.508 184.932C64.376 572.674 64.376 451.511 64.376 326.925z" />
<path d="M959.665 327.168c0 124.369 0 244.164 0 369.253-97.913-62.322-192.914-122.792-290.001-184.589C766.993 449.854 861.628 389.595 959.665 327.168z" />
</svg>
</div>
</a><li title="Follow me on Linkedin.">
<a class="button button--circle linkedin-button" itemprop="sameAs" href="https://www.linkedin.com/in/pengzhanhao" target="_blank">
<div class="icon"><svg fill="#000000" width="24px" height="24px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M260.096 155.648c0 27.307008-9.899008 50.516992-29.696 69.632-19.796992 19.115008-45.396992 28.672-76.8 28.672-30.036992 0-54.612992-9.556992-73.728-28.672-19.115008-19.115008-28.672-42.324992-28.672-69.632 0-28.672 9.556992-52.224 28.672-70.656 19.115008-18.432 44.372992-27.648 75.776-27.648 31.403008 0 56.32 9.216 74.752 27.648 18.432 18.432 28.331008 41.984 29.696 70.656 0 0 0 0 0 0m-202.752 808.96c0 0 0-632.832 0-632.832 0 0 196.608 0 196.608 0 0 0 0 632.832 0 632.832 0 0-196.608 0-196.608 0 0 0 0 0 0 0m313.344-430.08c0-58.708992-1.364992-126.292992-4.096-202.752 0 0 169.984 0 169.984 0 0 0 10.24 88.064 10.24 88.064 0 0 4.096 0 4.096 0 40.96-68.267008 105.812992-102.4 194.56-102.4 68.267008 0 123.220992 22.868992 164.864 68.608 41.643008 45.739008 62.464 113.664 62.464 203.776 0 0 0 374.784 0 374.784 0 0-196.608 0-196.608 0 0 0 0-350.208 0-350.208 0-91.476992-33.451008-137.216-100.352-137.216-47.787008 0-81.236992 24.576-100.352 73.728-4.096 8.192-6.144 24.576-6.144 49.152 0 0 0 364.544 0 364.544 0 0-198.656 0-198.656 0 0 0 0-430.08 0-430.08 0 0 0 0 0 0" />
</svg>
</div>
</a>
</li><li title="Follow me on Github.">
<a class="button button--circle github-button" itemprop="sameAs" href="https://github.com/codersherlock" target="_blank">
<div class="icon"><svg fill="#000000" width="24px" height="24px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path class="svgpath" data-index="path_0" fill="#272636" d="M0 525.2c0 223.6 143.3 413.7 343 483.5 26.9 6.8 22.8-12.4 22.8-25.4l0-88.7c-155.3 18.2-161.5-84.6-172-101.7-21.1-36-70.8-45.2-56-62.3 35.4-18.2 71.4 4.6 113.1 66.3 30.2 44.7 89.1 37.2 119 29.7 6.5-26.9 20.5-50.9 39.7-69.6C248.8 728.2 181.7 630 181.7 513.2c0-56.6 18.7-108.7 55.3-150.7-23.3-69.3 2.2-128.5 5.6-137.3 66.5-6 135.5 47.6 140.9 51.8 37.8-10.2 80.9-15.6 129.1-15.6 48.5 0 91.8 5.6 129.8 15.9 12.9-9.8 77-55.8 138.8-50.2 3.3 8.8 28.2 66.7 6.3 135 37.1 42.1 56 94.6 56 151.4 0 117-67.5 215.3-228.8 243.7 26.9 26.6 43.6 63.4 43.6 104.2l0 128.8c0.9 10.3 0 20.5 17.2 20.5C878.1 942.4 1024 750.9 1024 525.3c0-282.9-229.3-512-512-512C229.1 13.2 0 242.3 0 525.2L0 525.2z" />
</svg>
</div>
</a>
</li></ul>
</div>
</div>
</div><div class="site-info mt-2">
<div>© STSD 2021,
Powered by <a title="Jekyll is a simple, blog-aware, static site generator." href="http://jekyllrb.com/">Jekyll</a> & <a
title="TeXt is a super customizable Jekyll theme." href="https://github.com/kitian616/jekyll-TeXt-theme">TeXt Theme</a>.
</div>
</div>
</div>
</footer>
</div></div>
</div><script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $body = $('body'), $window = $(window);
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
var activeCount = 0;
function modal(options) {
var $root = this, visible, onChange, hideWhenWindowScroll = false;
var scrollTop;
function setOptions(options) {
var _options = options || {};
visible = _options.initialVisible === undefined ? false : show;
onChange = _options.onChange;
hideWhenWindowScroll = _options.hideWhenWindowScroll;
}
function init() {
setState(visible);
}
function setState(isShow) {
if (isShow === visible) {
return;
}
visible = isShow;
if (visible) {
activeCount++;
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
$root.addClass('modal--show');
$pageMain.scrollTop(scrollTop);
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
$window.on('keyup', handleKeyup);
} else {
activeCount > 0 && activeCount--;
$root.removeClass('modal--show');
$window.scrollTop(scrollTop);
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
$window.off('keyup', handleKeyup);
}
onChange && onChange(visible);
}
function show() {
setState(true);
}
function hide() {
setState(false);
}
function handleKeyup(e) {
// Char Code: 27 ESC
if (e.which === 27) {
hide();
}
}
setOptions(options);
init();
return {
show: show,
hide: hide,
$el: $root
};
}
$.fn.modal = modal;
});
})();
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
(function () {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
// search panel
var search = (window.search || (window.search = {}));
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
true : window.useDefaultSearchBox ;
var $searchModal = $('.js-page-search-modal');
var $searchToggle = $('.js-search-toggle');
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
var modalVisible = false;
search.searchModal = searchModal;
var $searchBox = null;
var $searchInput = null;
var $searchClear = null;
function getModalVisible() {
return modalVisible;
}
search.getModalVisible = getModalVisible;
function handleModalChange(visible) {
modalVisible = visible;
if (visible) {
search.onShow && search.onShow();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
} else {
search.onShow && search.onHide();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
setTimeout(function() {
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
search.clear && search.clear();
window.pageAsideAffix && window.pageAsideAffix.refresh();
}, 400);
}
}
$searchToggle.on('click', function() {
modalVisible ? searchModal.hide() : searchModal.show();
});
// Char Code: 83 S, 191 /
$(window).on('keyup', function(e) {
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
modalVisible || searchModal.show();
}
});
if (useDefaultSearchBox) {
$searchBox = $('.js-search-box');
$searchInput = $searchBox.children('input');
$searchClear = $searchBox.children('.js-icon-clear');
search.getSearchInput = function() {
return $searchInput.get(0);
};
search.getVal = function() {
return $searchInput.val();
};
search.setVal = function(val) {
$searchInput.val(val);
};
$searchInput.on('focus', function() {
$(this).addClass('focus');
});
$searchInput.on('blur', function() {
$(this).removeClass('focus');
});
$searchInput.on('input', window.throttle(function() {
var val = $(this).val();
if (val === '' || typeof val !== 'string') {
search.clear && search.clear();
} else {
$searchBox.addClass('not-empty');
search.onInputNotEmpty && search.onInputNotEmpty(val);
}
}, 400));
$searchClear.on('click', function() {
$searchInput.val(''); $searchBox.removeClass('not-empty');
search.clear && search.clear();
});
}
});
})();
</script><div class="search search--dark">
<div class="main">
<div class="search__header">Search</div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input type="text" />
<div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div>
</div>
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
Cancel</button>
</div>
<div class="search-result js-search-result"></div>
</div>
</div>
<script>var SOURCES = window.TEXT_VARIABLES.sources;
var PAHTS = window.TEXT_VARIABLES.paths;
window.Lazyload.js([SOURCES.jquery, PAHTS.search_js], function() {
var search = (window.search || (window.search = {}));
var searchData = window.TEXT_SEARCH_DATA || {};
function memorize(f) {
var cache = {};
return function () {
var key = Array.prototype.join.call(arguments, ',');
if (key in cache) return cache[key];
else return cache[key] = f.apply(this, arguments);
};
}
/// search
function searchByQuery(query) {
var i, j, key, keys, cur, _title, result = {};
keys = Object.keys(searchData);
for (i = 0; i < keys.length; i++) {
key = keys[i];
for (j = 0; j < searchData[key].length; j++) {
cur = searchData[key][j], _title = cur.title;
if ((result[key] === undefined || result[key] && result[key].length < 4 )
&& _title.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
if (result[key] === undefined) {
result[key] = [];
}
result[key].push(cur);
}
}
}
return result;
}
var renderHeader = memorize(function(header) {
return $('<p class="search-result__header">' + header + '</p>');
});
var renderItem = function(index, title, url) {
return $('<li class="search-result__item" data-index="' + index + '"><a class="button" href="' + url + '">' + title + '</a></li>');
};
function render(data) {
if (!data) { return null; }
var $root = $('<ul></ul>'), i, j, key, keys, cur, itemIndex = 0;
keys = Object.keys(data);
for (i = 0; i < keys.length; i++) {
key = keys[i];
$root.append(renderHeader(key));
for (j = 0; j < data[key].length; j++) {
cur = data[key][j];
$root.append(renderItem(itemIndex++, cur.title, cur.url));
}
}
return $root;
}
// search box
var $result = $('.js-search-result'), $resultItems;
var lastActiveIndex, activeIndex;
function clear() {
$result.html(null);
$resultItems = $('.search-result__item'); activeIndex = 0;
}
function onInputNotEmpty(val) {
$result.html(render(searchByQuery(val)));
$resultItems = $('.search-result__item'); activeIndex = 0;
$resultItems.eq(0).addClass('active');
}
search.clear = clear;
search.onInputNotEmpty = onInputNotEmpty;
function updateResultItems() {
lastActiveIndex >= 0 && $resultItems.eq(lastActiveIndex).removeClass('active');
activeIndex >= 0 && $resultItems.eq(activeIndex).addClass('active');
}
function moveActiveIndex(direction) {
var itemsCount = $resultItems ? $resultItems.length : 0;
if (itemsCount > 1) {
lastActiveIndex = activeIndex;
if (direction === 'up') {
activeIndex = (activeIndex - 1 + itemsCount) % itemsCount;
} else if (direction === 'down') {
activeIndex = (activeIndex + 1 + itemsCount) % itemsCount;
}
updateResultItems();
}
}
// Char Code: 13 Enter, 37 ⬅, 38 ⬆, 39 ➡, 40 ⬇
$(window).on('keyup', function(e) {
var modalVisible = search.getModalVisible && search.getModalVisible();
if (modalVisible) {
if (e.which === 38) {
modalVisible && moveActiveIndex('up');
} else if (e.which === 40) {
modalVisible && moveActiveIndex('down');
} else if (e.which === 13) {
modalVisible && $resultItems && activeIndex >= 0 && $resultItems.eq(activeIndex).children('a')[0].click();
}
}
});
$result.on('mouseover', '.search-result__item > a', function() {
var itemIndex = $(this).parent().data('index');
itemIndex >= 0 && (lastActiveIndex = activeIndex, activeIndex = itemIndex, updateResultItems());
});
});
</script>
</div></div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function scrollToAnchor(anchor, duration, callback) {
var $root = this;
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
callback && callback();
});
}
$.fn.scrollToAnchor = scrollToAnchor;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function affix(options) {
var $root = this, $window = $(window), $scrollTarget, $scroll,
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
hasInit = false, curState;
function setOptions(options) {
var _options = options || {};
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroll && (scroll = _options.scroll);
_options.disabled !== undefined && (disabled = _options.disabled);
$scrollTarget = $(scrollTarget);
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
$scroll = $(scroll);
}
function preCalc() {
top();
rootHeight = $root.outerHeight();
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
rootLeft = $root.offset().left;
}
function calc(needPreCalc) {
needPreCalc && preCalc();
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
rootBottomTop = scrollBottom - rootTop;
}
function top() {
if (curState !== 'top') {
$root.removeClass('fixed').css({
left: 0,
top: 0
});
curState = 'top';
}
}
function fixed() {
if (curState !== 'fixed') {
$root.addClass('fixed').css({
left: rootLeft + 'px',
top: 0
});
curState = 'fixed';
}
}
function bottom() {
if (curState !== 'bottom') {
$root.removeClass('fixed').css({
left: 0,
top: rootBottomTop + 'px'
});
curState = 'bottom';
}
}
function setState() {
var scrollTop = $scrollTarget.scrollTop();
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
fixed();
} else if (scrollTop < rootTop) {
top();
} else {
bottom();
}
}
function init() {
if(!hasInit) {
var interval, timeout;
calc(true); setState();
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState();
});
$window.on('resize', function() {
disabled || (calc(true), setState());
});
hasInit = true;
}
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions,
refresh: function() {
calc(true, { animation: false }); setState();
}
};
}
$.fn.affix = affix;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function toc(options) {
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
function setOptions(options) {
var _options = options || {};
_options.selectors && (selectors = _options.selectors);
_options.container && (container = _options.container);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroller && (scroller = _options.scroller);
_options.disabled !== undefined && (disabled = _options.disabled);
$headings = $(container).find(selectors).filter('[id]');
$scrollTarget = $(scrollTarget);
$scroller = $(scroller);
}
function calc() {
headingsPos = [];
$headings.each(function() {
headingsPos.push(Math.floor($(this).position().top));
});
}
function setState(element, disabled) {
var scrollTop = $scrollTarget.scrollTop(), i;
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
if (element) {
$activeCur = element;
} else {
for (i = 0; i < headingsPos.length; i++) {
if (scrollTop >= headingsPos[i]) {
$activeCur = $tocLi.eq(i);
} else {
$activeCur || ($activeCur = $tocLi.eq(i));
break;
}
}
}
$activeLast && $activeLast.removeClass('active');
($activeLast = $activeCur).addClass('active');
}
function render() {
if(!hasRendered) {
$root.append($tocUl);
$headings.each(function() {
var $this = $(this);
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
});
$tocLi = $tocUl.children('li');
$tocUl.on('click', 'a', function(e) {
e.preventDefault();
var $this = $(this);
scrolling = true;
setState($this.parent());
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
scrolling = false;
});
});
}
hasRendered = true;
}
function init() {
var interval, timeout;
if(!hasInit) {
render(); calc(); setState(null, scrolling);
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState(null, scrolling);
});
$window.on('resize', window.throttle(function() {
if (!disabled) {
render(); calc(); setState(null, scrolling);
}
}, 100));
}
hasInit = true;
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions
};
}
$.fn.toc = toc;
});
})();
/*(function () {
})();*/
</script><script>
/* toc must before affix, since affix need to konw toc' height. */(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window);
var $articleContent = $('.js-article-content');
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
var toc;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
function disabled() {
return $col2.css('display') === 'none' || !hasToc;
}
tocDisabled = disabled();
toc = $tocRoot.toc({
selectors: TOC_SELECTOR,
container: $articleContent,
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
tocDisabled = disabled();
toc && toc.setOptions({
disabled: tocDisabled
});
}, 100));
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window), $pageFooter = $('.js-page-footer');
var $pageAside = $('.js-page-aside');
var affix;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
affix = $pageAside.affix({
offsetBottom: $pageFooter.outerHeight(),
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
scroll: hasSidebar ? $('.js-page-main').children() : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
affix && affix.setOptions({
disabled: tocDisabled
});
}, 100));
window.pageAsideAffix = affix;
});
})();
</script>
</div>
<script>(function () {
var $root = document.getElementsByClassName('root')[0];
if (window.hasEvent('touchstart')) {
$root.dataset.isTouch = true;
document.addEventListener('touchstart', function(){}, false);
}
})();
</script>
</body>
</html>