操作系统入门(五) - 载入32位保护模式代码为c做准备

专注于操作系统24之boot,loader,kernel 在第6篇文章中,我们已能导入操作系统内核(该内核非常小,姑且称为内核),但也只是在实模式下,没有进入保护模式。前面我们已经学习了关于保护模式的很多内容,所以让操作系统进入保护模式是非常简单的。这里先解释一下boot,loader,kernel的意思和作用。boot是引导程序,它的作用是把loader(loader专门用于加载kernel)加载到内存,执行loader。loader是加载程序,它的作 阅读详情
操作系统入门( 五) - 载入32 位保护模式代码为c 做准备
 
经过上千次的试验,终于还是没有能够在vmware实现用一段程序载入kernel.img然后执行32位的kernel代码,无数次的跳出
无奈呀,后来知道实际上是因为gdt全局描述表没有正确载入造成的问题,至于能跳出这样提示的代码,我想没有人愿意去看吧,错的有什么好看的?
 
于是乎找来了鼎鼎大名的 Bochs来帮忙
它能对自己做的操作系统进行调试,如果早些用它的话,我就不会等了3年才又再玩起操作系统来了,说不定已经出了一些成果了呢。
 
但是自己笨没有办法,还是多向别人学习吧。
 
前面做过的程序仅仅是把16位的kernel.img载入到0x90000地址的地方执行,如果要在kernel.img里面再设置保护模式,那么,那个时候还需要从磁盘提取数据的程序,一大堆,现在我发现启动程序里面还可以把设置保护模式的程序加上而没有超过512字节,所以先加上了,试试看用C混合汇编得到的32位代码的执行效果,以后再看看怎么增强kernel.img
 
下面是启动程序
;;     文件 :fatboot.asm
;;     作用 :      从 7c00h 处启动
;;                   把 kernel.img 载入到 0x90000 的地方
;;                   用 32 位方式执行  
;;     有文件系统 ,1.44M 512bits/80sec 软盘启动,
;;     创建日期 :2004/01/30 flyback
;;     修改日期 :2006/04/24 flyback
;;     http://blog.youkuaiyun.com/flyback
;;     mailto:fly-back@163.com
;;     ===================================
 
 
       %define loadpoint 0x9000                          ; 载入点,初始化程序载入到 9000h 的地方
       %define loadoffset 0x0                      
 
       bits 16
       ORG 0x7c00 ; 启动入口地址
main:
       jmp short start              ; 跳转到开始程序入口
       nop                ;
 
; 引导区文件系统数据
;----------------------------------------------------------------------------
       brOEM           DB   ' -My-0S.'              ; 0003h - 引导程序的名字
       brBPS            DW 0x200            ; 000Bh - 每扇区的字节数 512
       brSPC            DB   0x01                     ; 000Dh - 每簇扇区数
       brResCount    DW 0x0001           ; 000Eh - 保留扇区数
       brFATs           DB   0x02                     ; 0010h - FAT 备份数
       brRootEntries DW 0x00e0           ; 0011h - 根目录入口数
       brSectorCount      
                            DW 2880              ; 0013h - 磁盘容量扇区数 < 32MB
       brMedia          DB   240                ; 0015h - 媒体描述符
       brSPF            DW 9                   ; 0016h - 每 FAT 扇区数
       brSPH            DW 18                  ; 0018h - 每磁道扇区数
       brHPC            DW 2                   ; 001Ah - 盘面数
       brHidden        DD 0                   ; 001Ch - 隐藏扇区数
       brSectors       DD 0                   ; 0020h - 如果大于 32m 的扇区总数
                            DB   0                   ; 0024h - 物理驱动器号
                            DB   0                   ; 0025h - 系统保留
                            DB   29H               ; 0026h - 扩展扇区标记(包含 29h )
       brSerialNum     DD    00000006H     ; 0027h - 卷 ID
       brLabel           DB   'teachosdisk'   ; 002Bh - 卷标
       brFSID          DB   'FAT12   '            ; 0036h - 系统保留
