0

Code from xv6's 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.

Then epa becomes 100 + (50*1) = 150.

new pa = 100 - (5%100) = 95. (What's the point ?)

The loop runs 3 times (1 sector more than necessary, why it doesn't matter ?)

  • 1
    Looks weird, if you ask me. Unless this `readsect` is doing something even weirder. – Eugene Sh. Aug 15 '18 at 18:04
  • The _implication_ is that `readsect(a,s)` reads exactly `SECTSIZE` bytes from sector s to address a. I don't see how it could work doing anything else – Tim Randall Aug 15 '18 at 18:59
  • @TimRandall Yes but the question is why does it start reading from address (pa - offset % SECTSIZE). If you look at the source code of xv6, it tries to load program segments specified in elf header (i.e start of kernel) previously read, at offset from kernel. I understand till that point but why are we subtracting the physical address and writing more than necessary ? – Debasish Das Aug 15 '18 at 19:29
  • I think the comment "Round down to sector boundary" is misleading. As a result of this operation `pa` doesn't end up at a sector boundary at all. – Ivan Ivanov Apr 04 '20 at 14:04

1 Answers1

0

Memory is broken down into sectors of SECTSIZE bytes each. The code is reducing the destination address because it delegates its work to readsect which only reads whole sectors. 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. The user calls 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".

readsect is going to be called once, and it's going to read in a 4 byte sector. The line that's causing confusion, 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).

    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
Tim Randall
  • 4,040
  • 1
  • 17
  • 39
  • I'm sorry but i didn't get what you meant by "it reads more than needed (as warned by the comment), to an address lower than that specified by the caller" – Debasish Das Aug 15 '18 at 19:37
  • Well, `readsect` reads complete sectors, so unless you ask for an exact multiple of `SECTSIZE`, it is going to read more than you asked for. The comment on the second line of your code warns of that. And the reason it reads to a lower address is related. If you ask for the second byte in a sector to be at address `a`, then the first byte of that sector is going to get written to address `a-1`. – Tim Randall Aug 15 '18 at 19:54
  • Edited to add an example and to take on board @Eugene's correction. – Tim Randall Aug 16 '18 at 14:16
  • I don't understand the example what are these numbers coming from? – LetsGoBrandon Sep 25 '22 at 14:00