无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: 不点
打印 上一主题 下一主题

现在的 PE 是用 svbus 还是 firadisk/winvblock?

    [复制链接]
181#
 楼主| 发表于 2021-11-25 11:28:51 | 只看该作者
本帖最后由 不点 于 2021-11-25 17:16 编辑
2011yaya2007777 发表于 2021-11-25 08:52
我个人的看法,EBDA 与 grub4dos 没有什么关系。grub4dos 的 int13 驻留内存代码的位置是由 0x413 确定, ...

好的,我前面的发言,有错误。


重新整理一下我的思路。目的还是帮助 yaya 进行开发。



0x413 处的指针,确定的是常规内存的量。DOS 下似乎一切正常,能够用 0x413 处的设置来保护我们的 int13 代码空间。


然而 Windows 却无视 0x413 的设置,也无视 int15/e820 的设置,而任意破坏掉我们的代码和数据。


wintoflash 说这是“霸道”。当然,这样解释是没问题的。然而,同一件事,可能有不同的解释。也许不是霸道,而是有某种道理呢?


我们以前的 int15 代码,就位于 int13 空间的尾部,结果,被破坏了。yaya 现在的碎片,也位于 int13 空间的尾部,也被破坏了。由此,就提醒我们,它破坏的是尾部,而不是首部。那么就有理由猜测,Windows 初始化程序是把堆栈设置在此处了。


为什么把堆栈设置在此处?那是因为它没承认 int13 空间是合法的。它只承认 EBDA 是合法的。



我们需要理清头绪。我们有两条路可以尝试。


1、假如我们把 int13 空间伪装成 EBDA 的一部分,那是否可以骗过 Windows 呢?


2、我们也不试图欺骗 Windows 了,我们可以设法保护 int13 的代码和数据,只需 workaround 即可。


这两条都可以试试。第1条,需要修改 0x40E 处的值,把它修改为指向 int13 空间的首部。同时也修改 int13 空间最开头的字节,让它看起来像是一个 EBDA 的样子。不过,这样做有一定的风险,有可能会导致 BIOS 完全失效、完全混乱。【此路不通,后面的第 3 条路才可能行得通。】


第2条,没有任何风险。我们在 int13 代码空间的尾部,留足一定的空间,比如,预留 2K,3K,4K 空间,给 Windows 初始化程序做堆栈用。我们可以估计所需堆栈空间的大小,选择一个合理的、安全的值。这么做以后,甚至有可能解决以前需要用 map --e820cycles=0 才能解决的问题。也就是说,有可能 int15/e820 不再导致死机了。


补充:想到了第3条路,不比第2条强,但比第1条好一些。


3、把 EBDA 向下平移,让我们的 int13 空间位于 EBDA 之上,处于常规内存的最高端。


改变 EBDA 的位置,DOS 本身曾经干过这事,不过,那只是在 EBDA 刚好只有 1K 的时候,DOS 才这么做。对于超过 1K 的 EBDA,DOS 就不移动它了。DOS 在移动 EBDA 之后,当然会修改 0x40E 处的值,指向新的位置。这说明,硬件厂家也是以 0x40E 处的值来确定 EBDA 位置的。因此,前面所说的第 1 条路,是不可行的,肯定会失败。


现在的 EBDA,都超过 1K,这第 3 条路是否真的可行,也存在很大的不确定性。

第2条路,肯定能成功,但是,要在 int13 空间尾部增加若干空间,对于运行 DOS 系统来说,也是一种浪费,因为 DOS 的可用内存减少了。当然了,如果不照顾 DOS,那也就不算浪费了。


第3条路最经济,不浪费空间。但不知是否可行。有两种风险:第一,不知 BIOS 是否还能正常运转。第二,不知 grub4dos 本身的各个部件之间是否能够适应这种改变,即 grub4dos 自身的兼容性问题,例如,当 grub.exe 从 DOS 运行的时候,能否识别出先前的 grub4dos 所建立的虚拟盘 。




回复

使用道具 举报

182#
发表于 2021-11-25 12:02:36 来自手机 | 只看该作者
2011whp:我还是没有理解,你说的有碎片,是指iso镜像里面的某个文件在镜像内部有碎片,还是指iso镜像在U盘上有碎片?
回复

使用道具 举报

183#
发表于 2021-11-25 12:26:48 | 只看该作者
是说  pe.iso 在u盘 有 碎片。
——————————————————————
iso内部 不清楚,也没有出现过什么 问题
(ku588  说  wim 也整理下碎片,估计是说,不涉及map ,微软引导在u盘上,直接 读 boot.wim 的话,连续的文件,读的快,他说的这个,我这没感觉)
回复

使用道具 举报

184#
发表于 2021-11-25 12:46:59 来自手机 | 只看该作者
唉,明白了。我的pe.iso在U盘没有碎片,不加载到内存,同样转圈圈3分半。而不点推荐的那个不转圈圈。现在还没有人能说明是哪个程序在转圈圈。bootmgr?svbus?