;------------------------------------------------------------------------
 
start:
       cli                  ; 关中断,防止意外中断打断程序执行
       mov ax, cs     ;
       mov ds, ax     ; 设置数据段
       mov es, ax      ;
 
       mov ax, 0x0000; 设置堆栈段
       mov ss, ax
       mov sp, 0ffffh       ; 堆栈入口
 
       sti                  ; 开中断
             
       mov si, loadmsg     ; 调用显示载入信息
       call pntchr
 
       ; 把磁盘目录信息载入到 7c00:0200 的地方
loadroot:
       mov        cx, 0
       mov        dx, 0      
       mov        ax, 0x0020                   ; 32 个字节 / 文件
       mul         WORD [brRootEntries] ; 32*224 (文件数) = 7168 (最多所有文件所占的字节数)
       div          WORD [brBPS]                   ; 7168/512 = 14 (Root dir) 文件的目录描述字节占用的扇区数 14
       xchg              ax, cx                          ; CX = 14
       mov        al, [brFATs]                  ; 2
       mul         word [brSPF]               ; 9 * 2 = 18
       add         ax, word [brResCount] ; 18 + 1 now AX = 19
       mov        WORD[datasector], ax         ; 目录起始的扇区 19
       add         WORD[datasector], cx         ; 数据区起始扇区 33
 
       ; 目录放入 0x0200 内存
       mov bx, 0x0200
       call ReadSec
 
       ; 比较目录中是否有 init.img 文件存在
       mov     cx, WORD [brRootEntries] ; CX:224 在目录的所有文件中寻找
       mov     di, 0x0200                   ; 从目录入口处开始 0x200
.LOOP:
       push    cx                                       ; 保护 CX = 224
      
       mov        cx, kernellen                 ; 8 个文件名称和 3 个扩展名称
       lea          si, [kernelname]                   ;
       push              di                                
       repe cmpsb                               ; stop compare if cx >0 or the
                                                        ; first unequal is met(zf=1)!
       pop     di
       je        loadfiledec                      ;if zf = 1, jmp LOAD_FAT!(Seek OK!)
       pop     cx
       add     di, 0x0020                           ; 跳到下一个目录入口
       loop    .LOOP                                 ; cx 自动减
       jmp     failure
 
       ; 载入文件描述子节
loadfiledec:
       ; 把启动的镜像文件 *.img 文件的起始单元保存起来
       mov   si, CRLF
       call    pntchr
       mov si, loadfat
       call    pntchr      
       lea   si, [kernelname]
       call pntchr
 
       mov     dx, WORD [di + 0x001A]                         ;the file's first cluster
       mov     WORD [cluster], dx                  ; store the first cluster
      
       ; 计算 fat 的大小并保存到 07c00:0x0200(ds:bx)
       xor     ax, ax
       mov     al, BYTE [brFATs]                ; al:2
       mul     WORD [brSPF]                ; AH:18 = 9*2
       mov     cx, ax                                                     ; CX:18
 
       ; 读取数据放入到 0x7c00:0x0200 ds:bx
       mov     ax, WORD [brResCount]          ; AX:1
       mov     bx, 0x0200                          ;
       call    ReadSec                                              ; AX:1 CX:18 BX:0200
 
       ; 读取 img 放入 9000:0x0000 处
       mov ax, loadpoint
       mov es, ax
       mov bx, loadoffset
       push    bx
 
