- 博客(43)
- 资源 (8)
- 收藏
- 关注
原创 昇思MindSpore介绍
昇腾计算,是基于昇腾系列处理器构建的全栈AI计算基础设施及应用,包括昇腾Ascend系列芯片、Atlas系列硬件、CANN芯片使能、MindSpore AI框架、ModelArts、MindX应用使能等。华为Atlas人工智能计算解决方案,是基于昇腾系列AI处理器,通过模块、板卡、小站、服务器、集群等丰富的产品形态,打造面向“端、边、云”的全场景AI基础设施方案,涵盖数据中心解决方案、智能边缘解决方案,覆盖深度学习领域推理和训练全流程。昇腾AI全栈如下图所示:昇腾应用使能。
2024-06-19 20:14:57
1106
原创 添加硬盘驱动 - 写磁盘
hd.c中#define WIN_WRITE 0x30char testbuf[256]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30};static void write_intr(void){ printk("write_intr\n");}void
2014-04-20 20:56:05
906
原创 添加硬盘驱动 - 读磁盘
修改hdhd_interrupt: pushl %eax pushl %ecx pushl %edx push %ds push %es push %fs movl $0x10,%eax mov %ax,%ds mov %ax,%es movl $0x17,%eax mov %ax,%fs movb $0x20,%al outb %al,$0xA0 # EOI to
2014-04-18 17:41:43
1114
原创 添加硬盘驱动-读identify
添加hd.c#include #include #include #include #include #include extern void hd_interrupt(void);#define port_read(port,buf,nr) \__asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr):)#define
2014-04-14 18:09:32
2056
原创 完善键盘
#include #include char key_map[]={ 0,27, '1','2','3','4','5','6','7','8','9','0','-','=', 127,9, 'q','w','e','r','t','y','u','i','o','p','[',']', 13,0, 'a','s','d','f','g','h','j','k','l',';'
2014-04-06 20:08:24
617
原创 多任务
得得得、dunsigned int TOTAL_TASK=0;//此变量记录了我们总的任务数,初始值为0.#define FIRST_TSS_ENTRY 4//第一个TSS,存在于gdt中的第4项#define FIRST_LDT_ENTRY 5//第一个LDT,存在于gdt中的第5项#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_T
2014-02-11 11:36:50
1056
原创 任务切换
首先我们的中断处理函数过于简单,起码应该保持相关的寄存器,所以System_call.S修改如下:.globl timer_interrupttimer_interrupt: push %ds pushl %edx pushl %ecx pushl %ebx pushl %eax movl $0x10, %eax mov %ax, %ds incl jiffies movb
2014-01-07 17:55:24
1058
原创 时钟中断处理函数
以前的中断处理函数只做为测试用,其实问题还很多,我把它放到了一个专门的文件中,kernel/System_call.S代码如下:.globl timer_interrupttimer_interrupt: incl jiffies movb $0x20,%al outb %al,$0x20 call do_timer iretmain.c中添加extern voi
2014-01-06 18:26:41
1942
原创 把进程放到ldt中
其实一个进程应该放到一个ldt中先创建我们的ldt表//ldt表struct desc_struct ldt[3];#define lldt() \__asm__ ("movw $0x48,%%ax\n\t" \ "lldt %%ax\n\t" \ :::"ax")#define DA_LDT 0x82下面的工作就是在gdt中设置ldt,然后在ldt中填充正确的值
2014-01-06 18:07:10
1072
原创 从进程到内核---ring3到ring0
这次我们用中断来实现从ring3到ring0的跳转,当我们用中断门实现从ring3到ring0的转移时,会从TSS加载ring0的堆栈STACKR0,然后将调用者ring3的ss、esp压入新堆栈STACKR0,然后EFLAGS压入堆栈,然后将当前ring3的cs和ip入栈,然后加载调用门中的新的cs和ip,使IF=0,开始执行中断服务函数。那么首先我们要准备TSS,其结构如下:typed
2013-10-10 13:05:44
7222
原创 一个简单的进程----跳到ring3
进程都是工作的特权级ring3下的,如何跳到ring3呢?我们用iret指令,不过在这之前我们要准备好ring3的堆栈,设置ring3的代码段,为了能在ring3模式下能够打印我们还要修改视频段,还记得前面《ring0到ring3》是如何做的吗?我们先写一个函数_set_gdt_desc来修改gdt,代码非常的简单,无非是设置gdt中的描述符。typedef unsigned int u32
2013-10-09 17:24:48
1272
原创 整理文件夹
目前我们所有的文件都在一个文件夹下,目录结构如下以后代码越来越多,管理起来很不方便,下面我们就仿照linux的目录结构来整理一下:新建一个boot文件夹,将bootsect.S、head.S、setup.S此文件夹下;新建include文件夹,在此文件夹下新建asm和linux文件夹,asm文件夹下添加io.h和system.h,linux文件夹下添加head.h;新建init文件夹并将mai
2013-10-09 14:57:48
1260
原创 设置中断门与陷阱门
通过前面中断的实验我们知道LABEL_IDT是放到内存中的一张表,里面是一个一个的门描述符,对应相应的中断向量。我们的工作就是在描述符中填充相应的内容。为了能在c中设置中断门,我们在head.S中添加.globl LABEL_IDT,这样在c中我们就可以使用了,我们在main.c中是这样声明的:typedef struct desc_struct {unsigned long a,b;
2013-09-23 16:46:01
2487
原创 改写load_system
前面提到过我们装载system的时候有问题,当system还很小的时候可以应付,后面如果变大我们没办法把它全部读入内存,下面我们就来修改启动扇区中的load_system将全部的system读入内存。 load_system: movb $0x00,%dl mov $0x0800,%ax int $0x13 movb $0x00,%ch
2013-09-14 14:12:54
1256
原创 加入库函数
加入一些实用的打印功能,这对我们的调试是大有帮助的,我们单独放到kliba.S文件中 .data.global disp_strdisp_pos: .4byte ((80 * 6 + 0) * 2) .text .globl disp_str,disp_int.code32/********************************************
2013-09-14 14:04:05
858
原创 跳到main函数
首先我设计一个简单的mian.c,打开中断然后进入死循环。#define sti() __asm__ ("sti"::)void main(void) { sti(); while(1);}同时对应的我们把head.S中是sti注释掉代码如下:#define Descriptor(base,lim,attr)\.word lim&0xffff;\.
2013-08-27 15:28:40
947
原创 启动分页机制
head.S代码变大了许多这时你在引导扇区读取system时要多读几个扇区,经测试最多可以读0x48个,我们就先这么凑合吧,等日后再改。head.S代码如下:#define Descriptor(base,lim,attr)\.word lim&0xffff;\.word base&0xffff;\.byte (base>>16)&0xff;\.word ((lim>>8)
2013-08-27 15:15:52
814
原创 时钟中断测试
第一步首先在setup中打开时钟中断,set_8259A修改如下 set_8259A: movb $0x11,%al//0x11表示边沿触发,多片级联,需要ICW4 out %al,$0x20//主8259,ICW1 .word 0x00eb,0x00eb out %al,$0xA0//从8259,IWC1 .word 0x00eb,0x00eb
2013-08-27 11:03:48
1028
原创 设置中断
head.S代码如下:#define Descriptor(base,lim,attr)\.word lim&0xffff;\.word base&0xffff;\.byte (base>>16)&0xff;\.word ((lim>>8)&0xf00)|(attr&0x0f0ff);\.byte ((base>>24)&0xff) #define Gate(
2013-08-27 10:58:08
1140
原创 重新加载gdt
system的任务很重仅打印一个字符可不行,首先我们重新加载gdt。代码如下:#define Descriptor(base,lim,attr)\.word lim&0xffff;\.word base&0xffff;\.byte (base>>16)&0xff;\.word ((lim>>8)&0xf00)|(attr&0x0f0ff);\.byte ((base>>
2013-08-27 10:53:57
1076
原创 搬运system到0地址
do_move用于将system移动到0地址,然后将Descriptor_SYSTM的基地址改为0,为了简单我把上面设置8259A的内容去掉了。测试代码如下:#define Descriptor(base,lim,attr)\.word lim&0xffff;\.word base&0xffff;\.byte (base>>16)&0xff;\.word ((lim>>8)
2013-08-27 10:40:36
1018
原创 setup中设置8259A
主要加入set_8259A代码代码如下:#define Descriptor(base,lim,attr)\.word lim&0xffff;\.word base&0xffff;\.byte (base>>16)&0xff;\.word ((lim>>8)&0xf00)|(attr&0x0f0ff);\.byte ((base>>24)&0xff)
2013-08-27 10:26:13
1035
原创 加入system
system部分就是将来我们的内核部分,现在只有一个简单的head.S,而且就是打印一个字符‘S’,代码如下:SETUPLEN = 4BOOTSEG = 0x7c0INITSEG = 0x9000SETUPSEG = 0x9020SYSSEG = 0x1000ENDSEG = SYSSEG + SYSSIZE.text .globl start/*程序从start
2013-08-27 10:14:22
925
原创 加入setup
一个启动扇区的空间太小了,我们需要更广阔的的空间于是我们加入了setup,我们会在引导扇区中将setup拷贝到内存,然后跳到setup中去执行,不过为了简单我们的第一个setup会非常简单,仅仅打印一句话代码如下:.text .globl start/*程序从start处开始运行*/ .code16 start: jmpl $0x07c0, $code m
2013-08-26 12:49:50
937
原创 拷贝自己
因为有可能在0x7c00处放东西所以将自己拷贝到0x90000处去执行 SETUPLEN = 4BOOTSEG = 0x7c0INITSEG = 0x9000SETUPSEG = 0x9020SYSSEG = 0x1000ENDSEG = SYSSEG + SYSSIZE.text .globl start/*程序从start处开始运行*/ .code1
2013-08-21 17:29:21
852
原创 关于链接地址
回过头来看我们的Helloworld程序,在Makefile中-Ttext 0x7c00,链接地址为0x7c00,code标号的偏移地址为0x15,则链接后其地址为0x7c15, 其他函数调用此函数时,也就会调用地址0x7c15,这时jmpl $0, $code语句反汇编后为:假如我们在Makefile中改为-Ttext 0x0,因为code标号的偏移地址为0x15,则链接后其地址为0
2013-08-21 16:51:40
1628
原创 sensor之libraries层(1)
C++中的JNI 相关文件:/frameworks/base/core/jni/android_hardware_SensorManager.cpp;Java和C++的函数对应关系本层及以下的所有相关代码都是为了实现这几个函数。static JNINativeMethod gMethods[] = { {"nativeClassInit", "()V",
2013-01-31 20:21:08
3423
原创 sensor之Application Framework层
相关文件目录:/frameworks/base/core/java/android/hardware/SensorManager.java这个SensorManager主要负责返回传感器类型,从底层获得数据。getSystemService(Stringname)是根据名字返回相应的Manager,这个机制也比较重要,网上有相关资料,在此不展开讨论了;mSensorManager.getDef
2013-01-31 12:57:02
3617
原创 sensor架构之app层
下面我们以重力感应为例,写一个简单的apk,看一下sensor到底是如果工作的,一般我们需要下面四个步骤来实现一个sensor应用。1.通过getSystemService获取sensor服务,其实就是初始化一个SensorManager实例。SensorManager mSensorManager=(SensorManager) getSystemService(SENSOR_S
2013-01-30 21:00:25
6481
原创 android sensor架构详解
个人比较喜欢这个图,我们就按照这个图从Applications层一直分析到底层driver。第一篇:sensor架构之app层第二篇:sensor架构之Framework层第三篇:sensor架构之Libraries层第四篇:sensor架构之HAL层第五篇:sensor架构之Driver
2013-01-30 20:46:10
5580
原创 特权级--ring3到ring0
还记得吗?我们用调用门和lcall指令实现特权级由低到高的转移.假设我们想由代码A转移到代码B,运用一个调用门G,即调用门G中的目标选择子指向代码B的段。实际上我们要考虑4个要素:CPL、RPL、DPL_B(代码B的DPL)、DPL_G(调用门G的DPL)。第一步,当A访问调用门G时,规则相当于访问一个数据段,要求CPL和RPL都小于或者等于DPL_G.也就是CPL和RPL需要在更高的特权
2013-01-15 17:29:28
1459
原创 特权级--ring0到ring3
内核要和用户程序分开,内核一定要安全,不能被用户程序干涉,但是有时候用户程序也需要读取内核的某些数据,怎么办呢?x86就引入了访问特权等级(0-3)的机制,x86 cpu共有4个特权级 level0 到 level3 其中level0特权级最高,level3特权级最高。处理器通过识别CPL、DPL、RPL这3中种特权级进行特权级检验。CPL(Current Privilege Level)是当
2013-01-15 11:21:11
2903
原创 调用门
门,顾名思义它是一扇门通向令一个地方,看一下门的结构里面有一个描述符和一个偏移值,门中定义了这扇门通向的目的地,当我们调用一个门的时候会到达这个地方:门中的选择子:门中的偏移值,也即下图的selector:offset这是我们代码中国定义的门的数据结构:#define Gate(Selector,Offset,PCount,Attr)\.2byte (Offset&0xff
2013-01-11 10:39:57
2543
原创 局部描述符表LDT
上一篇为了简单我们只涉及到GDT,其实LDT跟它差不多,跳转的时候选择子的第3位也就是TI位为0我们就用GDT,如果TI=1我们就用LDT。总结如下:TI=0时:CS:IP=全局描述符表中第1(0x8>>3)项描述符给出的段基址+0的偏移地址TI=1时:CS:IP=局部描述符表中第1(0x8>>3)项描述符给出的段基址+0的偏移地址局部描述符表在哪里?这要问ldtr寄存器了,ldt
2013-01-09 11:02:17
2912
原创 认识保护模式
想看懂linux内核必须要理解保护模式,也许它并不复杂只是书上讲的太抽象了,下面让我们来认识一下保护模式,在这里我们只考虑全局描述符表GDT。先来看下面两个重要的寄存器CS:代码段寄存器(Code Segment Register),其值为代码段的段值IP:指令指针寄存器,它用来存放代码段中的偏移地址。在程序运行过程中,它始终指向下一条指令的首地址,它与代码段寄存器CS联用确定下一条指
2013-01-07 17:33:24
1844
51单片机工具软件集合
2009-05-07
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人