linux kernel 0.11 setup
setup作用
①读取参数放在0x90000处。
②将原本在0x10000处的system模块移至0x00000处
③加载中断描述符表,全局描述符表,进入32位保护模式。
概念
关于实模式和保护模式区别及寻址方式,该博客已经很详尽:http://blog.csdn.net/rosetta/article/details/8933200,只是有个别信息没有。
IDT:Interrupt Descriptor Table--中断描述表
GDT:Global Descriptor Table --全局描述表
LDT:Local Descriptor Table --局部描述表
在Intel架构中,更准确的说是保护模式下,大部分内存管理和中断服务例程都通过描述符表来控制。每个描述符存储了CPU随时可能需要获取的一个单个对象(例如服务例程、任务、一段代码或数据等)的信息。如果试图装载一个数据到一个段寄存器中,CPU需要进行安全性和访问控制检查,来确认是否获得了访问该内存区域的许可。一旦检查结束,一些有用的信息(例如最低和最高地址)被缓存在CPU中的几个不可见的寄存器中。
Intel定义了3种类型的描述符表:中断描述符表IDT(用以替换中断向量表IVT)、全局描述符表GDT和局部描述符表LDT。每个表分别通过LIDT、LGDT、LLDT指令以(size, linear address)的形式定义(注:是载入描述符表的指令,这里就是说表包含了大小和基址组成。)。大多数情况下,操作系统中启动期指定这些表的位置,然后通过一个指针直接读写这些表。
setup源代码注释
!
! setup.s (C) Linus Torvalds
!
! setup.s is responsible for getting the system data from the BIOS,
! and putting them into the appropriate places in system memory.
! both setup.s and system has been loaded by the bootblock.
!
! This code asks the bios for memory/disk/other parameters, and
! puts them in a "safe" place: 0x90000-0x901FF, ie where the
! boot-block used to be. It is then up to the protected mode
! system to read them from there before the area is overwritten
! for buffer-blocks.
! ! NOTE! These had better be the same as in bootsect.s! INITSEG = 0x9000 ! we move boot here - out of the way
SYSSEG = 0x1000 ! system loaded at 0x10000 ().
SETUPSEG = 0x9020 ! this is the current segment .globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text entry start
start: ! ok, the read went well so we get current cursor position and save it for
! posterity.
! input:
! BH = page number.
! return:
! DH = row.
! DL = column.
! CH = cursor start line.
! CL = cursor bottom line.
mov ax,#INITSEG ! this is done in bootsect already, but...
mov ds,ax
mov ah,#0x03 ! read cursor pos
xor bh,bh
int 0x10 ! save it in known place, con_init fetches
mov [],dx ! it from 0x90000.光标的行 列的值 ! Get memory size (extended mem, kB) 内存大小 mov ah,#0x88
int 0x15
mov [],ax ! Get video-card data: 声卡数据 mov ah,#0x0f
int 0x10
mov [],bx ! bh = display page
mov [],ax ! al = video mode, ah = window width ! check for EGA/VGA and some config parameters VGA和配置参数 mov ah,#0x12
mov bl,#0x10
int 0x10
mov [],ax
mov [],bx
mov [],cx ! Get hd0 data 磁盘第一分区数据 mov ax,#0x0000
mov ds,ax
lds si,[*0x41]
mov ax,#INITSEG
mov es,ax
mov di,#0x0080
mov cx,#0x10
rep
movsb ! Get hd1 data 磁盘第二分区数据 mov ax,#0x0000
mov ds,ax
lds si,[*0x46]
mov ax,#INITSEG
mov es,ax
mov di,#0x0090
mov cx,#0x10
rep
movsb ! Check that there IS a hd1 :-) 检查是否存在第二个硬盘,不存在则清空磁盘二的参数表 mov ax,#0x01500
mov dl,#0x81
int 0x13
jc no_disk1
cmp ah,#
je is_disk1
no_disk1: !清空磁盘二的参数表
mov ax,#INITSEG
mov es,ax
mov di,#0x0090
mov cx,#0x10
mov ax,#0x00
rep
stosb
is_disk1: ! now we want to move to protected mode ...开始我们要保护模式方面的工作了。 cli ! no interrupts allowed !cli是关中断,防止有些硬件中断对程序的干扰 sti是开中断,允许硬件中断 ! first we move the system to it's rightful place mov ax,#0x0000
cld ! 'direction'=0, movs moves forward cld即告诉程序si,di向前移动,std指令为设置方向,告诉程序si,di向后移动
do_move: ! 0x1000=64k 循环移动ds:si->es:di数据,总共移动cx=(0x9000-0x1000)=0x8000的数据
mov es,ax ! destination segment
add ax,#0x1000
cmp ax,#0x9000
jz end_move
mov ds,ax ! source segment
sub di,di
sub si,si
mov cx,#0x8000
rep
movsw
jmp do_move ! then we load the segment descriptors end_move: ! 从实模式进入保护模式
mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-)
mov ds,ax
lidt idt_48 ! load idt with , 指令以(size=, linear address=)的形式加载中断描述符表
lgdt gdt_48 ! load gdt with whatever appropriate
! 指令以(size=0x800, linear address=+gdt,0x9)的形式加载全局描述符表 ! that was painless, now we enable A20 call empty_8042!等待为空
mov al,#0xD1 ! command write
out #0x64,al
call empty_8042
mov al,#0xDF ! A20 on
out #0x60,al
call empty_8042 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
! we put them right after the intel-reserved hardware interrupts, at
! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
! messed this up with the original PC, and they haven't been able to
! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
! which is used for the internal hardware interrupts as well. We just
! have to reprogram the 's, and it isn't fun. mov al,#0x11 ! initialization sequence
out #0x20,al ! send it to 8259A-
.word 0x00eb,0x00eb ! jmp $+, jmp $+
out #0xA0,al ! and to 8259A-
.word 0x00eb,0x00eb
mov al,#0x20 ! start of hardware int's (0x20)
out #0x21,al
.word 0x00eb,0x00eb
mov al,#0x28 ! start of hardware int's (0x28)
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0x04 ! - is master
out #0x21,al
.word 0x00eb,0x00eb
mov al,#0x02 ! - is slave
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0x01 ! mode for both
out #0x21,al
.word 0x00eb,0x00eb
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0xFF ! mask off all interrupts for now
out #0x21,al
.word 0x00eb,0x00eb
out #0xA1,al ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
! need no steenking BIOS anyway (except for the initial loading :-).
! The BIOS-routine wants lots of unnecessary data, and it's less
! "interesting" anyway. This is how REAL programmers do it.
!
! Well, now's the time to actually move into protected mode. To make
! things as simple as possible, we do no register set-up or anything,
! we let the gnu-compiled -bit programs do that. We just jump to
! absolute address 0x00000, in -bit protected mode. mov ax,#0x0001 ! protected mode (PE) bit
lmsw ax ! This is it!
jmpi , ! jmp offset of segment (cs) ! This routine checks that the keyboard command queue is empty
! No timeout is used - if this hangs there is something wrong with
! the machine, and we probably couldn't proceed anyway.
empty_8042:
.word 0x00eb,0x00eb
in al,#0x64 ! 8042 status port
test al,#2 ! is input buffer full?
jnz empty_8042 ! yes - loop
ret gdt:
.word 0,0,0,0 ! dummy .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9A00 ! code read/exec
.word 0x00C0 ! granularity=4096, 386 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9200 ! data read/write
.word 0x00C0 ! granularity=4096, 386 idt_48:
.word 0 ! idt limit=0
.word 0,0 ! idt base=0L gdt_48:
.word 0x800 ! gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 ! gdt base = 0X9xxxx .text
endtext:
.data
enddata:
.bss
endbss:
linux kernel 0.11 setup的更多相关文章
- linux kernel 0.11 head
head的作用 注意:bootsect和setup汇编采用intel的汇编风格,而在head中,此时已经进入32位保护模式,汇编的采用的AT&T的汇编语言,编译器当然也就变成对应的编译和连接器 ...
- linux kernel 0.11 bootsect
bootsect作用 ①将自己移动到0x90000处 ②将setup从磁盘读到0x90200处 ③将system从磁盘读到0x10000处 寄存器 汇编代码中存在:数据段data seg 栈段 sta ...
- Linux内核0.11 setup文件说明
一.总体功能介绍 这是关于Linux-kernel-0.11中boot文件夹下setup.s源文件的实现功能的总结说明. setup.s是一个操作系统加载程序,它的主要功能是利用BIOS中断读取机器系 ...
- Linux Kernel 4.11首个候选版本开放下载
Linus Torvalds宣布了即将到来的Linux Kernel 4.11内核分支的首个候选(RC)版本,用户可下载.编译并在自己的GNU/Linux发行版本中进行测试.Linus Torvald ...
- Linux Kernel 0.12 启动简介,调试记录(Ubuntu1804, Bochs, gdb)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- Linux内核0.11代码阅读(转)
最近决定开始阅读Linux 0.11的源代码. 学习Linux操作系统的核心概念最好的方法莫过于阅读源代码.而Linux当前最新的源代码包已经有70MB左右,代码十分庞大,要想深入阅读十分困难.而Li ...
- Linux内核0.11体系结构 ——《Linux内核完全注释》笔记打卡
0 总体介绍 一个完整的操作系统主要由4部分组成:硬件.操作系统内核.操作系统服务和用户应用程序,如图0.1所示.操作系统内核程序主要用于对硬件资源的抽象和访问调度. 图0.1 操作系统组成部分 内核 ...
- Linux mysql8.0.11安装
准备:检查是否已安装过mysql,若有便删除(linux系统自带的) rpm -qa | grep mariadb rpm -e nodeps mariadb-libs-5.5.56-2.el7.x8 ...
- Linux Kernel 3.11.4/3.10.15/3.4.65/3.0.99
Linux 今天又发布了4个更新版本,分别是: 3.11.4 2013-10-05 [tar.xz] [pgp] [patch] [view patch] [view inc] [cgit] [cha ...
随机推荐
- Begin using git (Part1) - Git的安装与配置
Git提供了适用于Linux, Windows, OSX的客户端, 本节以Windows为例介绍基本安装与配置. 所需工具:msysgit, kdiff3. Get windows installer ...
- Android开发-API指南- Calendar Provider
Calendar Provider 英文原文:http://developer.android.com/guide/topics/providers/calendar-provider.html 采集 ...
- Azure磁盘的吞吐量测试
Azure的高级存储具有吞吐量大,延迟低的特点,非常适合时间关键型的应用程序(如SQL Server, Oracle, Redis等). 但高级存储同时具有价格高的特点,用户往往对其实际的性能数据较为 ...
- dll 学习(一)
DLL(Dynamic Link Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量.函数或类.在仓库的发展史上经历了"无库-静态链接库-动态链接库 ...
- 正则表达式2——grep命令
grep是Global search Regular Expression and Print out the line的简称. 1. grep命令基本用法 命令格式: grep [选项][模式][文 ...
- Server2003安装SP2补丁提示密钥无效的解决方法
机器一直没有打SP2的补丁.几天要安装一个程序,还非要SP2不可.没办法.居然打补丁的时候出现了这样的错误信息: --------------------------- Service Pack 2 ...
- 根据JSON对象动态加载表格--大数据量
EasyUI的DataGrid加载数据的时候,如果列数过多(300列以上),数据渲染及其缓慢. JSON对象格式: 1:rowno 2:title 3:colspan 4:rowspan 5:back ...
- chrome调试学习
参考:http://ued.taobao.com/blog/2012/06/debug-with-chrome-dev-tool/ http://guoshuang.com/frontend/chro ...
- 最简洁粗暴版的虚拟用户配置FTP
最简洁粗暴版的虚拟用户配置FTP yum安装FTP: yum install vsftpd pam* db4* -y 设置为系统服务:chkconfig –level 35 vsftpd on 2.v ...
- C#中的快捷键,可以更方便的编写代码 (转载)
C#中的快捷键,可以更方便的编写代码 CTRL + SHIFT + B 生成解决方案 CTRL + F7 生成编译 CTRL + O 打开文件 CTRL + SHIFT + O 打开项目 CTRL + ...