LOAD_IMAGE:
       mov     ax, WORD [cluster]     ; cluster to read
       pop     bx                                ; buffer to read into
       call    ClusterLBA                     ; convert cluster to LBA
                                                 ; AX:[cluster] ES:BX[9000:0000](dest)
       xor     cx, cx
       mov     cl, BYTE [brSPC]        ; CL:1
       call    ReadSec                         ; AX:LBA CX:1 BX:0000 ES:0100
       push    bx
      
       ; 计算下一个单元
       mov     ax, WORD [cluster]     ; identify current cluster
       mov     cx, ax                         ; copy current cluster
       mov     dx, ax                         ; copy current cluster
       shr     dx, 0x0001                    ; divide by two
 
       add     cx, dx                          ; sum for (3/2)
       mov     bx, 0x200             ; location of FAT in memory
       add     bx, cx                            ; index into FAT
       mov     dx, WORD [bx]             ; read two bytes from FAT
       test    ax, 0x0001
       jnz     .ODD_CLUSTER
 
.EVEN_CLUSTER:
       and     dx, 0000111111111111b               ; take low twelve bits
       jmp     .DONE
 
.ODD_CLUSTER:
       shr     dx, 0x0004                          ; take high twelve bits
 
.DONE:
       mov     WORD [cluster], dx                  ; store new cluster
       cmp     dx, 0x0FF0                          ; test for end of file,>=0x0FF0: end or bad!
       jb      LOAD_IMAGE                                                 ; if dx<0x0ff0 (CF=1), jmp Load_image
    DONE:                                                                   ; this Label is not used!
       jmp gotopm
      
failure:
       mov si, CRLF
       call pntchr
       mov si, loadfail
       call pntchr
       hlt
      
; ---------------- 子程序区 -------------------------
 
;********************* 显示字符串 ********************************************
;
;
;
;***************************************************************************
 
pntchr:   
       pusha
.pnt:
       lodsb                            ; 从 DS:SI 装载一个字符到 AL
       or al,al                          ;
       jz endpntchr                  ; 如果 al = 0, 返回      
                                          ;
       mov ah,0x0E                ;
       mov bx,0x004a             ; 
       int 0x10                        ; 调用 bios 中断显示字符
       jmp .pnt                ;
                                          ;
endpntchr:                           ;
       popa
       ret                               ; 返回
 
 
;*************************************************************************
; PROCEDURE ReadSec
; 从 ax+1 的地方把 cx 个扇区载入到 es:bx 的内存
; 注意扇区是从 2 开始, 1 扇区已经读入了
;*************************************************************************
ReadSec:
.Main:
 
.secloop:
       push    ax
       push    bx
       push    cx                                                            ;protect ax, bx, cx
 
       call    LBACHS                  ; 调用转换
 
       mov     ah, 0x02        ; BIOS 读取扇区命令
       mov     al, 0x01         ; 一个扇区
       mov     ch, BYTE [Track] ; track
       mov     cl, BYTE [Sector] ; sector
       mov     dh, BYTE [Head]   ; head
       mov     dl, 0                     ; 因为是 a: 所以为 0
       int        0x13                     ; 调用中断
 
       jnc     .SUCCESS                            ; test for read error
      
       xor ax, ax
 
       pop     cx
       pop     bx
       pop     ax
       jnz .secloop
       jmp failure                   ; 错误则显示出错信息并停止
       hlt
      
.SUCCESS
       mov    si, Progress
       call      pntchr
       pop     cx
       pop     bx
       pop     ax
 
       add bx, WORD [brBPS]       ; 读取下一个扇区的内容
       inc   ax                               
       loop .Main                    ; cx -= 1, if cx != 0, jmp .main
       ret
 
;*************************************************************************
; PROCEDURE LBACHS
; 转换逻辑块访问为读取磁盘所使用的磁道,盘面,扇区
; 相对扇区 = ( 逻辑扇区 / 每磁道扇区数 ) + 1
; 相对盘面    = ( 逻辑扇区 / 每磁道扇区数 ) MOD 盘面数
; 相对磁道  = 逻辑扇区 / ( 每磁道扇区数 * 盘面数 )
;*************************************************************************
LBACHS:
       xor     dx, dx                           ; dx = 0
       div     WORD [brSPH]             ; div m16: ax/18 -> 商 :ax 余数 :dx
       inc     dl                                  ;
       mov     BYTE [Sector], dl        ;sector No relative to the Track
       xor     dx, dx                           ; dx = 0
       div     WORD [brHPC]             ; ax/2 -> 商 :ax 余数 :dx
       mov     BYTE [Head], dl           ;
       mov     BYTE [Track], al         ;
       ret
 
