简体   繁体   English

xv6:bootmain.c readseg()“向下舍入到扇区边界”

[英]xv6: bootmain.c readseg() “round down to sector boundary”

Code from xv6's bootmain.c: 来自xv6的bootmain.c的代码:

// Read 'count' bytes at 'offset' from kernel into physical address 'pa'.
// Might copy more than asked.

void
readseg(uchar* pa, uint count, uint offset)
{
  uchar* epa;

  epa = pa + count;

  // Round down to sector boundary.
  pa -= offset % SECTSIZE;

  // Translate from bytes to sectors; kernel starts at sector 1.
  offset = (offset / SECTSIZE) + 1;

  // If this is too slow, we could read lots of sectors at a time.
  // We'd write more to memory than asked, but it doesn't matter --
  // we load in increasing order.
  for(; pa < epa; pa += SECTSIZE, offset++)
    readsect(pa, offset);
}

I dont understand the following statement: 我不明白以下说法:

pa -= offset % SECTSIZE;

What exactly does "Round down to sector boundary" mean ? “向下到扇区边界”到底是什么意思? I don't understand why we are subtracting the physical address (when offset is not zero). 我不明白为什么我们要减去物理地址(偏移量不为零时)。

For simplicity, let's say pa = 100 (decimal), count = 50, offset = 5, SECTSIZE = 100. 为简单起见,假设pa = 100(十进制),count = 50,offset = 5,SECTSIZE = 100。

Then epa becomes 100 + (50*1) = 150. 然后epa变为100 +(50 * 1)= 150。

new pa = 100 - (5%100) = 95. (What's the point ?) 新pa = 100-(5%100)=95。(这是什么意思?)

The loop runs 3 times (1 sector more than necessary, why it doesn't matter ?) 循环运行3次(多于1个扇区,为什么没关系?)

Memory is broken down into sectors of SECTSIZE bytes each. 内存分为每个SECTSIZE字节的扇区。 The code is reducing the destination address because it delegates its work to readsect which only reads whole sectors. 该代码减少了目标地址,因为它将工作委托给readsect ,而readsect仅读取整个扇区。 If it's passed an address that's not on a sector boundary, it reads more than needed (as warned by the comment), to an address lower than that specified by the caller (something not covered by the warning). 如果它传递的地址不在扇区边界上,则它读取的内容会比调用方指定的地址低(警告涵盖),这超出了需要(如注释所警告)。 This is perhaps inefficient, and potentially disastrous, but this implementation does at least put the byte that the caller asked for at the address that they specified. 这可能效率低下,并且可能造成灾难性后果,但是此实现至少会将调用者要求的字节放在他们指定的地址上。

Consider the following example, with a sector size of 4 bytes. 考虑下面的示例,其扇区大小为4个字节。 The user calls readseg(pa, 2, 14); 用户调用readseg(pa, 2, 14); and let's assume for the sake of argument that each byte in kernel memory is set to a value equal to its offset, and that pa is pointing at the second word in "Hello world". 为了便于讨论,我们假设内核内存中的每个字节都设置为等于其偏移量的值,并且pa指向“ Hello world”中的第二个单词。

readsect is going to be called once, and it's going to read in a 4 byte sector. readsect将被调用一次,并将在一个4字节的扇区中读取。 The line that's causing confusion, pa -= offset % SECTSIZE; 引起混乱的行, pa -= offset % SECTSIZE; is how the code ensures that byte 14 ends up at the address specified by the caller (the initial value of pa ). 代码是如何确保字节14结束于调用方指定的地址( pa的初始值)的。

    Before      After
    'H'         'H'
    'e'         'e'
    'l'         'l
    'l'         'l'
    'o'      pa 12
    ' '         13
 pa 'w'         14
    'o'         15
epa 'r'     epa 'r'
    'l'         'l'
    'd'         'd'
    0           0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM