Labs de xv6 del MIT: P3, P5 y bono
Tres proyectos del curso usan laboratorios del curso
6.1810 Operating System Engineering
del MIT (otoño 2025). Corren sobre xv6-riscv, el mismo kernel de P2, y traen
su propio código de partida y sus propias pruebas (make grade). Los
enunciados del MIT están en inglés y son la referencia oficial; aquí van un
resumen, la versión exacta que usamos y cómo entregar.
| Proyecto | Lab del MIT | Enunciado | Rama | Commit fijado | Semanas |
|---|---|---|---|---|---|
| P3 | Tablas de páginas | pgtbl | pgtbl |
cff452f8f70f46e9b22f815fc879242ebe5eacd6 |
8 → 10 |
| P5 | Sistema de archivos | fs | fs |
a95dec46d4443c579f47e793e7d731cce2d34388 |
13 → 16 |
| Bono | Fork con copy-on-write | cow | cow |
cf0eb5bdaaa24f3a46a80d2702af3c9e260c2692 |
11 → 16 |
Antes de empezar cualquiera de los tres, lean la página de orientación del MIT (cómo depurar, qué hacer cuando el kernel entra en pánico) y repasen el calentamiento con gdb de P2.
Preparar el código
Todo se hace dentro del contenedor del curso. Desde la carpeta so/ (la que
se monta en /work):
./curso/env/run.sh # abre una shell en el contenedor
git clone git://g.csail.mit.edu/xv6-labs-2025
cd xv6-labs-2025
git config user.name "Nombre Apellido" # una sola vez por repositorio
git config user.email "correo@uni.pe"
Sin esas dos líneas, git commit falla dentro del contenedor: el contenedor
se borra al salir y no guarda una configuración global de git.
Cada lab vive en su propia rama. Creen una rama local con el nombre del lab, a partir del commit fijado (así todos trabajan sobre el mismo código, aunque el MIT actualice la rama durante el semestre):
git checkout -b pgtbl cff452f8f70f46e9b22f815fc879242ebe5eacd6 # P3
git checkout -b fs a95dec46d4443c579f47e793e7d731cce2d34388 # P5
git checkout -b cow cf0eb5bdaaa24f3a46a80d2702af3c9e260c2692 # bono
make clean
make qemu # salir con Ctrl-a x
Si ya avanzaron en un lab y van a cambiar de rama, primero hagan commit de su
trabajo. Si la red de la universidad bloquea el protocolo git://
(puerto 9418), el docente publicará una copia del repositorio por otro medio.
Correr las pruebas
make grade
make grade hace make clean, compila, arranca xv6 varias veces sin interfaz
gráfica y compara la salida con lo esperado. Al final imprime
Score: N/M. Sobre el código sin modificar casi todo falla; eso es lo normal.
Para correr una sola prueba, pasen su nombre (tal como aparece en el archivo
grade-lab-*):
make GRADEFLAGS=simple grade # solo la prueba "simple" de cow
- No corran
make grademientras tengan otromake qemuabierto en la misma carpeta. - Las tres rutinas de prueba piden un archivo
time.txtcon un solo número entero: las horas que les tomó el lab.pgtblademás pideanswers-pgtbl.txtcon sus respuestas a las preguntas del enunciado; pueden responder en español. - En los labs
fsycow,usertests -qes parte demake grade. Con el código terminado, las pruebas defstardan varios minutos (bigfileescribe un archivo de 64 MB).
P3 — Tablas de páginas (pgtbl)
Qué pide. Trabajar directamente con las tablas de páginas (page tables) de tres niveles de RISC-V (Sv39):
- Inspeccionar la tabla de páginas de un proceso de usuario con el
programa
pgtbltesty explicar, para cada entrada (PTE), qué contiene esa página y qué significan sus bits de permiso. - Acelerar
getpid(): al crear cada proceso, mapear en la direcciónUSYSCALLuna página de solo lectura para el usuario que guarde su PID. Asíugetpid()obtiene el PID sin entrar al kernel. Hay que crear, mapear y liberar esa página en los mismos puntos del ciclo de vida del proceso que el trapframe (kernel/proc.c). - Imprimir una tabla de páginas: implementar
vmprint()enkernel/vm.c, que recorre el árbol de tres niveles y muestra cada PTE válida con su nivel de indentación, su dirección virtual y la física. - Superpáginas (superpages): cuando un proceso pide 2 MB o más con
sbrk(), usar páginas de 2 MB alineadas en lugar de cientos de páginas de 4 KB. Implica reservar bloques de 2 MB enkernel/kalloc.c, y manejarlos enfork(copia),exit(liberación) y al reducir la memoria (partir una superpágina en páginas normales).
Pruebas. pgtbltest (ugetpid, print_kpgtbl, superpg),
answers-pgtbl.txt y time.txt.
Se apoya en. Semanas 5–8: espacios de direcciones, traducción de
direcciones, paginación (sem. 6), TLB y tablas de páginas multinivel (sem. 7)
y memoria virtual completa (sem. 8). La experiencia con llamadas al sistema y
con kernel/proc.c de P2. Lectura: capítulo 3 del
libro de xv6
y los archivos kernel/memlayout.h, kernel/vm.c y kernel/kalloc.c.
P5 — Archivos grandes y enlaces simbólicos (fs)
Qué pide. Dos extensiones al sistema de archivos (file system) de xv6:
- Archivos grandes. Hoy un inodo (inode) tiene 12 bloques directos y uno
indirecto simple, así que un archivo llega a 12 + 256 = 268 bloques. Hay que
cambiar uno de los directos por un bloque doblemente indirecto (256
bloques indirectos de 256 entradas cada uno), sin cambiar el tamaño del
inodo en disco. El máximo pasa a 11 + 256 + 256·256 = 65 803 bloques. El
trabajo está en
bmap()(traducir el número de bloque lógico del archivo a un bloque del disco, reservando bloques a medida que se necesitan) y enitrunc()(liberarlos todos), enkernel/fs.c, junto con las constantes dekernel/fs.hykernel/file.h. - Enlaces simbólicos (symbolic links). Agregar la llamada al sistema
symlink(target, path), un tipo de archivo nuevoT_SYMLINKy una opciónO_NOFOLLOWparaopen(). Al abrir un enlace,open()debe seguirlo (también si apunta a otro enlace), detectar ciclos con un límite de profundidad y fallar si el destino no existe. ConO_NOFOLLOWse abre el enlace mismo.link()yunlink()no siguen enlaces.
Pruebas. bigfile, symlinktest, usertests -q y time.txt. Hay que
agregar symlinktest a UPROGS en el Makefile.
Se apoya en. Semana 13 (API de archivos y directorios, enlaces duros y
simbólicos) y semana 14 (implementación de un sistema de archivos: inodos,
bloques indirectos, bitmaps; y journaling, que en xv6 es el log de
kernel/log.c con begin_op() y end_op()). En el laboratorio de la semana 14
ya dibujaron el formato del disco de xv6 y ubicaron bmap(). Lectura:
capítulo 10 (“File system”) del libro de xv6.
Bono — Fork con copy-on-write (cow)
Qué pide. Que fork() no copie la memoria del padre. En lugar de eso:
uvmcopy()(kernel/vm.c) mapea en el hijo las mismas páginas físicas del padre y quita el permiso de escritura en ambos. Conviene marcar esas PTE como copy-on-write, por ejemplo con uno de los bits RSW que RISC-V reserva para el software.- Cuando alguno de los dos escribe, ocurre un fallo de página (page fault). El kernel reconoce que es una página copy-on-write, reserva una página nueva, copia el contenido y la mapea con escritura. Las páginas que eran de solo lectura desde el principio (el código) siguen compartidas, y escribir en ellas mata al proceso.
- Como una página física puede estar en varias tablas de páginas, se lleva un
contador de referencias por página en
kernel/kalloc.c:kfree()solo la devuelve a la lista libre cuando el contador llega a cero. El contador se modifica desde varias CPUs, así que necesita un lock. copyout()debe tratar las páginas copy-on-write igual que un fallo de página.- Si no hay memoria para la copia, se mata al proceso (no se entra en pánico).
Pruebas. cowtest (simple, three, file y forkfork), usertests -q
y time.txt. Sin modificar, cowtest falla de inmediato porque simple
reserva más de la mitad de la memoria y luego hace fork().
Se apoya en. fork/exec (semana 2), paginación y fallos de página
(semanas 6–8; copy-on-write aparece en la semana 8 con VAX/VMS) y locks
(semana 10) para el contador de referencias. Es el lab que más integra: tiene
lugar entre la semana 11 y la 16 y conviene empezarlo apenas termine P3. Lectura:
capítulo 5 (“Page faults”) del libro de xv6, kernel/trap.c (usertrap()) y
vmfault() en kernel/vm.c.
Cómo entregar
-
Hagan commit de todo su trabajo en la rama del lab, incluidos
time.txt,answers-pgtbl.txt(solo P3) y unREADME.mdcorto en la raíz con los integrantes, qué funciona y qué no, y sus decisiones de diseño. -
Verifiquen con
make gradedentro del contenedor. -
Generen el archivo de entrega:
make zipballEsto crea
lab.zipcon el último commit (git archive HEAD). Si les avisa de cambios sin commit o de archivos sin seguimiento (??), hagangit addygit commitde lo que su solución necesita y repitan. -
Entreguen
lab.zipen la semana indicada en el calendario.
Las pruebas se corren con el make grade de la misma versión fijada. Además se
revisa el código y puede haber una defensa oral breve, como en los demás
proyectos (ver projects/README.md).
No publiquen sus soluciones en repositorios públicos: el MIT pide lo mismo a sus estudiantes y estos labs se reutilizan cada año.