;*************************************************************************
; PROCEDURE ClusterLBA
; 转换单元访问到直接扇区访问
; LBA = (cluster - 2) * sectors per cluster
;*************************************************************************
ClusterLBA:
sub     ax, 0x0002                          ; zero base cluster number
xor     cx, cx
mov     cl, BYTE [brSPC]        ; convert byte to word
mul     cx
add     ax, WORD [datasector]               ; base data sector
ret
 
;-------------------- 数据区 -------------------------------
 
loadmsg         db 'Boot',0                                  ; 要显示的字符窜以 0 结尾
loadfail           db 'Load Fail',0                                  ; 载入失败信息
Sector            db 0x00
Head              db 0x00
Track             db 0x00
datasector       dw 0x0000                                 ; 33 数据区起始扇区号
rootaccess      equ 0x0200                                 ; 存放目录数据的偏移地址
cluster            dw 0x0000
CRLF                    db 13,10,0
Progress         db ".", 0
loadfat            db 'Load', 0                                ; 字符串,回车,换行, 0
kernelname     db "KERNEL IMG"                          ; 11 chars                    
kernellen         equ $ - kernelname                      ; 长度
 
gdtr :
dw gdtend - gdt - 1                                                 ; gdt 的长度
dd gdt                                                             ; gdt 的物理地址
gdt:
       gdt0:
       dw 0,0,0,0                                               ; 据说是一定要为 0 否则会有错
codesel_gdt:
       dw   0xffff                                                ; 界限 Limit 值 = 0x100000 * 0x1000 = 4GB
       dw   0                                                      ; 基地址 = 0
       dw 0x9A00                                             ; 表示代码段 可读可执行
       dw   0x00CF                                             ; 粒度(不知道是什么意思)
datasel_gdt:
       dw   0xffff                                                ; 4GB
       dw   0x0                                                   ; 基地址
       dw 0x9200                                              ; 数据段 可读可写
       dw 0x00CF                                             ; 粒度
gdtend:
 
codesel equ codesel_gdt - gdt
datasel equ datasel_gdt - gdt
 
;             从这里启动 32 位的模式
gotopm:
       cli
       lgdt [gdtr]
 
       mov eax, cr0
       or eax,1
       mov cr0, eax
 
       jmp dword codesel:loadpoint * 0x10 + loadoffset
 
; -----------------------------------------------------------------
times 510 - ($ - $$) db 0                     ; 保证 boot 区有 512 个字节
       dw 0AA55h                         ; boot 区标记
 
times 1474560 - ( $ - $$) db 0             ; 大小为 1.44M
 
暗红色的地方做了修改
下面是kernel
;;     =================
;;     文件 :     
;;                   KERNEL.asm
;;     作用 :     
;;                   在 0x90000 处启动
;;                   显示一串信息
;;     创建日期 :
;;                   2006/04/24 flyback
;;     http://blog.youkuaiyun.com/flyback
;;     mailto:fly-back@163.com
;;      =================
[bits 32]
org 0x90000
 
kernel:    
       jmp kernel_start
       msg db 'Portected mode! Start at 0x90000',0
       pos dd 0
       ; re calculate
kernel_start:   
       cli
       lgdt[cs:gdtrs]
 
       mov eax, cr0
       or eax,1
       mov cr0, eax
 
       mov ax, datasels
       mov ds, ax
       mov es, ax
       mov ss, ax
       mov gs, ax
       mov fs, ax
       mov esp, 0x90000
 
       lea esi, [msg]
       call disp
       hlt
 
