0%

1. 创建仓库

在github上创建名称为username.github.io仓库

2. Clone

将仓库clone到本地

1
$ git clone https://github.com/username/username.github.io

3. Hello World

创建index.html

1
2
$ cd username.github.io
$ echo "Hello World" > index.html

4. push

提交代码并push

1
2
3
$ git add --all
$ git commit -m "Initial commit"
$ git push -u origin master

5. 验证

访问username.github.io,这样就能看到Hello World了

6. 域名映射

将域名映射到username.github.io

1
2
3
$ echo "www.yourdomain.com" > CNAME
$ git commit -m "Create CNAME"
$ git push origin master

在域名管理添加一条CNAME记录,将www.yourdomain.com指向username.github.io

7. 安装Hexo

7.1 什么是Hexo

Hexo is a fast, simple and powerful blog framework. You write posts in Markdown (or other languages) and Hexo generates static files with a beautiful theme in seconds.

7.2 安装Git
7.3 安装Node.js
1
2
$ wget -qO- https://raw.github.com/creationix/nvm/master/install.sh | sh
$ nvm install 4
7.4 安装Hexo
1
2
3
4
5
$ npm install -g hexo-cli
$ hexo init <folder>
$ cd <folder>
$ npm install
$ hexo server

这样就可以通过localhost:4000访问了

7.5 部署到github

安装hexo-deployer-git

1
$ npm install hexo-deployer-git --save

修改_config.yml

1
2
3
deploy:
type: git
repo: <repository url>

部署到github

1
$ hexo deploy

但是部署后会覆盖掉github上的CNAME和README.md,需要在hexo的source目录添加CNAME和README.md,但是执行hexo generate后README.md会生成README.html,因此需要配置下,不让其渲染README.md。
修改Hexo目录下的_config.yml

1
skip_render: README.md

然后运行

1
2
$ hexo g
$ hexo d

这样就部署到github上了,并且不会覆盖掉已写好的CNAME和README.md了。

7.6 写blog
1
$ hexo new "Markdown"

会在source/_posts/目录下生成Markdown.md文件,编辑该文件后

1
2
$ hexo g
$ hexo d

参考

https://github.io
https://hexo.io

实验环境:Ubuntu 7.10 + Linux Kernel 2.6.23.12
耗时:约 2-3 小时(主要是编译时间)
难度:⭐⭐⭐

经过一两天的摸索,终于在 Ubuntu 虚拟机中成功完成了内核编译和系统调用添加实验。期间踩了不少坑,换了几个内核版本,重新编译了多次。现将完整步骤整理如下,希望能有所帮助!

📋 准备工作

系统要求

  • Ubuntu 7.10 或更高版本
  • 至少 20GB 磁盘空间
  • 4GB 以上内存(虚拟机建议分配 2GB+)

下载内核源码

访问 https://www.kernel.org 下载 Linux 内核源码包(本文使用 linux-2.6.23.12.tar.gz

🔧 详细步骤

1. 解压内核源码

将内核包解压到 /usr/src 目录:

1
2
3
4
cd /usr/src
sudo tar jxvf linux-2.6.23.12.tar.bz2
# 或者如果是 .tar.gz 格式
sudo tar zxvf linux-2.6.23.12.tar.gz

2. 添加自定义系统调用

2.1 修改 sys.c 文件

在内核源码中添加系统调用实现:

1
2
cd /usr/src/linux-2.6.23.12
sudo vim kernel/sys.c

在文件末尾添加以下代码:

1
2
3
4
5
/* 自定义系统调用:打印消息并返回参数 */
asmlinkage int sys_mysyscall(int num) {
printk(KERN_INFO "Hello from mysyscall! Received: %d\n", num);
return num;
}

注意asmlinkage 是必需的,表示参数通过栈传递。

2.2 修改系统调用表

编辑系统调用表文件:

1
2
3
cd /usr/src/linux-2.6.23.12/arch/i386/kernel
# 如果没有 i386 目录,尝试 x86 目录
sudo vim syscall_table.S

在文件末尾添加:

1
.long sys_mysyscall

2.3 添加系统调用号

修改系统头文件(用户空间):

1
sudo vim /usr/include/asm-i386/unistd.h

在文件末尾添加:

1
#define __NR_mysyscall 325

修改内核头文件

