1 /* $OpenBSD: boot1.c,v 1.12 2022/09/02 10:15:35 miod Exp $ */
2 /* $NetBSD: boot1.c,v 1.1 2006/09/01 21:26:19 uwe Exp $ */
3
4 /*-
5 * Copyright (c) 2003 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by David Laight.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/param.h>
34 #include <lib/libsa/stand.h>
35 #include "ufs12.h"
36
37 #include <sys/disklabel.h>
38
39 #define XSTR(x) #x
40 #define STR(x) XSTR(x)
41
42 static uint32_t bios_sector;
43
44 const char *boot1(uint32_t *);
45 void putstr(const char *str);
46 int blkdevstrategy(void *, int, daddr_t, size_t, void *, size_t *);
47 int blkdevopen(struct open_file *, ...);
48 int blkdevclose(struct open_file *);
49 int readsects(int dev, uint32_t lba, void *buf, size_t size);
50
51 extern struct disklabel ptn_disklabel;
52
53 struct fs_ops file_system[] = {
54 { ufs12_open, ufs12_close, ufs12_read, ufs12_write, ufs12_seek,
55 ufs12_stat, ufs12_readdir, ufs12_fchmod },
56 };
57 int nfsys = nitems(file_system);
58
59 struct devsw devsw[] = {
60 { "dk", blkdevstrategy, blkdevopen, blkdevclose, noioctl },
61 };
62 int ndevs = nitems(devsw);
63
64 const char *
boot1(uint32_t * sector)65 boot1(uint32_t *sector)
66 {
67 struct stat sb;
68 int fd = -1;
69
70 bios_sector = *sector;
71
72 putstr("\r\nOpenBSD/" MACHINE " Primary Bootstrap\r\n");
73
74 do {
75 /*
76 * Nothing at the start of the MBR partition, fallback on
77 * partition 'a' from the disklabel in this MBR partition.
78 */
79 if (ptn_disklabel.d_magic != DISKMAGIC)
80 break;
81 if (ptn_disklabel.d_magic2 != DISKMAGIC)
82 break;
83 if (ptn_disklabel.d_partitions[0].p_fstype == FS_UNUSED)
84 break;
85
86 bios_sector = ptn_disklabel.d_partitions[0].p_offset;
87 *sector = bios_sector;
88 fd = open("boot", O_RDONLY);
89 } while (0);
90
91 if (fd == -1 || fstat(fd, &sb) == -1)
92 return "Can't open /boot.\r\n";
93
94 #if 0
95 if (sb.st_size > SECONDARY_MAX_LOAD)
96 return "/boot too large.\r\n";
97 #endif
98
99 if (read(fd, (void *)LOADADDRESS, sb.st_size) != sb.st_size)
100 return "/boot load failed.\r\n";
101
102 if (*(uint32_t *)(LOADADDRESS + 4) != 0x20041110)
103 return "Invalid /boot file format.\r\n";
104
105 return 0;
106 }
107
108 int
blkdevopen(struct open_file * f,...)109 blkdevopen(struct open_file *f, ...)
110 {
111 return 0;
112 }
113 int
blkdevclose(struct open_file * f)114 blkdevclose(struct open_file *f)
115 {
116 return 0;
117 }
118
119 int
blkdevstrategy(void * devdata,int flag,daddr_t dblk,size_t size,void * buf,size_t * rsize)120 blkdevstrategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize)
121 {
122
123 if (flag != F_READ)
124 return EROFS;
125
126 if (size & (DEV_BSIZE - 1))
127 return EINVAL;
128
129 if (rsize)
130 *rsize = size;
131
132 if (size != 0 && readsects(0x40, bios_sector + dblk, buf,
133 size / DEV_BSIZE) != 0)
134 return EIO;
135
136 return 0;
137 }
138
139 void
twiddle(void)140 twiddle(void)
141 {
142 static int pos;
143
144 putchar("|/-\\"[pos++ & 3]);
145 putchar('\b');
146 }
147
148 int
devopen(struct open_file * f,const char * fname,char ** file)149 devopen(struct open_file *f, const char *fname, char **file)
150 {
151 *file = (char *)fname;
152 f->f_flags |= F_NODEV;
153 f->f_dev = &devsw[0];
154 return (0);
155 }
156