disp:
              push esi
              push di
              push ax
              ; mov ax, datasels
              ; mov es,ax
.lop:
              mov edi,dword [pos]
              add edi, 0xb8000
              mov al, byte [esi]
              mov ah, 3
              mov [es:edi], ax
              inc dword [pos]
              inc dword [pos]
              inc esi
              test al, al
              jnz .lop
              pop ax
              pop di
              pop esi          
              ret
gdtrs :
dw gdtends - gdts - 1    ; gdt 的长度
dd gdts                         ; gdt 的物理地址
gdts:
       gdt0s:
       dw 0,0,0,0            ; 据说是一定要为 0 否则会有错
codesel_gdts:
       dw   0xffff             ; 界限 Limit 值 = 0x100000 * 0x1000 = 4GB
       dw   0                   ; 基地址 = 0
       dw 0x9A00          ; 表示代码段 可读可执行
       dw   0x00CF          ; 粒度(不知道是什么意思)
 datasel_gdts:
       dw   0xffff             ; 4GB
       dw   0x0                ; 基地址
       dw 0x9200           ; 数据段 可读可写
       dw 0x00CF          ; 粒度
gdtends:
 
codesels equ codesel_gdts - gdts
datasels equ datasel_gdts – gdts
把他们分别编译成fatboot.img和KERNEL.IMG文件然后用WinImage把fatboot.img打开,把kernel.img文件拖入WinImage
保存完毕后就可以使用bochs来调试了
首先要安装好bochs后要写一个批处理文件,一个配置文件
config.txt
# configuration file generated by Bochs
config_interface: textconfig
display_library: win32
megs: 32
romimage: file=E:/ 操作系统 /Bochs-2.1.1/Bochs-2.1.1/BIOS-bochs-latest, address=0xf0000
vgaromimage: E:/ 操作系统 /Bochs-2.1.1/Bochs-2.1.1/VGABIOS-elpin-2.40
boot: floppy
floppya: 1_44="fatboot.img", status=inserted
floppyb: 1_44="none", status=inserted
ata0: enabled=0
ata1: enabled=0
ata2: enabled=0
ata3: enabled=0
parport1: enabled=1, file="parport.out"
com1: enabled=1, dev=""
usb1: enabled=1, ioaddr=0xff80, irq=10
# no sb16
floppy_bootsig_check: disabled=0
vga_update_interval: 300000
keyboard_serial_delay: 250
keyboard_paste_delay: 100000
floppy_command_delay: 500
ips: 1000000
text_snapshot_check: 0
mouse: enabled=0
private_colormap: enabled=0
i440fxsupport: enabled=0
clock: sync=none, time0=local
# no ne2k
newharddrivesupport: enabled=1
# no loader
log: bochsout.txt
logprefix: %t%e%d
debugger_log: debug.txt
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
pass: action=fatal
keyboard_mapping: enabled=0, map=
keyboard_type: mf
user_shortcut: keys=none
# no cmosimage
上面的内容是用bochs.exe在执行的时候回答选项然后保存下来的
start.bat
bochsdbg -f config.txt –q
bochsdbg是bochs的调试程序
-f      参数指定一个名叫config.txt的文件作为配置
-q     参数跳过bochs的内置菜单直接运行
然后运行start.bat
执行的命令有不少,可以看bochs的文档internal-debugger.html一节
常用的是下面的一些
c      继续执行
s [count]单步执行count步指令,没有count就是1
ctrl-c       中断程序执行,出现命令行方式进入单步执行的状态
q      退出bochs
b      address 在address地址处设置断点
u      address address显示在address到address处的指令
info r       显示所有寄存器信息
info b       显示设置的断点
dump_cpu       显示cpu相关信息
…
然后我们先设置在0x7c00启动地址的断点b 0x7c00
然后让它继续运行c
到了0x7c00它就会停下来
这时候可以让它单步运行s
然后每次敲回车它就可以单步了
如果对上面的程序不放心,那么就用单步调试吧!,最后出现的结果
说明我们的kernel可以载入到0x90000的地方正确运行了
[系列]OS学习-自己写操作系统(5)-loader的产生 终于从保护模式走出来了。太艰难了。 现在我们将正式从引导扇区开始,编写Loader和内核。 由于引导扇区只有512字节,不够完成初始化和载入内核的工作,所以我们要写一个Loader,从引导扇区跳到Loader,由loader完成一切准备工作,然后进入内核。 用bximage创建软盘,在freedos中使用format B格式化B盘,用ultraISO向软盘中加入文件 一、FAT12格式 阅读详情