1
sudo vim /usr/src/linux-2.6.23.12/include/asm-i386/unistd.h

添加以下内容:

1
#define __NR_mysyscall 325

同时将原有的:

1
#define NR_syscalls 325

修改为:

1
#define NR_syscalls 326

提示:如果要添加多个系统调用,依次递增调用号(326, 327…)

3. 编译内核

3.1 配置内核

1
2
cd /usr/src/linux-2.6.23.12
sudo make menuconfig

在菜单中保持默认配置即可,直接保存退出。

3.2 编译内核镜像

1
sudo make bzImage

耗时:约 30-60 分钟

3.3 编译内核模块

1
sudo make modules

耗时:约 1-2 小时(虚拟机会更慢)
建议:此时可以休息一下,喝杯咖啡或打打球 😊

3.4 安装模块

1
sudo make modules_install

执行后会在 /lib/modules/ 下生成 2.6.23.12 目录。

3.5 安装内核

1
2
3
4
5
# 复制内核镜像
sudo cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.23.12

# 生成 initramfs
sudo mkinitramfs -o /boot/initrd.img-2.6.23.12 2.6.23.12

4. 配置 GRUB 引导

4.1 编辑 GRUB 配置文件

1
2
3
sudo vim /boot/grub/menu.lst
# 或者
sudo vim /boot/grub/grub.conf

4.2 添加新内核启动项

在文件中找到类似以下的配置:

1
2
3
4
5
title Ubuntu 7.10, kernel 2.6.22-14-generic
root (hd0,0)
kernel /boot/vmlinuz-2.6.22-14-generic root=UUID=e2478f9d-7f5d-458f-b017-43458a8f62ea ro quiet splash
initrd /boot/initrd.img-2.6.22-14-generic
quiet

仿照格式添加新内核配置:

1
2
3
4
5
title Ubuntu 7.10, kernel 2.6.23.12 (Custom)
root (hd0,0)
kernel /boot/vmlinuz-2.6.23.12 root=UUID=e2478f9d-7f5d-458f-b017-43458a8f62ea ro quiet splash
initrd /boot/initrd.img-2.6.23.12
quiet

注意UUID 需要替换为你自己的分区 UUID,可通过 sudo blkid 查看。

4.3 显示 GRUB 菜单

注释掉隐藏菜单选项(如果有):

1
#hiddenmenu

保存并退出。

5. 重启系统

1
sudo reboot

在 GRUB 启动菜单中选择新编译的内核 kernel 2.6.23.12 (Custom) 启动。

🧪 测试自定义系统调用

编写测试程序

创建 test.c 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>

#define __NR_mysyscall 325

int main() {
int result;

printf("调用自定义系统调用 mysyscall...\n");
result = syscall(__NR_mysyscall, 42);

printf("系统调用返回值: %d\n", result);

return 0;
}

编译并运行

1
2
gcc -o test test.c
./test

预期输出

1
2
调用自定义系统调用 mysyscall...
系统调用返回值: 42

查看内核日志

1
dmesg | tail

应该能看到类似输出:

1
[12345.678901] Hello from mysyscall! Received: 42

常见问题及解决方案

问题 1:找不到 i386 目录

解决方案:新版本内核可能使用 x86 目录,修改路径为:

1
cd /usr/src/linux-2.6.23.12/arch/x86/kernel

问题 2:make modules 非常慢

解决方案

  • 使用多核编译:sudo make -j4 modules(4 为 CPU 核心数)
  • 虚拟机分配更多 CPU 和内存

问题 3:编译报错缺少依赖

解决方案:安装必要的编译工具:

1
2
sudo apt-get update
sudo apt-get install build-essential libncurses5-dev

问题 4:系统调用返回 -1

解决方案

  • 检查系统调用号是否正确
  • 确认 NR_syscalls 已更新
  • 查看 dmesg 输出是否有错误信息

✅ 总结与建议

关键要点

  1. 耐心:内核编译耗时较长,尤其是 make modules
  2. 备份:修改前备份重要文件
  3. 版本匹配:确保内核版本与教程一致
  4. 日志查看:善用 dmesg 调试

学习收获

  • 理解 Linux 内核编译流程
  • 掌握系统调用添加方法
  • 熟悉内核模块机制
  • 提升 Linux 系统底层认知

📚 参考资料

祝各位实验顺利!如有问题欢迎交流讨论! 🎉