NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/60816: kernel load fails on KX-7000 CPU based motherboard using bios boot.



>Number:         60816
>Category:       kern
>Synopsis:       kernel load fails on KX-7000 CPU based motherboard using bios boot.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Sep 27 22:10:00 +0000 2026
>Originator:     Andrius V
>Release:        NetBSD current/11/10
>Organization:
>Environment:
>Description:
BIOS boot fails on the KX-7000 CPU based motherboard (AOS-MMZX700D), on both i386 and amd64.

Symptoms can be a partially loaded kernel followed by input/output error, for example:

22695668+595084+748404read section: input/output error

Or "inappropriate file type or format" before the kernel even starts to load. With the amd64 bios boot only image, the system even reboots on kernel load.

After investigation, it appears that we have a special case where we don't use int13ext to read disks until a certain sector, which can instead be read via CHS. However, for this particular system, that doesn't work.

Forcing int13ext (for example, via FORCE_INT13EXT) makes the system boot.

My proposal is to always use int13ext for reading sectors when it's available. The risk I see is that some legacy systems may advertise the feature but fail to work with it for CHS sectors.

I've checked that OpenBSD/FreeBSD currently do the same (relying on the capability, not on the sector count), and they both boot successfully.
>How-To-Repeat:
Set legacy only boot mode in BIOS.
Use i386 USB install image or amd64 bios only image.
Try to boot kernel.
>Fix:
--- a/sys/arch/i386/stand/lib/biosdisk_ll.c
+++ b/sys/arch/i386/stand/lib/biosdisk_ll.c
@@ -176,7 +176,7 @@ static daddr_t  ra_first;
 #define        NEED_INT13EXT(d, dblk, num)                             \
        (((d)->type == BIOSDISK_TYPE_CD) ||                     \
         ((d)->type == BIOSDISK_TYPE_HD &&                      \
-         ((dblk) + (num)) >= (d)->chs_sectors))
+         ((d)->flags & BIOSDISK_INT13EXT)))
 #endif
 
 static int
@@ -212,6 +212,10 @@ do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
        } else {
                int cyl, head, sec, nsec, spc, dblk32;
 
+               if (dblk + num > d->chs_sectors) {
+                       return -1;
+               }
+
                dblk32 = (int)dblk;
                spc = d->head * d->sec;
                cyl = dblk32 / spc;




Home | Main Index | Thread Index | Old Index