相关推荐

bochs(2.1.1)简易教程

这是网友王南洋制作的《x86汇编语言:从实模式到保护模式》工具。是一个bochs虚拟机的简单教程。优快云有一个太贵了,我下载了重新上传,方便没有积分的用户。

linux-0.11调试教程,Bochs-2.1.1配置文件,精简版可拷贝,及img文件制作过程

说明1:BIOS-bochs-latest文件和VGABIOS-elpin-2.40文件都在bochs安装目录下,既C:\Program Files\Bochs-2.1.1 说明2:bootimage-0.11-hd和diskb.img和hdc-0.11.img都是用户自己制作或下载的别人制作好的文件。 下面是bochsrc-hd.bxrc文件的内容: romimage: file=

linux-0.11调试教程 4961

Bochs-2.1.1.rar

Bochs-2.1.1 调试操作系统的必备工具 可作虚拟机使用

操作系统学习12 进入32位保护模式

自制操作系统学习4 进入保护模式一、概念1. 为什么要进保护模式2. 段描述符2. 进入保护模式的步骤: 一、概念 1. 为什么要进保护模式 8086最大寻址范围是1M,而超过64K的内存区域访问要靠切换段基址。 当Intel的CPU发展到32位后,寻址空间达到了4G。32位下改变了寻址方式,使用名为GDT的表来管理内存,其实就是查表法,在GDT里记录每个内存段的段基址、段界限、段属性等信息。GDT里每个表项称为描述符Descriptor。 CPU在保护模式下使用段描述符采用段描述符缓冲寄存器。在获得一个段

猿来这样-谢厂节的博客 1281

手把手教你用Wireshark抓包分析BLE广播包:从PDU结构到AD Type实战解析

本文详细介绍了如何使用Wireshark工具抓取并分析BLE广播包,从PDU结构到AD Type的实战解析。通过硬件设备选择、软件配置、协议栈解析及高级故障排查,帮助开发者深入理解蓝牙低功耗通信机制,提升物联网设备调试效率。

weixin_30482383的博客 417

MyBatis示例

MyBatis示例 基本示例 环境准备 jdk : 1.8.0 MyEclipse MySQL MyBatis-3.4.6.jar 新建JavaWeb Project 命名:mybatis 导入JAR包或添加POM.xml中添加依赖 MyBatis_config.xml &amp;amp;amp;amp;amp;lt;?xml version=&amp;amp;amp;amp;quot;1.0&amp;amp;amp;amp;quot; encoding=&a

走在命运的左岸 720

32位保护模式汇编语言[1]:实模式与保护模式的故事

漫游在机器指令的海洋,徘徊于实模式与保护模式之间,出入之间,自由无限。 ——谨以此系列文档献给广大疯狂痴迷于计算机程序的极客们~!

Mighten Dai的ASM, C, C++的天地 1377

arduino uno spi驱动12864

arduino uno spi驱动12864

yvee的博客 2060

操作系统学习笔记(一)x86架构操作系统的启动

刚看完b站操作系统(哈工大李治军老师)老师的课前三章,趁热打铁做个简单的笔记,不会讨论太多具体内部的代码主要是理解

