Browsed by
Category: Kernel

Running Arch Linux with customized kernel in QEMU

Running Arch Linux with customized kernel in QEMU

本文为内核爱好者们介绍一个便利的运行内核的方式,使用 QEMU + virtio 启动一个装载着自定义内核的 Arch Linux。 0x00 构建内核 我们使用 Arch Linux 发行版使用的 .config 作为配置文件, 可以省却很多自己配置 Kernel Options 的繁琐工作。将配置文件放入 kernel source tree 后,使用 make oldconfig 就可以通过一个交互的命令行将最新的内核里的可配置参数补全到我们使用的 Arch Linux 的 .config 文件中。 我们有两种方式获取到 Arch Linux (和其他发行版) 的 .config 文件: 使用 zcat 读取 /proc/config.gz 的内容并且保存为 .config 直接复制 `/usr/lib/modules/$(uname -r)/build/.config 若要使用方法 1 ,内核需要开启 Enable access to .config through /proc/config.gz 这一选项需要我们将 IKCONFIG_PROC 设置为 y (相关依赖 option 项目也需要满足) 配置文件准备好后,我们就可以开始构建内核了,如果你会频繁构建内核,建议使用 ccache 来缓存编译的中间目标文件 “*.o”。ccache 具体配置方法这里不多做介绍,简单说下使用方法,很简单,只需要在 gcc,cc,g++,c++ 的前面加上 ccache 即可,e.g 使用 ccahe 编译内核的构建命令可以这样写: make CC=”ccache gcc” -j8。注意:ccache 不会提升首次编译的速度,它会将这些中间文件缓存起来,在后续的…

Read More Read More

Kernel Bootup Page Table Initialize Process(x86_64)

Kernel Bootup Page Table Initialize Process(x86_64)

This article will provide detailed information about the kernel bootup page table setup. In a brief view, the kernel setup page table in three steps: Setup the 4GB identity mapping Setup 64bit mode page table early_top_pgt Setup 64bit mode page table init_top_pgt The last two steps are both higher mapping: Map the 512MB physical address to virtual address 0xffff80000000 – 0xffff80000000 + 512MB. Next, we will talk about the details. We will use the 4.14 version code to explain the process….

Read More Read More

Kernel Driver btusb Overview

Kernel Driver btusb Overview

Function btusb_probe btusb_probe is use for hot plug-in for bluetooth usb generic controller, here will explain the function in detail. First is an interface check mechanism This special condition is used for supporting apple Macbook 12,8 (2015 early). According to the normal specification, the main interface for USB is 0, and audio (isochronous) is 1, but apple made a change on it, changing the main interface to 2 and audio to 3. The “bInterfaceNumber !=2 ” is for checking hardware…

Read More Read More

Linux Kernel Development Resources

Linux Kernel Development Resources

Here are some resources for digging into linux kernel development (Keep updating) Books Understanding Linux Kernel [ULK] Linux Kernel Development [LKD] Linux Driver Development [LDD] Linux Kernel Module Programming Guide [LKMPG] Linux in a Nutshell   Sites Eudyptula Challenges: A step-by-step challenge for kernel newbies to get familiar with kernel. it promise you can get into kernel development after finish all tasks http://eudyptula-challenge.org/ The Linux Documentation Project: Website provide useful resources for linux & kernel http://www.tldp.org/ The Linux Kernel Archives: Official Kernel…

Read More Read More

ULK Chapter2 总结

ULK Chapter2 总结

本章的知识结构如下 地址转换过程 –Logical Address–> [Segment Unit] –Linear Address–> [Paging Unit] –Physical Address–> 谈到内存地址,具体来讲有三种不同类型的地址,逻辑地址,线性地址,物理地址。 逻辑地址对应内存的分段 线性地址对应分页 物理地址对应到硬件芯片上的内存单元的地址 MMU通过Segment Unit与Paging Unit两个硬件电路将一个逻辑地址转为物理地址, 具体转换过程如上代码段所示 下面对整个转换过程进行概述 段选择符 15 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +T+ R + + index +I+ P + + + + L + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [0-1]RPL: 请求者特权级 [2]TI: Table Indicator, 指明是从GDT还是LDT中取出段描述符(Segment Descriptor) [3-15]index:用来指定从GDT中第index项取出Segment Descriptor 段描述符 对段描述符的解释参考 [不是科普向?] RE: 从零开始的操作系统开发 第二集 中相应内容即可 Logical Addr ===> Linear Addr 逻辑地址的高16位为段选择符(Segment Selector)其余32位(或者64位)为偏移量(Offset) 流程如下 检查TI确定是从GDT(TI=0)还是从LDT(TI =1)中选择段描述符 从Segment Selector的index字段计算出段描述符的地址,计算方法 index * 8 (一个Segment Descriptor大小为8) 并与gdtr/ldtr中的内容相加得到Segment Descriptor 把逻辑地址的offset字段与Segment Descriptor中的Base字段相加,得到Linear Address   而Linux中的分段只是一个兼容性考虑,分段和分页的作用是重复的,分页能以更精细的粒度对内存进行管理,因而在Linux中分页是主要的手段,Linux分段中的用户代码段,数据段,内核代码段,数据段,都是以Base = 0…

Read More Read More

将内核编译到自定义的目录下

将内核编译到自定义的目录下

参考wiki: https://wiki.archlinux.org/index.php/Kernels/Traditional_compilation 使用ArchLinux作为构建Linux的环境 方法如下 假设我们的customized directory为kernel-build 我们必须在kernel-tree目录结构下对内核进行编译,假设kernel-tree目录名为linux-kernel 下面是具体的操作: make menuconfig # Change the local version in General Settings make -j8 make modules -j8 sudo make modules_install 在 make menuconfig 的时候,最好对内核版本进行修改,使之不会在make modules_install的时候覆盖掉现有内核的modules 修改途径为General Setup里的Local Version项 这样执行之后,应该在arch/ARCH/boot/下面存在bzImage内核镜像,并且modules应该被安装在了/lib/modules/<linux-version>-<localversion> 下 下一步操作, 修改linux.preset文件,并创建initrd文件 ## Change to kernel-build directory cp ../arch/<arch>/boot/bzImage [image-name] cp /etc/mkinitcpio.d/linux.preset . 修改linux.preset文件, 修改完毕后的内容类似下面 # mkinitcpio preset file for the ‘linux’ package ALL_config=”/etc/mkinitcpio.conf” ALL_kver=”/home/void001/linux-kernel/kernel-build/vmlinuz” PRESETS=(‘default’ ‘fallback’) #default_config=”/etc/mkinitcpio.conf” default_image=”/home/void001/linux-kernel/kernel-build/initramfs-linux.img” #default_options=”” #fallback_config=”/etc/mkinitcpio.conf” fallback_image=”/home/void001/linux-kernel/kernel-build/initramfs-linux-fallback.img” fallback_options=”-S autodetect” 我们需要修改ALL_kver, default_image, fallback_image三个选项,使其将image保存到指定的目录下 然后使用 mkinitcpio -p ./linux.preset 创建initrd, initrd-fallback,目前kernel-build目录应该有如下文件: ╰─➤ ls…

Read More Read More

My Yearly Goals

My Yearly Goals

—–BEGIN PGP MESSAGE—– Version: GnuPG v2 hQIOA2jnx9T3JM9SEAf/VSB3nCEOzyJEf9RRSI76xw4kv9VS7IJmeg80fNAcViYQ sn2PaRSYMC1X0nqOzpqOzYW5LIArSEehrr/Z085gOjNi/2rkDwSD3WGGXgUdSZRZ 10gRLoRE/CZw212CNZi0AV0GT7Zw5jizpJt4kh5Zn/RnrdxHCtSMaTJpIbOYhmca FQJfcLRp5unSUooOY1PREESA4tpaUy9kz4dgttnCPnq8DLeshkD5xMAloAFR13li TBeG/tqHKjNUZT5oLUSLxs9EXnG9LTLB+lJ4C0sdY6KW7Ad7SMzymTWSnjeYHxp+ 4FDhqGhrJwrBC3Gh63YLTLXALc2NBQ5s32trpSPV5wgAj2LKcSiiBxXh8LgjT+Em mGYIgs6drCwowBi/A6RDxA7kdnMVT9cSk6XjMIQjb0mG3JGnNYWEjRHx+5P4ZlsM tfv153RAbRaGCOSoJ8pm2NOmaGs7wgTv9yKRUGIFzROWsPOTx+Q1UGnurIFFa9LG lU42EXsIa7lzxsCgNx8vXqonTwRPinspfRUea/URgbCkIpnyVSIkFXujY+HAdRRo V8WRxq6Rm78YNMigt3lim7NLmYIk8K3CAz92+q5oRolIgCbqwN6dGHpJSDLBoKX8 7nFQQsrFOh5lSv/ZO0upjuye0JJTwU1yzcYRH7B0r2aMzxxMWu0ZB6kilq/RaDp9 nNLpAVHBo6oXX5j8+2k22F2vZVSTUl1SJgKahHOzTUQTK+rIESX5XTwJctJ0Eb/c jjaHV3GDZSGZBK6Ib+Ez+4SIqXZg26d5bnXbBS/iHL2baErZE4sFzEf8JsYbq3ZO 5Xk3eBURiLwwrl3ftu2O7/Mv6AUFyYSaWJWanYPMGm0I3NDYmaMWWIRPRD6wE32R bklG/xvktnLkp75nk0FKqVPXlci0aeAzxVYvsvd9CnkcDxeEi3WdLRlyhE5xsLRv CL4KpQzw7d6Rg2TZ0kn7gHYmS0HJHLDf7VrUndLcDMjiF/wrBfxH/ZsfIKxmfzMd LgIWYefwVWndpejO5FMlzl+7NFFy+Uc036iWUXcfScbyChujdYRGyyJy8B9zJmhf pBescXTzjpCp7yySmz11FpBUNpfA6Bg44T8t2ERlNMae4ZuL+U25y8E0QgiUJTHe guDWpdhxLESXRi7TF9D0k0DWWguUAsJlioQJZDRMZze+pLOwMa0bdgqbJFMexQQk IKs9rzobcM1a0aeIEyytCiVdDiEmcc/PEwJ7yDaZ7aQvknP92p9xDZl0flzlLbbp 6bjxHySKV13QKoE1ymmsZjqLqqLlHLDz3lOs2gb0ZEG64N/8grRimGCOhNj+U7pH rvuBR3lJMFyjI8MKmEPViupXXoYr8tDQC+f11CccT5IS65gqJ5pwNDBRU4BMkg6A 7Z7wnNvZzt5aNKW+tYYqknR//qTpEYgFCxoEp24n =CB7d —–END PGP MESSAGE—–  

[科普向?] Re: 从零开始的操作系统开发 第一集

[科普向?] Re: 从零开始的操作系统开发 第一集

Hmm, 果然还是开坑了~! 在学校智障的操作系统课设的发起下, 再加上每个程序员都有一个写一个自己的操作系统的公主梦(雾), 我们愉(作)快(死)地开坑啦~ 以前曾经跟着 “30天自制操作系统” 玩过DIY操作系统, 不过那个书更像面向小白, 讲的东西也不够系统, 而且使用的是自己改过的nas汇编器, 因而不能算写过, 这一次则是真正的开坑啦~ (虽然课设时间很短写出一个完整的根本不可能不过慢慢写总会写完的你说对不喵~) 我们的开发过程在Bearychat上直播 neugeek.bearychat.com 的Toy-OS频道, 我们的git-repo 为 https://github.com/VOID001/toy-os 菊苣们不要喷, 既然挖了坑窝就不会不填(….你都已经挖了多少个坑了啊喂! (逃)) 这个系列的文章将会记录在开发操作系统的整个过程中的一些经验&心得&吐槽 不知道会有多少集(   参考资料们: MIT 的 XV6 源代码 & handbook University of Birmingham 的 Writing an simple operating system from scratch Quora, StackOverflow Jiong Zhao Linux 0.11内核完全注释   我们使用的工具链: GNU Assembler & GNU C Compiler Qemu Gdb objcopy, objdump, binutils, elfutils GNU Makefile   操作系统编写总览 什么是BIOS 参考阅读: http://whatis.techtarget.com/definition/BIOS-basic-input-output-system 我们的定位是写一个操作系统,那么首先我们应该了解,整个操作系统都应该由哪些模块构成, 那么就让我们从操作系统的启动说起, 说到这里就不得不说一下BIOS, BIOS是Basic Input and Output System, 是你的计算机加电运行后加载的第一个程序, 它是固化在你的EPROM内的一个程序片段…

Read More Read More

[C Linux内核] 文件与I/O

[C Linux内核] 文件与I/O

系统调用 Hello world 先看一个例子,利用系统调用sys_write用汇编实现的向stdout输出hello world .data msg: .ascii “Hello, world!\n” len = . – msg .text .global _start _start: movl $len, %edx # third argument: message length movl $msg, %ecx # second argument: pointer to message to write movl $1, %ebx # frist argument: file handle(here stdout) movl $4, %eax int $0x80 movl $0, %ebx movl $1, %eax int $0x80 将_start作为 ELF linker or loader的 外部可以使用的符号(通过 .global) 并且在.data段内定义一个标号msg,代表字符串Hello world 的首地址,  定义len的时候用到的 . 是一个用来代替当前段内地址(在每一个段开头, “.” 的值都会初始化回0)因而, len的值就是当前地址减去msg的首地址, 换句话说,就是 字符串常量”Hello world\n”长度, 上面的代码进行了两次系统调用,…

Read More Read More