点评

转圈的原因是 : svbus 认为 是虚拟盘,要 建立,svbus内存盘(大家说的要占一大片内存) 而此时,正是 win内核阶段,估计只有 基础的 总线类驱动可用, 此时svbus只能以,io读取的方式,用不上  详情 回复 发表于 2021-11-25 13:08
回复

使用道具 举报

185#
发表于 2021-11-25 13:08:53 | 只看该作者
本帖最后由 2011whp 于 2021-11-25 13:32 编辑
2011yaya2007777 发表于 2021-11-25 12:46
唉,明白了。我的pe.iso在U盘没有碎片,不加载到内存,同样转圈圈3分半。而不点推荐的那个不转圈圈。现在还 ...

3分钟时间,是svbus在执行 建立 内存盘,20KB/S 速度读磁盘
——————————————————————————
转圈的原因是 : svbus 认为 是虚拟盘,要 建立,svbus内存盘(大家说的要占一大片内存)
         而此时,正是 win内核阶段,估计只有 基础的 总线类驱动可用,
         此时svbus只能以,io读取的方式,用不上 dma高级的驱动,读取时 u盘指示灯 不理会
         估计,磁盘得完成 扇区数次的 任务,相应cpu要 扇区数次 中断处理
         结果是  20KB/S 速度,所以转圈3分钟,才能完成。

这个是实践猜测, 得 用svbus 原代码的实际执行过程,来证明
(这样的话,从磁盘 读了两次,bcd 一次boot.wim,svbus一次pe.iso)
————————————————————————————————--

不点的 win11pe,没有svbus
转圈是 svbus基于磁盘,读取太慢
(即使有svbus,判断为,不能 建立 svbus内存盘的话,秒过,判断用不了多长时间
这个我 在  试imdisk时,用 xorbootU 引导pe.iso,一切正常的)

回复

使用道具 举报

186#
发表于 2021-11-25 13:43:15 来自手机 | 只看该作者
如果是这样的话,那么只要使用svbus,又不加载到内存,都要转圈圈几分钟了。

点评

如果 svbus 是把扇区复制到内存的话,它很容易支持不连续的 iso。只需在实模式下调用 int13 进行复制便可。 可是,svbus 不支持碎块,因此,可以判定, svbus 不是复制到内存。 若它真的复制到内存,又不在实  详情 回复 发表于 2021-11-25 13:57
是的。 —————————————————— 用其它引导器,svbus搜索不到 插槽 ,也是 秒过的 g4e的话 ,除非 ,像grub205那样,是否 写 插槽 有开关参数  详情 回复 发表于 2021-11-25 13:48
回复

使用道具 举报

187#
发表于 2021-11-25 13:44:41 | 只看该作者
本帖最后由 liuzhaoyzz 于 2021-11-25 13:58 编辑
不点 发表于 2021-11-25 06:59
好的,假定不存在 svbus 之类的驱动,那么,用 iso 虚拟出来的光驱是 “短命” 的。

因此,map --mem 的 ...

一般地一个WIN10PE,只需要1GB内存就可以启动了。一般地WIN10PE.ISO一般在1GB以内,1+1=2GB,基本上大多数电脑都能满足。

需要澄清的一点是,WIN10操作系统本身最少需要8GB内存来运行才行,4GB内存电脑上面跑WIN10一般需要开启虚拟内存,虚拟内存就是把硬盘虚拟出一个内存条出来,如果不开启虚拟内存,WIN10容易提示内存不够。开启了虚拟内存速度肯定比不上纯粹靠内存运行的模式。

那么,4GB内存、8GB内存跑个WIN10PE有什么问题?何谈浪费?内存本来就是用的。一个4GB内存条只要100RMB,一个8GB内存条只要200RMB而已,很贵吗?

map --mem模式启动不含firadisk/winvblock/svbus这样子的WIN10PE,多消耗ISO大小的内存,不到1GB而已,只是启动的时候需要,启动之后占用的这个内存会释放掉,在WIN10下面可用。这也算是一个workground的办法,以空间换时间,换来的是启动的稳定性,何乐而不为?


这么多年来,我一直用的是map --mem模式,没有感觉到任何不妥。

但我完全理解并支持大家探讨并改进g4d对碎片的处理、svbus对碎片的处理等。



点评

这个说法是错误的。--mem 占用的是系统内存,不可能被释放掉。  详情 回复 发表于 2021-11-25 15:02
回复

使用道具 举报

188#
发表于 2021-11-25 13:48:42 | 只看该作者
2011yaya2007777 发表于 2021-11-25 13:43
如果是这样的话,那么只要使用svbus,又不加载到内存,都要转圈圈几分钟了。

是的。
——————————————————