weixin_43470170的博客 668

亚马逊SP-API授权实战:从OAuth流程到Refresh Token获取

本文详细解析了亚马逊SP-API授权流程,从OAuth认证到Refresh Token获取的全过程。通过实战经验分享,帮助开发者快速掌握Marketplace Appstore、Website Workflow和自行授权三种方式,解决常见错误如MD5100和MD9999,并提供了安全存储Refresh Token的最佳实践。

weixin_30379531的博客 518

[毕设项目-MCP+ENSP]一句话搞定ENSP自动化:MCP + LLM实战(架构图、工具清单、踩坑全解)

用 MCP + LLM 把“人话”变成对华为 ENSP 的安全自动化操作,三款工具覆盖配置/查询/落盘,配套架构、实战与排坑清单。

逐梦苍穹的博客 2538

x86汇编语言:从实模式到保护模式_实战操作系统 loader 编写(上) 进入保护模式...

1. 引言此前的文章中,我们详细介绍了从引导扇区跳转到 loader 的工作:从启动扇区跳转到loader引导扇区的工作已经告一段落,接下来我们的工作就是编写我们的 loader 了。loader 的工作只有两个:将内核载入内存跳入保护模式本文我们就来详细介绍一下。2. loader加载内核的过程有了通过引导扇区加载 loader 的经验,让 loader 加载内核就简单的多了。从原...

weixin_39621669的博客 565

AutosarMCAL开发——基于EB MCU驱动

本文为博主个人学习总结记录,如有不正,欢迎指正。

qq_45583706的博客 920

学习笔记:一个操作系统的实现--认识保护模式

; ========================================== ; pmtest1.asm ; 编译方法:nasm pmtest1.asm -o pmtest1.bin ; ========================================== %include "pm.inc" ; 常量, 宏, 以及一些说明 org 07c00h jmp LABEL

Kleinlin'HB的专栏 691

大模型在电力交易功率预测中的应用:短期,超短期,中长期的完整解决方案代码详解

本文介绍了基于大模型的电力交易功率预测系统,该系统覆盖超短期(15分钟-1小时)、短期(1-6小时)和中长期(1天-1月)三个时间尺度。文章详细阐述了数据准备与特征工程,包括多源数据集成和特征重要性分析。在模型构建方面,采用了Temporal Fusion Transformer (TFT)模型进行超短期预测,Informer模型进行短期预测,以及N-HiTS模型进行中长期预测。此外,文章还探讨了概率预测与风险分析,并介绍了模型部署与交易策略集成的实现。最后,文章总结了系统的贡献,并展望了未来发展方向,如市

专注AI大模型,软件混淆,授权 1261

【NVIDIA-B200 GPU固件升级】NVIDIA Blackwell B200 GPU 固件更新全指南

B200 GPU 固件更新并非 “执行一条命令即可” 的简单操作,而是涉及 “版本兼容性校验、BMC 环境准备、UEFI 引导、Redfish 协议交互” 的系统性工程。从文档翻译与技术解析来看,NVIDIA 的更新流程设计围绕 “安全” 与 “稳定” 两大核心 —— 无论是 0.9 版本的 “跳板限制”,还是 UEFI Shell 的引导要求,本质都是为了避免因操作不当导致硬件损坏。对于数据中心运维人员,建议在更新前做好三项准备:① 确认 GPU 当前固件版本(通过查询),规划升级路径;

jundao1997的专栏 741

操作系统入门(四)痛并学习中

前面的教程已经说了怎么由机器启动然后转到执行我们自己的代码,现在已经可以显示出一个粗糙的图形界面了,我们的程序可以先启动loader,然后再由loader里面的代码把放在磁盘里面的kernel文件载入到一个指定的位置,再转到kernel里面执行,这样一来,代码就可以突破512个字节的限制,任意由你爱写多长就写多长了,但是如果所有的代码都用汇编来写的话,我想你首先尝到的是身体上病痛的折磨,而不是完成

