- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
根据这个tutorial创建一个简单的操作系统就足够了,只需像以下代码一样简单地切换到保护模式,而无需其他众所周知的操作,例如启用 A20...
无论如何,我是这个领域的新手,我写了下面的代码,正如他们提到的那样,并根据这个 SO 进行了修改。 .
代码结构:这个简单的操作系统应按如下方式短暂加载:
但是模拟器仍在重新启动。请找到随附的完整代码。
bootloader.asm
[bits 16]
[org 0x7C00]
KERNEL_OFFSET equ 0x1000
xor ax, ax
mov ds, ax
mov es, ax
mov [BOOT_DRIVE], dl
mov ax, 0x07E0 ; End of stack
cli
mov ss, ax
mov sp, 0x1200 ; Size of Stack. By this, we assume that stack starts at 9000h
; of size 1200h and ends at 7E00h to avoid being overwritten.
sti
call load_kernel
call switch_to_pm
jmp $
%include "src/functions/disk_load.asm"
load_kernel:
mov bx, KERNEL_OFFSET
mov dh, 15
mov dl, [BOOT_DRIVE]
call disk_load
ret
; Global variables
BOOT_DRIVE db 0
SECTORS db 0
MSG_PROT_MODE db "Successfully landed in 32-bit Protected Mode" , 0
%include "src/functions/gdt.asm"
%include "src/functions/switch_to_pm.asm"
[ bits 32]
; This is where we arrive after switching to and initialising protected mode.
BEGIN_PM:
mov ebx , MSG_PROT_MODE
call print_string_pm ; Use our 32 - bit print routine.
;call KERNEL_OFFSET ; Now jump to the address of our loaded
; kernel code , assume the brace position ,
; and cross your fingers. Here we go !
jmp $ ; Hang.
%include "src/functions/writing_video_mode.asm"
; Bootsector padding
times 510-($-$$) db 0
dw 0xAA55
; 15 sector padding
times 15*256 dw 0xDADA
disk_load.asm
disk_load:
mov [SECTORS], dh
mov ch, 0x00 ;C=0
mov dh, 0x00 ;H=0
mov cl, 0x02 ;S=2
next_group:
mov di, 5 ;Max 5 tries
again:
mov ah, 0x02 ;Read sectors
mov al, [SECTORS]
int 0x13
jc maybe_retry
sub [SECTORS], al ;Remaining sectors
jz ready
mov cl, 0x01 ;Always sector 1
xor dh, 1 ;Next head on diskette!
jnz next_group
inc ch ;Next cylinder
jmp next_group
maybe_retry:
mov ah, 0x00 ;Reset diskdrive
int 0x13
dec di
jnz again
jmp disk_error
ready:
ret
disk_error:
mov ah, 0x0e
mov al, 'Y'
int 0x10
jmp $
DISK_ERROR_MSG db "Disk read error!", 0
gdt.asm
gdt_start:
gdt_null:
dd 0x0 ; ’ dd ’ means define double word ( i.e. 4 bytes )
dd 0x0
gdt_code:
dw 0xffff
dw 0x0
db 0x0
db 10011010b ; 1 st flags , type flags
db 11001111b ; 2 nd flags , Limit ( bits 16 -19)
db 0x0
gdt_data:
dw 0xffff
dw 0x0
db 0x0
db 10010010b ; 1 st flags , type flags
db 11001111b ; 2 nd flags , Limit ( bits 16 -19)
db 0x0
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
switch_to_pm.asm
[ bits 16 ]
switch_to_pm:
cli
lgdt [ gdt_descriptor ]
mov eax , cr0
or eax , 0x1
mov cr0 , eax
jmp CODE_SEG:init_pm
[ bits 32 ]
init_pm:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp , 0x90000
mov esp , ebp
call BEGIN_PM
为了确保我们进入保护模式:
writing_video_mode.asm
[ bits 32]
VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f
print_string_pm:
push eax
push ebx
push edx
mov edx , VIDEO_MEMORY ; Set edx to the start of vid mem.
print_string_pm_loop:
mov al, [ebx]
mov ah, WHITE_ON_BLACK
cmp al, 0
je print_string_pm_done
mov [edx], ax
add ebx, 1
add edx, 2
jmp print_string_pm_loop
print_string_pm_done:
pop edx
pop ebx
pop eax
ret
内核.c
void main () {
char * video_memory = (char *) 0xb8000;
*video_memory = 'X';
}
顺便说一句,我正在使用这个Makefile:
all: bootloader.bin kernel.bin
bootloader.bin: src/bootloader.asm
nasm src/bootloader.asm -f bin -o output/bootloader.bin
kernel.o: src/kernel/kernel.c
gcc -ffreestanding -c src/kernel/kernel.c -o output/kernel.o -m32
kernel.bin: kernel.o
ld -o output/kernel.bin -Ttext 0x1000 --oformat binary output/kernel.o -melf_i386
clean:
rm -f output/*.* output/*
为了将它移动到闪存中,我使用了这些命令:
cat output/bootloader.bin output/kernel.bin > os-image
sudo dd if=os-image of=/dev/sdb bs=512 conv=notrunc && sync
为了运行它,我使用带有此命令的 qemu:
qemu-system-i386 -hda /dev/sdb
注意/dev/sdb 是我的闪存驱动器。
问题:实际上,代码正在进入保护模式(即打印“成功进入 32 位保护模式”),就在 bootloader.asm
中禁用/注释 call KERNEL_OFFSET
时>。但是,当启用此行时,它会开始引导和重新启动。
我希望我已经提供了所有需要的信息。在我看来,远跳不应该这样做。任何意见表示赞赏。
最佳答案
只需删除
times 15*256 dw 0xDADA
(顺便说一句,为什么是 DADA?)
然后编译你的内核,在那之后
cat output/bootloader.bin output/kernel.bin > os-image
并以某种方式使您的操作系统镜像长 8192 字节(16 个扇区,引导加载程序 + 15)。我不是 Linux/Unix 粉丝(甚至不能使用它们),但我认为 dd 命令(类似于 dd if=dev\zero of=temp_file count=(8192 - < em>file actual size),然后 cat os-image temp-file > os-image) 应该可以完成这项工作。我也不确定这个编译命令是否正确(只是不确定)。我会从链接器命令中删除“-melf_i386”,但是我知道,我只在 Windows 上使用过 MinGW(它只类似于 GCC)。
抱歉我的英语不好,我希望我能帮到你。
关于c - 从实模式切换到保护模式后远跳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42482999/
我知道这有点愚蠢,但我需要保护 javascript,从某种意义上说,我希望增加尽可能多的安全性,以免它被盗版。好吧,因为它是系统的核心组件。我打算用YUI compressor来压缩混淆。 但我还想
因此,当我的宏运行时,我有这些简单的子程序可以解除保护而不是保护东西,唯一的问题是我的一些工作表实际上是图表,并且在调用这些子程序时它们没有得到保护。如何更改我的代码以合并图表?谢谢! Sub Unp
有很多关于 preventing CSRF 的文章. 但我就是不明白:为什么我不能只解析目标页面表单中的 csrf token 并将其与我的伪造请求一起提交? 最佳答案 如果您能够将脚本代码注入(in
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
我正在使用一个包含用于docker创建的敏感信息的env文件。 但问题是它们并不安全。可以通过docker inspect轻松查看它们,因此,任何可以运行docker命令的用户都可以使用它们。 我正在
NSA在此处提供了保护.NET框架2.0版的指南:http://www.nsa.gov/ia/_files/app/I731-008R-2006.pdf 我想知道他们是否提供更高版本的指南,例如版本3
我编写了一个 Java 应用程序,并计划在线发布它。每个版本都将使用我制作的 secret 序列 key 锁定。 我需要从反编译器等保护我的 jar 文件。这是我到目前为止所做的: 用户在表格中输入他
我不知道为什么这不起作用。如果 ?Session=2 不是您发出的,那么您将返回您的帐户。 这是我的代码: query("SELECT * FROM user_host WHERE uid = '"
我是 elasticsearch 的新手,但我非常喜欢它。我唯一找不到也无法完成的是保护生产系统的 Elasticsearch 。我读了很多关于在 elasticsearch 前使用 nginx 作为
假设我有以下头文件: #ifndef TESTCLASS_H #define TESTCLASS_H #include class TestClass { public: TestClass
在 C++ 中,我有一个基类 A,一个子类 B。两者都有虚方法 Visit。我想在 B 中重新定义“访问”,但 B 需要访问每个 A(以及所有子类)的“访问”功能。 我有类似的东西,但它告诉我 B 无
我目前正在使用 Apache FOP 库生成 PDF。我希望这些 PDF 免受复制粘贴,因此人们必须使用实际的 OCR 库(或手动输入)来获取 PDF 上的信息。 FOP 显然提供了一些安全性,然后将
我有一个使用 JSONP 进行跨域 ajax 调用的脚本。这很好用,但我的问题是,有没有办法阻止其他站点访问这些 URL 并从中获取数据?我基本上想制作一个允许的站点列表,并且只返回列表中的数据。我正
我在基于 Html/Javascript 构建的 Web 应用程序上使用了一些全局变量。我跨页面(或部分页面)使用这些变量,有时它们用作 ajax 调用的发布数据。我的问题是:这有多安全?当然,我可以
我有一个扩展到多个类文件的大项目。这个项目是在赶时间前匆忙完成的。这对项目安全造成了影响。所以简单来说,理论上任何人都可以在我的项目中调用一个 AJAX 脚本并让它运行,因为脚本中的函数不是用户权限感
相当多的人对 ivé 发送给他们的 dll 真正感兴趣,他们不是那种应该经常免费赠送的类型... 我只是想知道,如果我要出售我的组件、用户控件等,我将如何在所有权/加密代码(如果可能)等方面保护它们。
我正在开发一个 PHP 库,我们将在其中为客户提供加密代码。该代码将包括一个他们可以实例化的主要类,该类将处理许可证验证并公开其使用方法。主类将实例化几个子类,每个子类都包含在自己的文件中。我怎样才能
我有一个以 VUEJS 作为前端的 Laravel 应用程序,我通过创建 API 路由获取数据。因此,例如获取帖子数据的路线将是 http://localhost/api/posts 保护路线的最佳方
在许多网页上,我们都包含外部脚本。无论是类似于 Facebook 的按钮、用于分析或广告系统的客户端代码、外部评论提供商还是其他东西。 那些脚本无法访问我的 Ajax 资源,因为一直在检查原始 hea
我目前正在使用 PHP/MySQL 开发一个公开和开放源代码的软件。我在一个文件夹中有几个重要的 SECRET TXT 文件。我在软件中使用它们,但问题是它们也可以被任何知道文件夹和文件名的人读取:
我是一名优秀的程序员,十分优秀!