用其它引导器,svbus搜索不到 插槽 ,也是 秒过的
g4e的话  ,除非 ,像grub205那样,是否 写 插槽  有开关参数

点评

你这就基本上证实了,svbus 是把 img 复制到内存的。可是,它竟然不支持连续的文件。这一点应该很容易改进。只要改成调用 int13 读盘,就可解决这个问题。谁懂得修改源码的,可以尝试修改。  详情 回复 发表于 2021-11-25 14:06
回复

使用道具 举报

189#
 楼主| 发表于 2021-11-25 13:57:57 | 只看该作者
2011yaya2007777 发表于 2021-11-25 13:43
如果是这样的话,那么只要使用svbus,又不加载到内存,都要转圈圈几分钟了。

如果 svbus 是把扇区复制到内存的话,它很容易支持不连续的 iso。只需在实模式下调用 int13 进行复制便可。

可是,svbus 不支持碎块,因此,可以判定, svbus 不是复制到内存。

若它真的复制到内存,又不在实模式,而是保护模式用起始扇区+长度的模式(当作无碎片的文件)来复制,那就复制了错误的 data,这就太不应该了。

点评

读了一下SVBus的源代码。 SVBus在这方面处理是相当直接的。 直接构造IRP下发给下层“物理”设备(类似于\\.\PhysicalDrive0这种东西),算出起始扇区和长度后直接读取,直来直去。 所以我个人认为还是刚刚启  详情 回复 发表于 2021-11-25 14:33
回复

使用道具 举报

190#
 楼主| 发表于 2021-11-25 14:06:27 | 只看该作者
2011whp 发表于 2021-11-25 13:48
是的。
——————————————————

你这就基本上证实了,svbus 是把 img 复制到内存的。可是,它竟然不支持连续的文件。这一点应该很容易改进。只要改成调用 int13 读盘,就可解决这个问题。谁懂得修改源码的,可以尝试修改。
回复

使用道具 举报

191#
发表于 2021-11-25 14:33:10 | 只看该作者
本帖最后由 sunsea 于 2021-11-25 14:38 编辑
不点 发表于 2021-11-25 13:57
如果 svbus 是把扇区复制到内存的话,它很容易支持不连续的 iso。只需在实模式下调用 int13 进行复制便可 ...

读了一下SVBus的源代码。
SVBus在这方面处理是相当直接的。

直接构造IRP下发给下层“物理”设备(类似于\\.\PhysicalDrive0这种东西),算出起始扇区和长度后直接读取,直来直去,纯粹是“应上级请求”,上层要求什么就读什么。

所以我个人认为还是刚刚启动时,SVBus作为SCSI Miniport组设备,启动相当早,没有得到Windows的高速的USB或者其他磁盘等驱动。或者Windows为了识别文件系统等可能读取很多数据。此外驱动对读写请求不是即时同步处理的,是保存到内部队列交给别的线程完成的,这也可能是一个原因:请求太碎太多。这大概算个优化问题。

以及,目前并不清楚NT以后怎么直接呼叫int13。我怀疑已经被全部破坏掉了。