魔芋的专栏 2122

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【C语言实现操作系统内核入门】:手把手教你从零构建简易内核(含完整源码)

掌握操作系统底层原理?本文提供C语言实现简易操作系统内核入门完整指南,涵盖引导加载、GDT设置、中断处理等核心步骤,基于x86架构从零构建可运行内核。附带可编译源码与调试技巧,适合学习操作系统设计基础,值得收藏。

ProceSeed的博客 1377

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

When Do We Write Our Chinese Os? (2)

上一篇谈到了怎样把计算机用我们自己的程序启动起来,然而我已经说过,那只是最最初始的一步,只表明了我们的确可以让计算机从一开始就按照我们的命令去执行一个任务。但它并不能算是一个操作系统,当计算机用引导程序引导起来之后,我们需要让它把真正的操作系统内核载入内存中,然后跳转到真正的操作系统内核中运行。本篇将完成一个真正意义上的操作系统引导,而不是第一篇里所描述的计算机的引导。这里我们将从计算机启动时的1

潇寒的Blog 3406

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

操作系统开发之——进入保护模式

依旧直接贴代码: %macro Descriptor 3 dw %2 & 0FFFFh ; 段界限 1 (2 字节) dw %1 & 0FFFFh ; 段基址 1 (2 字节) db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节) dw ((%2 >> 8) &amp...

weixin_30800987的博客 124

从开机加电到执行main函数之前的过程

CPU收到int 0x19中断 ---> 在中断向量表找到int 0x19中断 ---> 中断向量把CPU指向0x0E6F2,即int 0x19对应的中断服务程序(即启动加载服务程序,这个中断服务程序的作用是把软盘第一扇区中的程序512B加载到内存0x07C00处) ---> 第一扇区的内容就是bootsect,作用是把软盘中的操作系统程序载入内存。IP/EIP:指令指针寄存器,存在于CPU中,记录将要执行的指令在代码段内的偏移地址,和CS组合为将要执行的指令的内存地址。head程序在前,内核程序在后。

m0_73535031的博客 579

【操作系统】从开机加电到执行main函数之前的过程

从开机加电到执行main函数之前的过程,包括了以下三个.s文件:bootsect程序(扇区 -> 主机内存);setup程序(设置内核运行所需的机器系统数据);head程序(保护模式,内存分页)

Enchanted to meet U 738

重新认识intel保护模式

Intel 8086和80386的段机制有本质的差别,前者目的是实现16位的寄存器寻址20位的地址,后者不仅利用段寄存器寻址,还利用多余的部分实现保护机制。本文希望对比两者区别加深对Linux寻址的理解

Take Easy,Work Hard! 756

哈工大李治军老师OS课程笔记(1)——操作系统导论

哈工大李治军老师操作系统第一章课程笔记,包括什么是操作系统,计算机启动的过程以及系统调用如何实现。课程链接https://www.bilibili.com/video/BV19r4y1b7Aw/?spm_id_from=333.337.search-card.all.click&vd_source=94c8d46c97aafd8c5a20f063eadb0ba4

weixin_46750485的博客 1334

Linux内核(1)--从开机到main函数

从开机到main函数1. 启动BIOS,准备中断向量表和中断服务程序1.1 启动BIOS1.2 加载操作系统内核程序1.3 为调用main函数做准备 从开机到main函数的执行分为三步完成,目的是实现从启动盘加载操作系统程序,完成执行main函数所需要的准备工作。第一步,启动BIOS,准备实模式下的中断向量表和中断服务程序;第二步,从启动盘加载操作系统程序到内存,加载操作系统程序的工作就是利用第一...

魔法师の屋子★↓☆ 4006
上一篇: 操作系统入门(四)痛并学习中
下一篇: 写够30篇再说
魔芋
博客等级 码龄26年 37粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值