贴代码:
  1.                                         // zero start sector and sector count
  2.                                         StartSector = 0;
  3.                                         SectorCount = 0;

  4.                                         // check for read / write / verify 16 command
  5.                                         if(Cdb->AsByte[0] == SCSIOP_READ16 || Cdb->AsByte[0] == SCSIOP_WRITE16 || Cdb->AsByte[0] == SCSIOP_VERIFY16)
  6.                                         {
  7.                                                 // convert start LBA and transfer length to start sector and sector count
  8.                                                 REVERSE_BYTES_QUAD(&StartSector,&Cdb->CDB16.LogicalBlock[0]);
  9.                                                 REVERSE_BYTES(&SectorCount,&Cdb->CDB16.TransferLength[0]);
  10.                                         }
  11.                                         // check for read / write / verify command
  12.                                         else if(Cdb->AsByte[0] == SCSIOP_READ || Cdb->AsByte[0] == SCSIOP_WRITE || Cdb->AsByte[0] == SCSIOP_VERIFY)
  13.                                         {
  14.                                                 // convert start LBA and transfer length to start sector and sector count
  15.                                                 StartSector = ((ULONG)Cdb->CDB10.LogicalBlockByte0 << 24) | ((ULONG)Cdb->CDB10.LogicalBlockByte1 << 16) | ((ULONG)Cdb->CDB10.LogicalBlockByte2 << 8) | Cdb->CDB10.LogicalBlockByte3;
  16.                                                 SectorCount = ((ULONG)Cdb->CDB10.TransferBlocksMsb << 8) | Cdb->CDB10.TransferBlocksLsb;
  17.                                         }

  18.                                         // check for a disk access beyond the limit of the image size
  19.                                         if(StartSector + SectorCount > DeviceExtension->Disk.ImageSizeInLBAs)
  20.                                         {
  21.                                                 // return SCSI_SENSE_ILLEGAL_REQUEST
  22.                                                 Srb->SenseInfoBufferLength = (UCHAR)MemCopy(Srb->SenseInfoBuffer,Srb->SenseInfoBufferLength,&DeviceExtension->Disk.SenseData,(ULONG)sizeof(SENSE_DATA));
  23.                                                 Srb->DataTransferLength = 0;
  24.                                                 Srb->SrbStatus = SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_ERROR;
  25.                                                 Status = STATUS_INVALID_PARAMETER;
  26.                                                 break;
  27.                                         }

  28.                                         // calculate length of transfer
  29.                                         Length = SectorCount * DeviceExtension->Disk.SectorSize;

  30.                                         // SRB data buffer is valid and transfer length did not match the SRB data transfer length
  31.                                         if(Srb->DataBuffer != NULL && Length != Srb->DataTransferLength)
  32.                                         {
  33.                                                 // return SCSI_SENSE_ILLEGAL_REQUEST
  34.                                                 Srb->SenseInfoBufferLength = (UCHAR)MemCopy(Srb->SenseInfoBuffer,Srb->SenseInfoBufferLength,&DeviceExtension->Disk.SenseData,(ULONG)sizeof(SENSE_DATA));
  35.                                                 Srb->DataTransferLength = 0;
  36.                                                 Srb->SrbStatus = SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_ERROR;
  37.                                                 Status = STATUS_INVALID_PARAMETER;
  38.                                                 break;
  39.                                         }

  40.                                         // transfer length is not a multiple of sector size
  41.                                         if(Length % DeviceExtension->Disk.SectorSize != 0)
  42.                                         {
  43.                                                 // return SCSI_SENSE_ILLEGAL_REQUEST
  44.                                                 Srb->SenseInfoBufferLength = (UCHAR)MemCopy(Srb->SenseInfoBuffer,Srb->SenseInfoBufferLength,&DeviceExtension->Disk.SenseData,(ULONG)sizeof(SENSE_DATA));
  45.                                                 Srb->DataTransferLength = 0;
  46.                                                 Srb->SrbStatus = SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_ERROR;
  47.                                                 Status = STATUS_INVALID_PARAMETER;
  48.                                                 break;                                                
  49.                                         }

  50.                                         // return success on zero sectors to transfer or verify only command
  51.                                         if(SectorCount == 0 || Cdb->AsByte[0] == SCSIOP_VERIFY16 || Cdb->AsByte[0] == SCSIOP_VERIFY)
  52.                                         {
  53.                                                 Srb->DataTransferLength = 0;
  54.                                                 break;
  55.                                         }

  56.                                         // get nonpaged system space virtual address for the buffer
  57.                                         sysAddr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,HighPagePriority);
  58.                                         if(sysAddr == NULL)
  59.                                         {
  60.                                                 // return SCSI_SENSE_ILLEGAL_REQUEST
  61.                                                 Srb->SenseInfoBufferLength = (UCHAR)MemCopy(Srb->SenseInfoBuffer,Srb->SenseInfoBufferLength,&DeviceExtension->Disk.SenseData,(ULONG)sizeof(SENSE_DATA));
  62.                                                 Srb->DataTransferLength = 0;
  63.                                                 Srb->SrbStatus = SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_ERROR;
  64.                                                 Status = STATUS_INSUFFICIENT_RESOURCES;
  65.                                                 break;
  66.                                         }

  67.                                         // calculate buffer address from base virtual address and nonpaged system space virtual address
  68.                                         buffer = (PVOID)(((SIZE_T)Srb->DataBuffer - (SIZE_T)MmGetMdlVirtualAddress(Irp->MdlAddress)) + (SIZE_T)sysAddr);

  69.                                         // calculate start offset on the physical disk
  70.                                         offset.QuadPart = (LONGLONG)(DeviceExtension->Disk.ImageStartOffsetInBytes + StartSector * DeviceExtension->Disk.SectorSize);

  71.                                         // check if file object is valid
  72.                                         if(DeviceExtension->Disk.FileObject == NULL)
  73.                                         {
  74.                                                 // open disk file
  75.                                                 Status = DiskOpenFile(StartContext);
  76.                                                 if(!NT_SUCCESS(Status))
  77.                                                 {
  78.                                                         Srb->DataTransferLength = 0;
  79.                                                         Srb->SrbStatus = SRB_STATUS_BUSY;
  80.                                                         Status = STATUS_DEVICE_NOT_READY;
  81.                                                         break;
  82.                                                 }
  83.                                         }

  84.                                         // 0x28 READ (10) or 0x88 READ (16)
  85.                                         if(Cdb->AsByte[0] == SCSIOP_READ || Cdb->AsByte[0] == SCSIOP_READ16)
  86.                                         {
  87.                                                 // allocate memory for temporary read buffer
  88.                                                 // We can not use the buffer address here like in the write code below. We have to
  89.                                                 // use double buffering, otherwise we get a MEMORY MANAGEMENT BSOD on Windows 10.
  90.                                                 // Reason is the MmProbeAndLockPages call in IoBuildSynchronousFsdRequest function,
  91.                                                 // which probes the pages for IoReadAccess.
  92.                                                 tmpBuffer = ExAllocatePoolWithTag(PagedPool,(SIZE_T)Length,SVBUS_POOL_TAG);
  93.                                                 if(tmpBuffer == NULL)
  94.                                                 {
  95.                                                         Srb->DataTransferLength = 0;
  96.                                                         Srb->SrbStatus = SRB_STATUS_ERROR;
  97.                                                         Status = STATUS_INSUFFICIENT_RESOURCES;
  98.                                                         break;
  99.                                                 }

  100.                                                 // read from the physical disk
  101.                                                 Status = ReadWritePhysicalDisk(DeviceExtension->Disk.FileDeviceObject,DeviceExtension->Disk.FileObject,IRP_MJ_READ,tmpBuffer,Length,&offset);
  102.                                                 if(!NT_SUCCESS(Status))
  103.                                                 {
  104.                                                         ExFreePoolWithTag(tmpBuffer,SVBUS_POOL_TAG);
  105.                                                         Srb->DataTransferLength = 0;
  106.                                                         Srb->SrbStatus = SRB_STATUS_ERROR;
  107.                                                         break;
  108.                                                 }

  109.                                                 // copy data from temporary buffer to buffer
  110.                                                 RtlCopyMemory(buffer,tmpBuffer,(SIZE_T)Length);
  111.                                                 // free temporary buffer memory
  112.                                                 ExFreePoolWithTag(tmpBuffer,SVBUS_POOL_TAG);

  113.                                                 // set returned read length
  114.                                                 Irp->IoStatus.Information = Length;
  115.                                                 Srb->DataTransferLength = Length;
  116.                                         }
复制代码
  1. #define REVERSE_BYTES_QUAD REVERSE_BYTES_8
  2. #define REVERSE_BYTES_8(Destination, Source) {              \
  3.     PEIGHT_BYTE d = (PEIGHT_BYTE)(Destination);             \
  4.     PEIGHT_BYTE s = (PEIGHT_BYTE)(Source);                  \
  5.     d->Byte7 = s->Byte0;                                    \
  6.     d->Byte6 = s->Byte1;                                    \
  7.     d->Byte5 = s->Byte2;                                    \
  8.     d->Byte4 = s->Byte3;                                    \
  9.     d->Byte3 = s->Byte4;                                    \
  10.     d->Byte2 = s->Byte5;                                    \
  11.     d->Byte1 = s->Byte6;                                    \
  12.     d->Byte0 = s->Byte7;                                    \
  13. }
复制代码
  1. //------------------------------------------------------------------------------
  2. // read / write physical disk
  3. //------------------------------------------------------------------------------
  4. NTSTATUS ReadWritePhysicalDisk(PDEVICE_OBJECT DeviceObject,PFILE_OBJECT FileObject,ULONG MajorFunction,PVOID buffer,ULONG length,PLARGE_INTEGER offset)
  5. {
  6.         KEVENT Event;
  7.         PIRP Irp;
  8.         IO_STATUS_BLOCK IoStatusBlock;
  9.         PIO_STACK_LOCATION Stack;
  10.         NTSTATUS Status;

  11.         // initialize notification event object
  12.         KeInitializeEvent(&Event,NotificationEvent,FALSE);

  13.         // allocate and set up an IRP for a synchronously processed I/O request
  14.         Irp = IoBuildSynchronousFsdRequest(MajorFunction,DeviceObject,buffer,length,offset,&Event,&IoStatusBlock);
  15.         if(Irp == NULL)
  16.         {
  17.                 return STATUS_INSUFFICIENT_RESOURCES;
  18.         }

  19.         // get higher level driver access to the next lower driver's I/O stack location
  20.         Stack = IoGetNextIrpStackLocation(Irp);

  21.         // set the flag SL_OVERRIDE_VERIFY_VOLUME
  22.         Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;

  23.         // since Windows Vista direct write operations to volumes and disks are blocked, therefore we use the flag SL_FORCE_DIRECT_WRITE
  24.         // which bypasses the check in file system and storage drivers
  25.         if(MajorFunction == IRP_MJ_WRITE)
  26.         {
  27.                 // set the flag SL_FORCE_DIRECT_WRITE
  28.                 Stack->Flags |= SL_FORCE_DIRECT_WRITE;
  29.         }

  30.         // reference file object, we take an extra reference here to prevent early unload problems
  31.         ObReferenceObject(FileObject);

  32.         // set the FileObject pointer in the first stack location
  33.         Stack->FileObject = FileObject;

  34.         // send IRP to the device object
  35.         Status = IoCallDriver(DeviceObject,Irp);
  36.         if(Status == STATUS_PENDING)
  37.         {
  38.                 // wait for disk read / write to finish
  39.                 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
  40.                 // get returned NTSTATUS value
  41.                 Status = IoStatusBlock.Status;
  42.         }

  43.         // dereference file object
  44.         ObDereferenceObject(FileObject);

  45.         return Status;
  46. }

复制代码



点评

但我貌似听说 “驱动程序的级别比普通程序的级别高”,不知是啥意思? 难道说,级别高,也不是最高的 Ring 0?而是 Ring 1?或 Ring 2?  详情 回复 发表于 2021-11-25 15:23
对于 Windows 软件的开发,我完全没经验。 我从 CPU 指令的角度,谈一点思路。可能有用,也可能无用,供参考。 驱动程序,它假如运行在最高特权级 Ring 0,就有权切换到实模式,然后调用 int13,然后再返回保  详情 回复 发表于 2021-11-25 14:43
回复

使用道具 举报

192#
 楼主| 发表于 2021-11-25 14:43:17 | 只看该作者
sunsea 发表于 2021-11-25 14:33
读了一下SVBus的源代码。
SVBus在这方面处理是相当直接的。

对于 Windows 软件的开发,我完全没经验。

我从 CPU 指令的角度,谈一点思路。可能有用,也可能无用,供参考。

驱动程序,它假如运行在最高特权级 Ring 0,就有权切换到实模式,然后调用 int13,然后再返回保护模式。这样,问题就解决了。

回复

使用道具 举报

193#
 楼主| 发表于 2021-11-25 15:02:51 | 只看该作者
liuzhaoyzz 发表于 2021-11-25 13:44
一般地一个WIN10PE,只需要1GB内存就可以启动了。一般地WIN10PE.ISO一般在1GB以内,1+1=2GB,基本上大多 ...
map --mem模式启动不含firadisk/winvblock/svbus这样子的WIN10PE,多消耗ISO大小的内存,不到1GB而已,只是启动的时候需要,启动之后占用的这个内存会释放掉,在WIN10下面可用。


这个说法是错误的。--mem 占用的是系统内存,不可能被释放掉。

点评

已证实,map --mem这部分内存会被直接不识别。(20H1的PE) 、 [attachimg]491252[/attachimg] ↑直接map [attachimg]491251[/attachimg] ↑map --mem(无SVBus  详情 回复 发表于 2021-11-25 15:30
哦,不点大说的是对的,map --mem不可能被释放掉,我错了。  详情 回复 发表于 2021-11-25 15:23
回复

使用道具 举报

194#
发表于 2021-11-25 15:23:00 | 只看该作者
不点 发表于 2021-11-25 15:02
这个说法是错误的。--mem 占用的是系统内存,不可能被释放掉。

哦,不点大说的是对的,map --mem不可能被释放掉,我错了。        

点评

map --mem 占用的内存,是占用 BIOS 级别的内存。按照 BIOS 的 int15/e820 规范,任何操作系统都不可以重新分配这些内存而让用户使用。 但是,也真有可能性,让这些内存被操作系统使用。 注意到我们的 map  详情 回复 发表于 2021-11-25 15:44
回复

使用道具 举报

195#
 楼主| 发表于 2021-11-25 15:23:01 | 只看该作者
sunsea 发表于 2021-11-25 14:33
读了一下SVBus的源代码。
SVBus在这方面处理是相当直接的。
搜索了一下这种行为似乎在ntoskrnl.exe接管控制权以后就完全不可能了。不知道HAL是怎么做的。

但我貌似听说 “驱动程序的级别比普通程序的级别高”,不知是啥意思?

难道说,级别高,也不是最高的 Ring 0?而是 Ring 1?或 Ring 2?


点评

驱动程序也在R0。但是纵使在R0,现在Windows内核也有完善的安保机制,估计一堆东西会爆炸。  详情 回复 发表于 2021-11-25 15:31
是ring0。理论上是可以切到实模式再切回来的,但是实际上估计会爆炸。 我记得grub2 加载了ahci驱动之后就没办法再切回实模式用int13h读磁盘了。Windows这么复杂,保不准也有什么东西在切模式之后会爆炸。  详情 回复 发表于 2021-11-25 15:28
回复

使用道具 举报

196#
发表于 2021-11-25 15:28:01 | 只看该作者
不点 发表于 2021-11-25 15:23
但我貌似听说 “驱动程序的级别比普通程序的级别高”,不知是啥意思?

难道说,级别高,也不是最高 ...


是ring0。理论上是可以切到实模式再切回来的,但是实际上估计会爆炸。
我记得grub2 加载了ahci驱动之后就没办法再切回实模式用int13h读磁盘了。Windows这么复杂,保不准也有什么东西在切模式之后会爆炸。

点评

AHCI这事似乎是Intel自己规范里都写了,加载驱动以后INT13报废。保不齐还会有什么东西也一起爆炸。  详情 回复 发表于 2021-11-25 15:37
回复

使用道具 举报

197#
发表于 2021-11-25 15:30:26 | 只看该作者
本帖最后由 sunsea 于 2021-11-25 15:35 编辑
不点 发表于 2021-11-25 15:02
这个说法是错误的。--mem 占用的是系统内存,不可能被释放掉。

已证实,map --mem这部分内存会被直接不识别。(20H1的PE)


↑直接map


↑map --mem(无SVBus )
使用e820cycles=0的话倒是可以回收这部分内存。



点评

我也试了一下,map --mem 后的那部分内存,Windows 10 系统里面真的是不可用的,被认为是为硬件保留的内存。 图一:直接进入 Windows 10 桌面后的内存情况截图: [attachimg]491312[/attachimg] 图二:先用 G  详情 回复 发表于 2021-11-26 15:25
回复

使用道具 举报

198#
发表于 2021-11-25 15:31:26 | 只看该作者
不点 发表于 2021-11-25 15:23
但我貌似听说 “驱动程序的级别比普通程序的级别高”,不知是啥意思?

难道说,级别高,也不是最高 ...

驱动程序也在R0。但是纵使在R0,现在Windows内核也有完善的安保机制,估计一堆东西会爆炸。
回复

使用道具 举报

199#
发表于 2021-11-25 15:37:35 | 只看该作者
wintoflash 发表于 2021-11-25 15:28
是ring0。理论上是可以切到实模式再切回来的,但是实际上估计会爆炸。
我记得grub2 加载了ahci驱动之 ...

AHCI这事似乎是Intel自己规范里都写了,加载驱动以后INT13报废。保不齐还会有什么东西也一起爆炸。
回复

使用道具 举报

200#
 楼主| 发表于 2021-11-25 15:44:01 | 只看该作者
本帖最后由 不点 于 2021-11-25 15:46 编辑
liuzhaoyzz 发表于 2021-11-25 15:23
哦,不点大说的是对的,map --mem不可能被释放掉,我错了。


map  --mem 占用的内存,是占用 BIOS 级别的内存。按照 BIOS 的 int15/e820 规范,任何操作系统都不可以重新分配这些内存而企图让用户使用。

但是,也真有可能性,让 --mem 内存被操作系统重新分配给用户使用。

注意到我们的 map --e820cycles=0 这个参数了吗?当时被迫用这个办法来躲过某个陷阱。

现在这条命令可以用来达到您的目的。我不能保证一定成功,但有可能成功。然而,出问题、造成内存冲突、或死机,也都是有可能的。您如果有兴趣,可以试试。

map   --mem   (...)/PE.iso   (255)  此 PE 不含 svbus 之类的,只有微软自己的 bootmgr 来访问虚拟光驱。
map   --e820cycles=0   这让 int15 保持 ROM BIOS 状态,也就是告诉操作系统,不存在新的内存盘,可以随便毁掉内存盘,这条命令不可以放在 map  --hook 之后;若放在 map --hook 之后,就成了马后炮,不起作用了。
map   --hook
chainloader   (255)
boot

点评

虚拟机中已经证实对于内存比较宽松的环境下可以e820cycles=0来回收内存。但是内存比较紧张的话就不好说了。  详情 回复 发表于 2021-11-25 16:02
回复

使用道具 举报

201#
 楼主| 发表于 2021-11-25 15:54:54 | 只看该作者
本帖最后由 不点 于 2021-11-25 16:20 编辑

关于 Ring 0,您两位,wintoflash 和 sunsea,都是高手,细节把握得十分精准。佩服!

好啦,那就死了这条心,一心一意在保护模式底下来做事吧。






忽然想到:仍然有希望搞成功!


此时,不调用 int13 进入 ROM,因为那会出问题、死机。


但是,可以调用 int13,设置单步跟踪,记录它进入 ROM 的时刻,然后停止跟踪。此时,用寄存器或堆栈上的数据,判断它是在读哪个扇区,然后,把扇区号反馈给保护模式的程序,让保护模式的程序再去读扇区,这就成功了。



回复

使用道具 举报

202#
发表于 2021-11-25 16:02:45 | 只看该作者
不点 发表于 2021-11-25 15:44
map  --mem 占用的内存,是占用 BIOS 级别的内存。按照 BIOS 的 int15/e820 规范,任何操作系统都不可 ...

虚拟机中已经证实对于内存比较宽松的环境下可以e820cycles=0来回收内存。但是内存比较紧张的话就不好说了。

点评

假定在某些 “有利” 的条件下,这个办法是可行的。比如,微软的 bootmgr,它把 wim 加载完了之后,Windows 内核才接管控制,此时,iso 已经用不上了,也就不会再被操作系统访问了,这就没问题了,也就不怕 iso 所占  详情 回复 发表于 2021-11-25 16:08
回复

使用道具 举报

203#
 楼主| 发表于 2021-11-25 16:08:36 | 只看该作者
sunsea 发表于 2021-11-25 16:02
虚拟机中已经证实对于内存比较宽松的环境下可以e820cycles=0来回收内存。但是内存比较紧张的话就不好说了 ...

假定在某些 “有利” 的条件下,这个办法是可行的。比如,微软的 bootmgr,它把 wim 加载完了之后,Windows 内核才接管控制,此时,iso 已经用不上了,也就不会再被操作系统访问了,这就没问题了,也就不怕 iso 所占据的内存被操作系统毁掉了。
回复

使用道具 举报

204#
发表于 2021-11-25 19:15:21 | 只看该作者
搞 不清,为什么转圈,

转圈启动后,为  硬件保留的 内存 没有增加

点评

不要看为硬件保留的内存。看总内存。  详情 回复 发表于 2021-11-25 19:16
回复

使用道具 举报

205#
发表于 2021-11-25 19:16:28 | 只看该作者
2011whp 发表于 2021-11-25 19:15
搞 不清,为什么转圈,

转圈启动后,为  硬件保留的 内存 没有增加

不要看为硬件保留的内存。看总内存。
回复

使用道具 举报

206#
发表于 2021-11-25 19:21:23 | 只看该作者
其实我U启一直拒绝用打包成iso的pe,iso除了虚拟机测试方便,别的一无事处
wim不香吗,无要求直接用bootmgr,有要求用wimboot,

点评

bootmgr 怎么启动 wim? 能给个操作步骤吗?我不熟悉bcd等知识,是个小白菜,最好给个傻瓜化教程,连傻子都能看懂的。  发表于 2021-11-27 06:58
实验室 模式,帮忙 解 惑  详情 回复 发表于 2021-11-25 19:58
回复

使用道具 举报

207#
 楼主| 发表于 2021-11-25 19:21:54 | 只看该作者
专门下载了 0.4.5c 的版本, 目的是看看当年 e820 handler 是在什么位置.

居然是在偏移 0x17A0 处!


而 int13 空间的尾部在 0x3000 处,

也就是说, 至少破坏了 6K 还多一点! 而真正破坏的量可能大得很! 没准还可能完全覆盖掉整个 int13 的空间!


当然了, 这是 XP 的某个显卡驱动带来的问题, 据说在 win7 已经没有此问题了.

既然 6K 都破坏了, 那就不像是堆栈了. 实模式的堆栈, 通常都不需要很大, 1K 或 2K 就够了.

是的, 如果尾部 6K 都破坏掉了, 那么, 很可能不是堆栈破坏的, 而可能是从低地址向高地址破坏, 也就是说, 从 int13 的开头开始破坏! 那样我们根本没有对策!

我们只好认为, 那种情况不存在. 因为即使存在了, 我们也没办法. 我们假定 win7 以后都不存在那种糟糕的情况了.

好的, 就假定是堆栈的问题吧! 不是堆栈, 我们就放弃, 就投降.

而堆栈, 不会超级巨大. 先给个 2K, 应该够它用了.

如果不够用, 那它可能是保护模式的堆栈! 需要更大的空间. 那就给它 4K 吧.

yaya 可以先用 2K 试试. 不行就用 4K.




回复

使用道具 举报

208#
发表于 2021-11-25 19:29:15 | 只看该作者
本帖最后由 2011whp 于 2021-11-25 19:31 编辑

无碎片svbuspe.iso  任务管理器对比


1.  map  iso 转圈启动 (外加 xorboot启动,不转圈)如下图



2. map --mem  iso启动,如下图

点评

总内存差200M,这就是e820保留的内存。直接map是按需读取,不会向内存拷贝。所以我怀疑是优化环节问题。  详情 回复 发表于 2021-11-25 19:34
回复

使用道具 举报

209#
发表于 2021-11-25 19:34:30 | 只看该作者
2011whp 发表于 2021-11-25 19:29
无碎片svbuspe.iso  任务管理器对比

总内存差200M,这就是e820保留的内存。直接map是按需读取,不会向内存拷贝。所以我怀疑是优化环节问题。
回复

使用道具 举报

210#
发表于 2021-11-25 19:55:42 | 只看该作者
本帖最后由 2011whp 于 2021-11-26 12:40 编辑

537 - 296 =241 (正好 pe.iso的体积)

想要 想通 ,是否  又得这样 理解


记得,有次  第一碎片是 50MB左右时,转圈 3秒黑屏,这个  情况,没保留下图片

点评

不对。bootmgr在启动后把boot.wim已经完全读入内存,后面操作X盘就是ramdisk.sys的纯内存操作。没看懂你这个蓝色字什么意思。  详情 回复 发表于 2021-11-25 19:58
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-30 15:18

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表